jhead.c revision d6a02c32e6fa83fad5794b0e19b1d28563e5a99b
134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Program to pull the information out of various types of EXIF digital 334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// camera files and show it in a reasonably consistent way 434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// 5d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang// Version 2.86 634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// 734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Compiling under Windows: 834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Make sure you have Microsoft's compiler on the path, then run make.bat 934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// 10d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang// Dec 1999 - Mar 2009 1134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// 1234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// by Matthias Wandel www.sentex.net/~mwandel 1334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 1434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#include "jhead.h" 1534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 1634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#include <sys/stat.h> 1734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#include <utils/Log.h> 1834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 19d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang#define JHEAD_VERSION "2.87" 2034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 2134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// This #define turns on features that are too very specific to 2234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// how I organize my photos. Best to ignore everything inside #ifdef MATTHIAS 23d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang//#define MATTHIAS 2434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 2534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef _WIN32 2634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #include <io.h> 2734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 2834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 2934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int FilesMatched; 3034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int FileSequence; 3134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 3234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic const char * CurrentFile; 3334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 3434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic const char * progname; // program name for error messages 3534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 3634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 3734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Command line options flags 3834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int TrimExif = FALSE; // Cut off exif beyond interesting data. 39d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Changstatic int RenameToDate = 0; // 1=rename, 2=rename all. 40d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang#ifdef _WIN32 4134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int RenameAssociatedFiles = FALSE; 42d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang#endif 4334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * strftime_args = NULL; // Format for new file name. 4434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int Exif2FileTime = FALSE; 4534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DoModify = FALSE; 4634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DoReadAction = FALSE; 4734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int ShowTags = FALSE; // Do not show raw by default. 4834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int Quiet = FALSE; // Be quiet on success (like unix programs) 4934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int DumpExifMap = FALSE; 5034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int ShowConcise = FALSE; 5134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int CreateExifSection = FALSE; 5234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * ApplyCommand = NULL; // Apply this command to all images. 5334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * FilterModel = NULL; 5434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int ExifOnly = FALSE; 5534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int PortraitOnly = FALSE; 5634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic time_t ExifTimeAdjust = 0; // Timezone adjust 5734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic time_t ExifTimeSet = 0; // Set exif time to a value. 5834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char DateSet[11]; 5934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic unsigned DateSetChars = 0; 6034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic unsigned FileTimeToExif = FALSE; 6134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 6234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DeleteComments = FALSE; 6334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DeleteExif = FALSE; 6434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DeleteIptc = FALSE; 65d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Changstatic int DeleteXmp = FALSE; 6634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DeleteUnknown = FALSE; 6734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * ThumbSaveName = NULL; // If not NULL, use this string to make up 6834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // the filename to store the thumbnail to. 6934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 7034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * ThumbInsertName = NULL; // If not NULL, use this string to make up 7134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // the filename to retrieve the thumbnail from. 7234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 7334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int RegenThumbnail = FALSE; 7434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 7534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * ExifXferScrFile = NULL;// Extract Exif header from this file, and 7634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // put it into the Jpegs processed. 7734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 7834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int EditComment = FALSE; // Invoke an editor for editing the comment 7934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int SupressNonFatalErrors = FALSE; // Wether or not to pint warnings on recoverable errors 8034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 8134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * CommentSavefileName = NULL; // Save comment to this file. 8234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * CommentInsertfileName = NULL; // Insert comment from this file. 8334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char * CommentInsertLiteral = NULL; // Insert this comment (from command line) 8434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 8534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int AutoRotate = FALSE; 8634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int ZeroRotateTagOnly = FALSE; 8734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 8834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int ShowFileInfo = TRUE; // Indicates to show standard file info 8934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // (file name, file size, file date) 9034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 9134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 9234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef MATTHIAS 9334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // This #ifdef to take out less than elegant stuff for editing 9434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // the comments in a JPEG. The programs rdjpgcom and wrjpgcom 9534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // included with Linux distributions do a better job. 9634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 9734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project static char * AddComment = NULL; // Add this tag. 9834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project static char * RemComment = NULL; // Remove this tag 9934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project static int AutoResize = FALSE; 10034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif // MATTHIAS 10134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 10234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 10334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Error exit handler 10434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 10534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid ErrFatal(char * msg) 10634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 10734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project LOGE("Error : %s\n", msg); 10834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CurrentFile) fprintf(stderr,"in file '%s'\n",CurrentFile); 10934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(EXIT_FAILURE); 11034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 11134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 11234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 11334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Report non fatal errors. Now that microsoft.net modifies exif headers, 11434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// there's corrupted ones, and there could be more in the future. 11534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 11634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid ErrNonfatal(char * msg, int a1, int a2) 11734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 11834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project LOGE("Nonfatal Error : "); 11934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project LOGE(msg, a1, a2); 12034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (SupressNonFatalErrors) return; 12134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 122d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang fprintf(stderr,"\nNonfatal Error : "); 12334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CurrentFile) fprintf(stderr,"'%s' ",CurrentFile); 12434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fprintf(stderr, msg, a1, a2); 12534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fprintf(stderr, "\n"); 12634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 12734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 12834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 12934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Set file time as exif time. 13034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 13134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid FileTimeAsString(char * TimeStr) 13234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 13334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct tm ts; 13434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ts = *localtime(&ImageInfo.FileDateTime); 13534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strftime(TimeStr, 20, "%Y:%m:%d %H:%M:%S", &ts); 13634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 13734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 13834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#if 0 // not used -- possible security risk with use of system, sprintf, etc. 13934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 14034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Invoke an editor for editing a string. 14134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 14234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int FileEditComment(char * TempFileName, char * Comment, int CommentSize) 14334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 14434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FILE * file; 14534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 146d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char QuotedPath[PATH_MAX+10]; 14734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 14834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project file = fopen(TempFileName, "w"); 14934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (file == NULL){ 15034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fprintf(stderr, "Can't create file '%s'\n",TempFileName); 15134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("could not create temporary file"); 15234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 15334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fwrite(Comment, CommentSize, 1, file); 15434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 15534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fclose(file); 15634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 15734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fflush(stdout); // So logs are contiguous. 15834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 15934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project { 160d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char * Editor; 161d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang Editor = getenv("EDITOR"); 16234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Editor == NULL){ 16334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef _WIN32 16434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Editor = "notepad"; 16534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#else 16634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Editor = "vi"; 16734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 16834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 169d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (strlen(Editor) > PATH_MAX) ErrFatal("env too long"); 17034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 17134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(QuotedPath, "%s \"%s\"",Editor, TempFileName); 17234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a = system(QuotedPath); 17334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 174d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 17534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a != 0){ 17634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project perror("Editor failed to launch"); 17734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(-1); 17834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 17934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 18034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project file = fopen(TempFileName, "r"); 18134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (file == NULL){ 18234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("could not open temp file for read"); 18334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 18434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 18534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Read the file back in. 18634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSize = fread(Comment, 1, 999, file); 18734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 18834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fclose(file); 18934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 19034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unlink(TempFileName); 19134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 19234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return CommentSize; 19334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 19434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 19534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef MATTHIAS 19634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 19734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Modify one of the lines in the comment field. 19834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// This very specific to the photo album program stuff. 19934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 20034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic char KnownTags[][10] = {"date", "desc","scan_date","author", 20134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "keyword","videograb", 20234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "show_raw","panorama","titlepix",""}; 20334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 20434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int ModifyDescriptComment(char * OutComment, char * SrcComment) 20534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 20634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char Line[500]; 20734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int Len; 20834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a,i; 20934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned l; 21034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int HasScandate = FALSE; 21134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int TagExists = FALSE; 21234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int Modified = FALSE; 21334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Len = 0; 21434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 21534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project OutComment[0] = 0; 21634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 21734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 21834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (i=0;;i++){ 21934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (SrcComment[i] == '\r' || SrcComment[i] == '\n' || SrcComment[i] == 0 || Len >= 199){ 22034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Process the line. 22134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Len > 0){ 22234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Line[Len] = 0; 22334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project //printf("Line: '%s'\n",Line); 22434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;;a++){ 22534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project l = strlen(KnownTags[a]); 22634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!l){ 22734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Unknown tag. Discard it. 22834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: Unknown tag '%s'\n", Line); // Deletes the tag. 22934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 23034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 23134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 23234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (memcmp(Line, KnownTags[a], l) == 0){ 23334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Line[l] == ' ' || Line[l] == '=' || Line[l] == 0){ 23434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Its a good tag. 23534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Line[l] == ' ') Line[l] = '='; // Use equal sign for clarity. 23634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a == 2) break; // Delete 'orig_path' tag. 23734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a == 3) HasScandate = TRUE; 23834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RemComment){ 23934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (strlen(RemComment) == l){ 24034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!memcmp(Line, RemComment, l)){ 24134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 24234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 24334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 24434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 24534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 24634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (AddComment){ 24734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Overwrite old comment of same tag with new one. 24834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!memcmp(Line, AddComment, l+1)){ 24934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project TagExists = TRUE; 250d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncpy(Line, AddComment, sizeof(Line)); 25134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 25234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 25334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 254d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncat(OutComment, Line, MAX_COMMENT_SIZE-5-strlen(OutComment)); 25534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcat(OutComment, "\n"); 25634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 25734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 25834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 25934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 26034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 26134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Line[Len = 0] = 0; 26234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (SrcComment[i] == 0) break; 26334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 26434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Line[Len++] = SrcComment[i]; 26534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 26634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 26734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 26834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (AddComment && TagExists == FALSE){ 269d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncat(OutComment, AddComment, MAX_COMMENT_SIZE-5-strlen(OutComment)); 27034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcat(OutComment, "\n"); 27134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 27234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 27334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 27434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!HasScandate && !ImageInfo.DateTime[0]){ 27534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Scan date is not in the file yet, and it doesn't have one built in. Add it. 27634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char Temp[30]; 27734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(Temp, "scan_date=%s", ctime(&ImageInfo.FileDateTime)); 278d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncat(OutComment, Temp, MAX_COMMENT_SIZE-5-strlen(OutComment)); 27934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 28034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 28134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return Modified; 28234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 28334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 28434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Automatic make smaller command stuff 28534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 28634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int AutoResizeCmdStuff(void) 28734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 288d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang static char CommandString[PATH_MAX+1]; 28934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project double scale; 29034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 29134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ApplyCommand = CommandString; 29234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 29334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.Height <= 1280 && ImageInfo.Width <= 1280){ 29434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("not resizing %dx%x '%s'\n",ImageInfo.Height, ImageInfo.Width, ImageInfo.FileName); 29534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return FALSE; 29634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 29734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 29834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project scale = 1024.0 / ImageInfo.Height; 29934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (1024.0 / ImageInfo.Width < scale) scale = 1024.0 / ImageInfo.Width; 30034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 30134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (scale < 0.5) scale = 0.5; // Don't scale down by more than a factor of two. 30234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 30334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(CommandString, "mogrify -geometry %dx%d -quality 85 &i",(int)(ImageInfo.Width*scale), (int)(ImageInfo.Height*scale)); 30434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return TRUE; 30534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 30634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 30734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 30834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif // MATTHIAS 30934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 31034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 31134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 312d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang// Escape an argument such that it is interpreted literally by the shell 313d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang// (returns the number of written characters) 314d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang//-------------------------------------------------------------------------- 315d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Changstatic int shellescape(char* to, const char* from) 316d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang{ 317d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang int i, j; 318d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang i = j = 0; 319d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 320d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // Enclosing characters in double quotes preserves the literal value of 321d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // all characters within the quotes, with the exception of $, `, and \. 322d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang to[j++] = '"'; 323d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang while(from[i]) 324d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang { 325d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang#ifdef _WIN32 326d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // Under WIN32, there isn't really anything dangerous you can do with 327d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // escape characters, plus windows users aren't as sercurity paranoid. 328d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // Hence, no need to do fancy escaping. 329d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang to[j++] = from[i++]; 330d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang#else 331d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang switch(from[i]) { 332d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang case '"': 333d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang case '$': 334d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang case '`': 335d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang case '\\': 336d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang to[j++] = '\\'; 337d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // Fallthru... 338d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang default: 339d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang to[j++] = from[i++]; 340d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang } 341d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang#endif 342d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (j >= PATH_MAX) ErrFatal("max path exceeded"); 343d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang } 344d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang to[j++] = '"'; 345d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang return j; 346d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang} 347d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 348d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 349d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang//-------------------------------------------------------------------------- 35034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Apply the specified command to the JPEG file. 35134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 35234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic void DoCommand(const char * FileName, int ShowIt) 35334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 35434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a,e; 355d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char ExecString[PATH_MAX*3]; 356d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char TempName[PATH_MAX+10]; 35734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int TempUsed = FALSE; 35834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 35934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project e = 0; 36034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 361d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // Generate an unused temporary file name in the destination directory 362d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // (a is the number of characters to copy from FileName) 363d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang a = strlen(FileName)-1; 364d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang while(a > 0 && FileName[a-1] != SLASH) a--; 365d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang memcpy(TempName, FileName, a); 366d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strcpy(TempName+a, "XXXXXX"); 367d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang mktemp(TempName); 368d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if(!TempName[0]) { 369d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang ErrFatal("Cannot find available temporary file name"); 370d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang } 371d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 372d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 37334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 37434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Build the exec string. &i and &o in the exec string get replaced by input and output files. 37534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;;a++){ 37634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ApplyCommand[a] == '&'){ 37734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ApplyCommand[a+1] == 'i'){ 37834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Input file. 379d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang e += shellescape(ExecString+e, FileName); 38034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a += 1; 38134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project continue; 38234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 38334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ApplyCommand[a+1] == 'o'){ 38434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Needs an output file distinct from the input file. 385d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang e += shellescape(ExecString+e, TempName); 38634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a += 1; 38734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project TempUsed = TRUE; 38834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project continue; 38934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 39034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 39134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExecString[e++] = ApplyCommand[a]; 39234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ApplyCommand[a] == 0) break; 39334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 39434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 39534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowIt) printf("Cmd:%s\n",ExecString); 39634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 39734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project errno = 0; 39834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a = system(ExecString); 39934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 40034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a || errno){ 40134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // A command can however fail without errno getting set or system returning an error. 40234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (errno) perror("system"); 40334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Problem executing specified command"); 40434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 40534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 40634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (TempUsed){ 40734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Don't delete original file until we know a new one was created by the command. 40834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct stat dummy; 40934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (stat(TempName, &dummy) == 0){ 41034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unlink(FileName); 41134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project rename(TempName, FileName); 41234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 41334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("specified command did not produce expected output file"); 41434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 41534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 41634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 41734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 41834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 41934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// check if this file should be skipped based on contents. 42034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 42134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int CheckFileSkip(void) 42234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 42334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // I sometimes add code here to only process images based on certain 42434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // criteria - for example, only to convert non progressive Jpegs to progressives, etc.. 42534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 42634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (FilterModel){ 42734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Filtering processing by camera model. 42834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // This feature is useful when pictures from multiple cameras are colated, 42934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // the its found that one of the cameras has the time set incorrectly. 43034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (strstr(ImageInfo.CameraModel, FilterModel) == NULL){ 43134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Skip. 43234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return TRUE; 43334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 43434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 43534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 43634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ExifOnly){ 43734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Filtering by EXIF only. Skip all files that have no Exif. 43834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (FindSection(M_EXIF) == NULL){ 43934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return TRUE; 44034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 44134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 44234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 44334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (PortraitOnly == 1){ 44434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.Width > ImageInfo.Height) return TRUE; 44534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 44634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 44734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (PortraitOnly == -1){ 44834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.Width < ImageInfo.Height) return TRUE; 44934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 45034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 45134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return FALSE; 45234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 45334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 45434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 45534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Subsititute original name for '&i' if present in specified name. 45634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// This to allow specifying relative names when manipulating multiple files. 45734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 45834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic void RelativeName(char * OutFileName, const char * NamePattern, const char * OrigName) 45934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 46034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // If the filename contains substring "&i", then substitute the 46134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // filename for that. This gives flexibility in terms of processing 46234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // multiple files at a time. 46334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char * Subst; 46434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Subst = strstr(NamePattern, "&i"); 46534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Subst){ 46634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strncpy(OutFileName, NamePattern, Subst-NamePattern); 46734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project OutFileName[Subst-NamePattern] = 0; 46834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strncat(OutFileName, OrigName, PATH_MAX); 46934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strncat(OutFileName, Subst+2, PATH_MAX); 47034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 471d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncpy(OutFileName, NamePattern, PATH_MAX); 47234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 47334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 47434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 47534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 47634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef _WIN32 47734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 47834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Rename associated files 47934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 48034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid RenameAssociated(const char * FileName, char * NewBaseName) 48134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 48234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 48334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int PathLen; 48434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int ExtPos; 485d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char FilePattern[_MAX_PATH+1]; 486d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char NewName[_MAX_PATH+1]; 48734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct _finddata_t finddata; 48834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project long find_handle; 48934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 49034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for(ExtPos = strlen(FileName);FileName[ExtPos-1] != '.';){ 49134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (--ExtPos == 0) return; // No extension! 49234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 49334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 49434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy(FilePattern, FileName, ExtPos); 49534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FilePattern[ExtPos] = '*'; 49634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FilePattern[ExtPos+1] = '\0'; 49734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 498d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang for(PathLen = strlen(FileName);FileName[PathLen-1] != SLASH;){ 49934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (--PathLen == 0) break; 50034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 50134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 50234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project find_handle = _findfirst(FilePattern, &finddata); 50334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 50434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (;;){ 50534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (find_handle == -1) break; 50634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 50734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Eliminate the obvious patterns. 50834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!memcmp(finddata.name, ".",2)) goto next_file; 50934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!memcmp(finddata.name, "..",3)) goto next_file; 51034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (finddata.attrib & _A_SUBDIR) goto next_file; 51134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 512d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncpy(FilePattern+PathLen, finddata.name, PATH_MAX-PathLen); // full name with path 51334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 51434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(NewName, NewBaseName); 51534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for(a = strlen(finddata.name);finddata.name[a] != '.';){ 51634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (--a == 0) goto next_file; 51734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 518d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncat(NewName, finddata.name+a, _MAX_PATH-strlen(NewName)); // add extension to new name 51934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 52034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (rename(FilePattern, NewName) == 0){ 52134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Quiet){ 52234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("%s --> %s\n",FilePattern, NewName); 52334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 52434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 52534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 52634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project next_file: 52734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (_findnext(find_handle, &finddata) != 0) break; 52834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 52934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project _findclose(find_handle); 53034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 53134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 53234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 53334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 53434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Handle renaming of files by date. 53534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 53634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic void DoFileRenaming(const char * FileName) 53734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 53834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int NumAlpha = 0; 53934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int NumDigit = 0; 540d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang int PrefixPart = 0; // Where the actual filename starts. 541d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang int ExtensionPart; // Where the file extension starts. 54234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 54334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct tm tm; 54434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char NewBaseName[PATH_MAX*2]; 545d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang int AddLetter = 0; 546d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char NewName[PATH_MAX+2]; 54734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 548d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang ExtensionPart = strlen(FileName); 54934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;FileName[a];a++){ 550d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (FileName[a] == SLASH){ 55134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Don't count path component. 55234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project NumAlpha = 0; 55334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project NumDigit = 0; 55434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project PrefixPart = a+1; 55534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 55634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 55734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (FileName[a] == '.') ExtensionPart = a; // Remember where extension starts. 55834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 55934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (isalpha(FileName[a])) NumAlpha += 1; // Tally up alpha vs. digits to judge wether to rename. 56034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (isdigit(FileName[a])) NumDigit += 1; 56134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 56234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 56334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RenameToDate <= 1){ 56434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // If naming isn't forced, ensure name is mostly digits, or leave it alone. 56534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (NumAlpha > 8 || NumDigit < 4){ 56634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 56734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 56834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 56934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 57034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Exif2tm(&tm, ImageInfo.DateTime)){ 57134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("File '%s' contains no exif date stamp. Using file date\n",FileName); 57234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Use file date/time instead. 57334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm = *localtime(&ImageInfo.FileDateTime); 57434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 57534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 57634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 577d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncpy(NewBaseName, FileName, PATH_MAX); // Get path component of name. 57834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 57934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (strftime_args){ 58034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Complicated scheme for flexibility. Just pass the args to strftime. 58134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project time_t UnixTime; 58234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 58334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char *s; 58434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char pattern[PATH_MAX+20]; 58534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int n = ExtensionPart - PrefixPart; 58634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 58734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Call mktime to get weekday and such filled in. 58834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project UnixTime = mktime(&tm); 58934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ((int)UnixTime == -1){ 59034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Could not convert %s to unix time",ImageInfo.DateTime); 59134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 59234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 59334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 59434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Substitute "%f" for the original name (minus path & extension) 59534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project pattern[PATH_MAX-1]=0; 59634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strncpy(pattern, strftime_args, PATH_MAX-1); 59734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project while ((s = strstr(pattern, "%f")) && strlen(pattern) + n < PATH_MAX-1){ 59834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memmove(s + n, s + 2, strlen(s+2) + 1); 59934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memmove(s, FileName + PrefixPart, n); 60034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 60134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 60234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project { 60334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Sequential number renaming part. 60434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // '%i' type pattern becomes sequence number. 60534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int ppos = -1; 60634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;pattern[a];a++){ 60734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (pattern[a] == '%'){ 60834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ppos = a; 60934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (pattern[a] == 'i'){ 61034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ppos >= 0 && a<ppos+4){ 61134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Replace this part with a number. 612d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char pat[8], num[16]; 613d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang int l,nl; 61434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy(pat, pattern+ppos, 4); 61534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project pat[a-ppos] = 'd'; // Replace 'i' with 'd' for '%d' 61634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project pat[a-ppos+1] = '\0'; 61734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(num, pat, FileSequence); // let printf do the number formatting. 618d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang nl = strlen(num); 619d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang l = strlen(pattern+a+1); 620d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (ppos+nl+l+1 >= PATH_MAX) ErrFatal("str overflow"); 621d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang memmove(pattern+ppos+nl, pattern+a+1, l+1); 622d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang memcpy(pattern+ppos, num, nl); 62334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 62434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 62534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!isdigit(pattern[a])){ 62634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ppos = -1; 62734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 62834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 62934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 630d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strftime(NewName, PATH_MAX, pattern, &tm); 63134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 63234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // My favourite scheme. 633d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang sprintf(NewName, "%02d%02d-%02d%02d%02d", 63434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); 63534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 63634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 637d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang NewBaseName[PrefixPart] = 0; 638d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang CatPath(NewBaseName, NewName); 639d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 640d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang AddLetter = isdigit(NewBaseName[strlen(NewBaseName)-1]); 64134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;;a++){ 642d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char NewName[PATH_MAX+10]; 64334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char NameExtra[3]; 64434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct stat dummy; 64534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 64634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a){ 64734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Generate a suffix for the file name if previous choice of names is taken. 64834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // depending on wether the name ends in a letter or digit, pick the opposite to separate 64934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // it. This to avoid using a separator character - this because any good separator 65034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // is before the '.' in ascii, and so sorting the names would put the later name before 65134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // the name without suffix, causing the pictures to more likely be out of order. 652d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (AddLetter){ 653d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang NameExtra[0] = (char)('a'-1+a); // Try a,b,c,d... for suffix if it ends in a number. 65434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 655d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang NameExtra[0] = (char)('0'-1+a); // Try 0,1,2,3... for suffix if it ends in a latter. 65634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 65734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project NameExtra[1] = 0; 65834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 65934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project NameExtra[0] = 0; 66034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 66134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 66234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(NewName, "%s%s.jpg", NewBaseName, NameExtra); 66334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 66434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!strcmp(FileName, NewName)) break; // Skip if its already this name. 66534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 666d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (!EnsurePathExists(NewBaseName)){ 667d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang break; 668d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang } 669d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 670d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 67134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (stat(NewName, &dummy)){ 67234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // This name does not pre-exist. 67334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (rename(FileName, NewName) == 0){ 67434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("%s --> %s\n",FileName, NewName); 67534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef _WIN32 67634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RenameAssociatedFiles){ 67734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(NewName, "%s%s", NewBaseName, NameExtra); 67834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RenameAssociated(FileName, NewName); 67934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 68034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 68134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 68234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: Couldn't rename '%s' to '%s'\n",FileName, NewName); 68334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 68434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 685d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 68634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 68734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 688d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (a > 25 || (!AddLetter && a > 9)){ 68934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Possible new names for for '%s' already exist\n",FileName); 69034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 69134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 69234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 69334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 69434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 69534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 69634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Rotate the image and its thumbnail 69734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 69834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int DoAutoRotate(const char * FileName) 69934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 70034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.Orientation >= 2 && ImageInfo.Orientation <= 8){ 70134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project const char * Argument; 70234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Argument = ClearOrientation(); 70334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 70434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!ZeroRotateTagOnly){ 70534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char RotateCommand[PATH_MAX*2+50]; 70634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Argument == NULL){ 70734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Orientation screwup"); 70834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 70934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 710d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang sprintf(RotateCommand, "jpegtran -trim -%s -outfile &o &i", Argument); 71134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ApplyCommand = RotateCommand; 71234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoCommand(FileName, FALSE); 71334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ApplyCommand = NULL; 71434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 71534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Now rotate the thumbnail, if there is one. 71634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.ThumbnailOffset && 71734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.ThumbnailSize && 71834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.ThumbnailAtEnd){ 71934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Must have a thumbnail that exists and is modifieable. 72034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 721d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char ThumbTempName_in[PATH_MAX+5]; 722d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char ThumbTempName_out[PATH_MAX+5]; 72334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 72434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(ThumbTempName_in, FileName); 72534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcat(ThumbTempName_in, ".thi"); 72634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(ThumbTempName_out, FileName); 72734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcat(ThumbTempName_out, ".tho"); 72834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project SaveThumbnail(ThumbTempName_in); 729d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang sprintf(RotateCommand,"jpegtran -trim -%s -outfile \"%s\" \"%s\"", 73034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Argument, ThumbTempName_out, ThumbTempName_in); 73134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 73234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (system(RotateCommand) == 0){ 73334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Put the thumbnail back in the header 73434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ReplaceThumbnail(ThumbTempName_out); 73534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 73634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 73734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unlink(ThumbTempName_in); 73834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unlink(ThumbTempName_out); 73934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 74034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 74134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return TRUE; 74234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 74334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return FALSE; 74434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 74534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 74634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 74734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Regenerate the thumbnail using mogrify 74834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 74934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic int RegenerateThumbnail(const char * FileName) 75034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 75134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char ThumbnailGenCommand[PATH_MAX*2+50]; 75234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.ThumbnailOffset == 0 || ImageInfo.ThumbnailAtEnd == FALSE){ 75334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // There is no thumbnail, or the thumbnail is not at the end. 75434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return FALSE; 75534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 75634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 75734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(ThumbnailGenCommand, "mogrify -thumbnail %dx%d \"%s\"", 75834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RegenThumbnail, RegenThumbnail, FileName); 75934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 76034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (system(ThumbnailGenCommand) == 0){ 76134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Put the thumbnail back in the header 76234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return ReplaceThumbnail(FileName); 76334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 76434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Unable to run 'mogrify' command"); 76534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return FALSE; 76634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 76734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 76834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 76934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 77034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Do selected operations to one file at a time. 77134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 77234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid ProcessFile(const char * FileName) 77334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 77434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int Modified = FALSE; 775d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang ReadMode_t ReadMode; 776d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 777d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (strlen(FileName) >= PATH_MAX-1){ 778d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang // Protect against buffer overruns in strcpy / strcat's on filename 779d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang ErrFatal("filename too long"); 780d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang } 781d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang 782d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang ReadMode = READ_METADATA; 78334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CurrentFile = FileName; 78434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FilesMatched = 1; 78534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 78634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ResetJpgfile(); 78734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 78834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Start with an empty image information structure. 78934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memset(&ImageInfo, 0, sizeof(ImageInfo)); 79034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.FlashUsed = -1; 79134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.MeteringMode = -1; 79234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.Whitebalance = -1; 79334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 79434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Store file date/time. 79534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project { 79634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct stat st; 79734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (stat(FileName, &st) >= 0){ 79834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.FileDateTime = st.st_mtime; 79934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.FileSize = st.st_size; 80034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 80134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("No such file"); 80234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 80334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 80434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 80534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DoModify || RenameToDate || Exif2FileTime){ 80634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (access(FileName, 2 /*W_OK*/)){ 80734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Skipping readonly file '%s'\n",FileName); 80834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 80934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 81034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 81134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 81234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strncpy(ImageInfo.FileName, FileName, PATH_MAX); 81334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 81434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 81534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ApplyCommand || AutoRotate){ 81634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Applying a command is special - the headers from the file have to be 81734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // pre-read, then the command executed, and then the image part of the file read. 81834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 81934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!ReadJpegFile(FileName, READ_METADATA)) return; 82034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 82134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #ifdef MATTHIAS 82234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (AutoResize){ 82334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Automatic resize computation - to customize for each run... 82434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (AutoResizeCmdStuff() == 0){ 82534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardData(); 82634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 82734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 82834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 82934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #endif // MATTHIAS 83034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 83134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 83234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CheckFileSkip()){ 83334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardData(); 83434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 83534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 83634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 83734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardAllButExif(); 83834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 83934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (AutoRotate){ 84034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DoAutoRotate(FileName)){ 84134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 84234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 84334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 84434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct stat dummy; 84534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoCommand(FileName, Quiet ? FALSE : TRUE); 84634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 84734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (stat(FileName, &dummy)){ 84834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // The file is not there anymore. Perhaps the command 84934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // was a delete or a move. So we are all done. 85034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 85134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 85234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 85334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 85434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ReadMode = READ_IMAGE; // Don't re-read exif section again on next read. 85534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 85634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (ExifXferScrFile){ 85734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char RelativeExifName[PATH_MAX+1]; 85834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 85934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Make a relative name. 86034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RelativeName(RelativeExifName, ExifXferScrFile, FileName); 86134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 86234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if(!ReadJpegFile(RelativeExifName, READ_METADATA)) return; 86334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 86434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardAllButExif(); // Don't re-read exif section again on next read. 86534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 86634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 86734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ReadMode = READ_IMAGE; 86834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 86934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 87034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DoModify){ 87134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ReadMode |= READ_IMAGE; 87234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 87334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 87434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!ReadJpegFile(FileName, ReadMode)) return; 87534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 87634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CheckFileSkip()){ 87734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardData(); 87834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 87934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 88034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 88134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FileSequence += 1; // Count files processed. 88234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 88334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowConcise){ 88434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowConciseImageInfo(); 88534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 88634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!(DoModify || DoReadAction) || ShowTags){ 88734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowImageInfo(ShowFileInfo); 88834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 88934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project { 89034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // if IPTC section is present, show it also. 89134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Section_t * IptcSection; 89234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project IptcSection = FindSection(M_IPTC); 89334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 89434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (IptcSection){ 89534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project show_IPTC(IptcSection->Data, IptcSection->Size); 89634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 89734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 89834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("\n"); 89934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 90034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 90134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 90234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ThumbSaveName){ 90334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char OutFileName[PATH_MAX+1]; 90434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Make a relative name. 90534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RelativeName(OutFileName, ThumbSaveName, FileName); 90634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 90734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (SaveThumbnail(OutFileName)){ 90834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Created: '%s'\n", OutFileName); 90934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 91034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 91134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 91234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CreateExifSection){ 91334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Make a new minimal exif section 91434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project create_EXIF(NULL, 0, 0); 91534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 91634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 91734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 91834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RegenThumbnail){ 91934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RegenerateThumbnail(FileName)){ 92034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 92134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 92234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 92334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 92434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ThumbInsertName){ 92534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char ThumbFileName[PATH_MAX+1]; 92634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Make a relative name. 92734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RelativeName(ThumbFileName, ThumbInsertName, FileName); 92834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 92934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ReplaceThumbnail(ThumbFileName)){ 93034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 93134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 93234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (TrimExif){ 93334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Deleting thumbnail is just replacing it with a null thumbnail. 93434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ReplaceThumbnail(NULL)){ 93534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 93634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 93734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 93834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 93934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ( 94034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef MATTHIAS 94134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project AddComment || RemComment || 94234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 94334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project EditComment || CommentInsertfileName || CommentInsertLiteral){ 94434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 94534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Section_t * CommentSec; 946d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char Comment[MAX_COMMENT_SIZE+1]; 94734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int CommentSize; 94834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 94934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec = FindSection(M_COM); 95034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 95134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentSec == NULL){ 95234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned char * DummyData; 95334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 95434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DummyData = (uchar *) malloc(3); 95534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DummyData[0] = 0; 95634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DummyData[1] = 2; 95734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DummyData[2] = 0; 95834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec = CreateSection(M_COM, DummyData, 2); 95934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 96034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 96134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSize = CommentSec->Size-2; 962d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (CommentSize > MAX_COMMENT_SIZE){ 963d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang fprintf(stderr, "Truncating comment at %d chars\n",MAX_COMMENT_SIZE); 964d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang CommentSize = MAX_COMMENT_SIZE; 96534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 96634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 96734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentInsertfileName){ 96834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Read a new comment section from file. 96934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char CommentFileName[PATH_MAX+1]; 97034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FILE * CommentFile; 97134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 97234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Make a relative name. 97334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RelativeName(CommentFileName, CommentInsertfileName, FileName); 97434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 97534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentFile = fopen(CommentFileName,"r"); 97634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentFile == NULL){ 97734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Could not open '%s'\n",CommentFileName); 97834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 97934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Read it in. 98034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Replace the section. 98134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSize = fread(Comment, 1, 999, CommentFile); 98234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fclose(CommentFile); 98334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentSize < 0) CommentSize = 0; 98434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 98534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (CommentInsertLiteral){ 986d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang strncpy(Comment, CommentInsertLiteral, MAX_COMMENT_SIZE); 98734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSize = strlen(Comment); 98834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 98934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef MATTHIAS 990d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char CommentZt[MAX_COMMENT_SIZE+1]; 99134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy(CommentZt, (char *)CommentSec->Data+2, CommentSize); 99234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentZt[CommentSize] = '\0'; 99334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ModifyDescriptComment(Comment, CommentZt)){ 99434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 99534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSize = strlen(Comment); 99634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 99734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (EditComment) 99834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#else 99934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy(Comment, (char *)CommentSec->Data+2, CommentSize); 100034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 100134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project { 1002d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char EditFileName[PATH_MAX+5]; 100334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(EditFileName, FileName); 100434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcat(EditFileName, ".txt"); 100534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 100634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSize = FileEditComment(EditFileName, Comment, CommentSize); 100734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 100834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 100934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 101034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (strcmp(Comment, (char *)CommentSec->Data+2)){ 101134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Discard old comment section and put a new one in. 101234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int size; 101334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project size = CommentSize+2; 101434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project free(CommentSec->Data); 101534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec->Size = size; 101634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec->Data = malloc(size); 101734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec->Data[0] = (uchar)(size >> 8); 101834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec->Data[1] = (uchar)(size); 101934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy((CommentSec->Data)+2, Comment, size-2); 102034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 102134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 102234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Modified){ 102334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Comment not modified\n"); 102434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 102534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 102634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 102734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 102834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentSavefileName){ 102934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Section_t * CommentSec; 103034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSec = FindSection(M_COM); 103134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 103234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentSec != NULL){ 103334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char OutFileName[PATH_MAX+1]; 103434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FILE * CommentFile; 103534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 103634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Make a relative name. 103734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RelativeName(OutFileName, CommentSavefileName, FileName); 103834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 103934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentFile = fopen(OutFileName,"w"); 104034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 104134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentFile){ 104234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fwrite((char *)CommentSec->Data+2, CommentSec->Size-2 ,1, CommentFile); 104334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fclose(CommentFile); 104434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 104534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Could not write comment file"); 104634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 104734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 104834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("File '%s' contains no comment section\n",FileName); 104934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 105034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 105134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 105234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ExifTimeAdjust || ExifTimeSet || DateSetChars || FileTimeToExif){ 105334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.numDateTimeTags){ 105434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct tm tm; 105534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project time_t UnixTime; 105634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char TempBuf[50]; 105734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 105834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Section_t * ExifSection; 105934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ExifTimeSet){ 106034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // A time to set was specified. 106134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project UnixTime = ExifTimeSet; 106234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 106334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (FileTimeToExif){ 106434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FileTimeAsString(ImageInfo.DateTime); 106534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 106634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DateSetChars){ 106734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy(ImageInfo.DateTime, DateSet, DateSetChars); 106834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a = 1970; 106934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sscanf(DateSet, "%d", &a); 107034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a < 1970){ 107134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(TempBuf, ImageInfo.DateTime); 107234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project goto skip_unixtime; 107334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 107434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 107534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // A time offset to adjust by was specified. 107634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Exif2tm(&tm, ImageInfo.DateTime)) goto badtime; 107734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 107834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Convert to unix 32 bit time value, add offset, and convert back. 107934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project UnixTime = mktime(&tm); 108034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ((int)UnixTime == -1) goto badtime; 108134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project UnixTime += ExifTimeAdjust; 108234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 108334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm = *localtime(&UnixTime); 108434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 108534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Print to temp buffer first to avoid putting null termination in destination. 108634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // snprintf() would do the trick, hbut not available everywhere (like FreeBSD 4.4) 108734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sprintf(TempBuf, "%04d:%02d:%02d %02d:%02d:%02d", 108834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 108934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_hour, tm.tm_min, tm.tm_sec); 109034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 109134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectskip_unixtime: 109234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExifSection = FindSection(M_EXIF); 109334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 109434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a = 0; a < ImageInfo.numDateTimeTags; a++) { 109534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project uchar * Pointer; 109634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Pointer = ExifSection->Data+ImageInfo.DateTimeOffsets[a]+8; 109734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project memcpy(Pointer, TempBuf, 19); 109834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 1099d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang memcpy(ImageInfo.DateTime, TempBuf, 19); 110034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 110134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Modified = TRUE; 110234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 110334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("File '%s' contains no Exif timestamp to change\n", FileName); 110434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 110534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 110634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 110734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DeleteComments){ 110834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RemoveSectionType(M_COM)) Modified = TRUE; 110934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 111034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DeleteExif){ 111134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RemoveSectionType(M_EXIF)) Modified = TRUE; 111234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 111334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DeleteIptc){ 111434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RemoveSectionType(M_IPTC)) Modified = TRUE; 111534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 1116d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (DeleteXmp){ 1117d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang if (RemoveSectionType(M_XMP)) Modified = TRUE; 1118d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang } 111934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DeleteUnknown){ 112034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RemoveUnknownSections()) Modified = TRUE; 112134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 112234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 112334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 112434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Modified){ 1125d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang char BackupName[PATH_MAX+5]; 112634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct stat buf; 112734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 112834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Quiet) printf("Modified: %s\n",FileName); 112934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 113034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(BackupName, FileName); 113134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcat(BackupName, ".t"); 113234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 113334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Remove any .old file name that may pre-exist 113434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unlink(BackupName); 113534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 113634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Rename the old file. 113734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project rename(FileName, BackupName); 113834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 113934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Write the new file. 114034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (WriteJpegFile(FileName)) { 114134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 114234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Copy the access rights from original file 114334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (stat(BackupName, &buf) == 0){ 114434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // set Unix access rights and time to new file 114534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct utimbuf mtime; 114634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project chmod(FileName, buf.st_mode); 114734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 114834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project mtime.actime = buf.st_mtime; 114934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project mtime.modtime = buf.st_mtime; 115034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 115134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project utime(FileName, &mtime); 115234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 115334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 115434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Now that we are done, remove original file. 115534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unlink(BackupName); 115634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } else { 115734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // move back the backup file 115834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project rename(BackupName, FileName); 115934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 116034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 116134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 116234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 116334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Exif2FileTime){ 116434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Set the file date to the date from the exif header. 116534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ImageInfo.numDateTimeTags){ 116634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Converte the file date to Unix time. 116734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct tm tm; 116834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project time_t UnixTime; 116934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct utimbuf mtime; 117034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Exif2tm(&tm, ImageInfo.DateTime)) goto badtime; 117134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 117234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project UnixTime = mktime(&tm); 117334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ((int)UnixTime == -1){ 117434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project goto badtime; 117534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 117634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 117734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project mtime.actime = UnixTime; 117834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project mtime.modtime = UnixTime; 117934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 118034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (utime(FileName, &mtime) != 0){ 118134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: Could not change time of file '%s'\n",FileName); 118234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 118334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Quiet) printf("%s\n",FileName); 118434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 118534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 118634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("File '%s' contains no Exif timestamp\n", FileName); 118734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 118834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 118934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 119034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Feature to rename image according to date and time from camera. 119134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // I use this feature to put images from multiple digicams in sequence. 119234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 119334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RenameToDate){ 119434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoFileRenaming(FileName); 119534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 119634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardData(); 119734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 119834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectbadtime: 119934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: Time '%s': cannot convert to Unix time\n",ImageInfo.DateTime); 120034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DiscardData(); 120134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 120234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 120334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 120434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// complain about bad state of the command line. 120534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 120634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectstatic void Usage (void) 120734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 120834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Jhead is a program for manipulating settings and thumnails in Exif jpeg headers\n" 1209d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang "used by most Digital Cameras. v"JHEAD_VERSION" Matthias Wandel, Mar 02 2009.\n" 121034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "http://www.sentex.net/~mwandel/jhead\n" 121134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\n"); 121234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 121334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Usage: %s [options] files\n", progname); 121434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Where:\n" 121534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " files path/filenames with or without wildcards\n" 121634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 121734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "[options] are:\n" 121834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\nGENERAL METADATA:\n" 121934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -te <name> Transfer exif header from another image file <name>\n" 122034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Uses same name mangling as '-st' option\n" 122134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -dc Delete comment field (as left by progs like Photoshop & Compupic)\n" 122234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -de Strip Exif section (smaller JPEG file, but lose digicam info)\n" 122334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -di Delete IPTC section (from Photoshop, or Picasa)\n" 1224d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang " -dx Deletex XMP section\n" 122534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -du Delete non image sections except for Exif and comment sections\n" 122634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -purejpg Strip all unnecessary data from jpeg (combines -dc -de and -du)\n" 122734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -mkexif Create new minimal exif section (overwrites pre-existing exif)\n" 122834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ce Edit comment field. Uses environment variable 'editor' to\n" 122934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " determine which editor to use. If editor not set, uses VI\n" 123034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " under Unix and notepad with windows\n" 123134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -cs <name> Save comment section to a file\n" 123234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ci <name> Insert comment section from a file. -cs and -ci use same naming\n" 123334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " scheme as used by the -st option\n" 123434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -cl string Insert literal comment string\n" 123534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 123634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\nDATE / TIME MANIPULATION:\n" 123734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ft Set file modification time to Exif time\n" 123834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -dsft Set Exif time to file modification time\n" 123934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -n[format-string]\n" 124034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Rename files according to date. Uses exif date if present, file\n" 124134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " date otherwise. If the optional format-string is not supplied,\n" 124234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " the format is mmdd-hhmmss. If a format-string is given, it is\n" 124334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " is passed to the 'strftime' function for formatting\n" 124434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " In addition to strftime format codes:\n" 124534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " '%%f' as part of the string will include the original file name\n" 124634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " '%%i' will include a sequence number, starting from 1. You can\n" 124734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " You can specify '%%03i' for example to get leading zeros.\n" 124834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " This feature is useful for ordering files from multiple digicams to\n" 124934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " sequence of taking. Only renames files whose names are mostly\n" 125034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " numerical (as assigned by digicam)\n" 125134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " The '.jpg' is automatically added to the end of the name. If the\n" 125234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " destination name already exists, a letter or digit is added to \n" 125334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " the end of the name to make it unique.\n" 1254d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang " The new name may include a path as part of the name. If this path\n" 1255d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang " does not exist, it will be created\n" 125634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -nf[format-string]\n" 125734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Same as -n, but rename regardless of original name\n" 125834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -a (Windows only) Rename files with same name but different extension\n" 125934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Use together with -n to rename .AVI files from exif in .THM files\n" 126034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " for example\n" 126134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ta<+|->h[:mm[:ss]]\n" 126234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Adjust time by h:mm backwards or forwards. Useful when having\n" 126334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " taken pictures with the wrong time set on the camera, such as when\n" 126434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " traveling across time zones or DST changes. Dates can be adjusted\n" 126534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " by offsetting by 24 hours or more. For large date adjustments,\n" 126634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " use the -da option\n" 126734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -da<date>-<date>\n" 126834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Adjust date by large amounts. This is used to fix photos from\n" 126934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " cameras where the date got set back to the default camera date\n" 127034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " by accident or battery removal.\n" 127134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " To deal with different months and years having different numbers of\n" 127234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " days, a simple date-month-year offset would result in unexpected\n" 127334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " results. Instead, the difference is specified as desired date\n" 1274d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang " minus original date. Date is specified as yyyy:mm:dd or as date\n" 1275d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang " and time in the format yyyy:mm:dd/hh:mm:ss\n" 127634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ts<time> Set the Exif internal time to <time>. <time> is in the format\n" 127734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " yyyy:mm:dd-hh:mm:ss\n" 127834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ds<date> Set the Exif internal date. <date> is in the format YYYY:MM:DD\n" 127934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " or YYYY:MM or YYYY\n" 128034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 128134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\nTHUMBNAIL MANIPULATION:\n" 128234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -dt Remove exif integral thumbnails. Typically trims 10k\n" 128334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -st <name> Save Exif thumbnail, if there is one, in file <name>\n" 128434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " If output file name contains the substring \"&i\" then the\n" 128534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " image file name is substitute for the &i. Note that quotes around\n" 128634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " the argument are required for the '&' to be passed to the program.\n" 128734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifndef _WIN32 128834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " An output name of '-' causes thumbnail to be written to stdout\n" 128934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 129034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -rt <name> Replace Exif thumbnail. Can only be done with headers that\n" 129134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " already contain a thumbnail.\n" 129234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -rgt[size] Regnerate exif thumbnail. Only works if image already\n" 129334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " contains a thumbail. size specifies maximum height or width of\n" 129434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " thumbnail. Relies on 'mogrify' programs to be on path\n" 129534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 129634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\nROTATION TAG MANIPULATION:\n" 129734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -autorot Invoke jpegtran to rotate images according to Exif orientation tag\n" 129834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Note: Windows users must get jpegtran for this to work\n" 129934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -norot Zero out the rotation tag. This to avoid some browsers from\n" 130034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " rotating the image again after you rotated it but neglected to\n" 130134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " clear the rotation tag\n" 130234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 130334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\nOUTPUT VERBOSITY CONTROL:\n" 130434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -h help (this text)\n" 130534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -v even more verbose output\n" 130634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -q Quiet (no messages on success, like Unix)\n" 130734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -V Show jhead version\n" 130834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -exifmap Dump header bytes, annotate. Pipe thru sort for better viewing\n" 130934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -se Supress error messages relating to corrupt exif header structure\n" 131034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -c concise output\n" 131134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -nofinfo Don't show file info (name/size/date)\n" 131234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 131334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\nFILE MATCHING AND SELECTION:\n" 131434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -model model\n" 131534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Only process files from digicam containing model substring in\n" 131634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " camera model description\n" 131734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -exonly Skip all files that don't have an exif header (skip all jpegs that\n" 131834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " were not created by digicam)\n" 131934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -cmd command\n" 132034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Apply 'command' to every file, then re-insert exif and command\n" 132134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " sections into the image. &i will be substituted for the input file\n" 132234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " name, and &o (if &o is used). Use quotes around the command string\n" 132334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " This is most useful in conjunction with the free ImageMagick tool. \n" 132434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " For example, with my Canon S100, which suboptimally compresses\n" 132534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " jpegs I can specify\n" 132634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " jhead -cmd \"mogrify -quality 80 &i\" *.jpg\n" 132734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " to re-compress a lot of images using ImageMagick to half the size,\n" 132834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " and no visible loss of quality while keeping the exif header\n" 132934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " Another invocation I like to use is jpegtran (hard to find for\n" 133034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " windows). I type:\n" 133134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " jhead -cmd \"jpegtran -progressive &i &o\" *.jpg\n" 133234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " to convert jpegs to progressive jpegs (Unix jpegtran syntax\n" 133334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " differs slightly)\n" 133434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -orp Only operate on 'portrait' aspect ratio images\n" 133534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -orl Only operate on 'landscape' aspect ratio images\n" 133634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef _WIN32 133734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -r No longer supported. Use the ** wildcard to recurse directories\n" 133834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " with instead.\n" 133934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " examples:\n" 134034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " jhead **/*.jpg\n" 134134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " jhead \"c:\\my photos\\**\\*.jpg\"\n" 134234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 134334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 134434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 134534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef MATTHIAS 134634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "\n" 134734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -cr Remove comment tag (my way)\n" 134834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ca Add comment tag (my way)\n" 134934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " -ar Auto resize to fit in 1024x1024, but never less than half\n" 135034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif //MATTHIAS 135134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 135234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 135334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ); 135434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 135534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(EXIT_FAILURE); 135634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 135734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 135834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 135934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 136034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Parse specified date or date+time from command line. 136134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 136234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projecttime_t ParseCmdDate(char * DateSpecified) 136334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 136434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 136534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct tm tm; 136634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project time_t UnixTime; 136734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 136834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_wday = -1; 136934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_hour = tm.tm_min = tm.tm_sec = 0; 137034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 137134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a = sscanf(DateSpecified, "%d:%d:%d/%d:%d:%d", 137234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 137334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project &tm.tm_hour, &tm.tm_min, &tm.tm_sec); 137434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 137534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a != 3 && a < 5){ 137634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Date must be YYYY:MM:DD, YYYY:MM:DD+HH:MM 137734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // or YYYY:MM:DD+HH:MM:SS 137834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Could not parse specified date"); 137934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 138034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_isdst = -1; 138134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_mon -= 1; // Adjust for unix zero-based months 138234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project tm.tm_year -= 1900; // Adjust for year starting at 1900 138334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 138434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project UnixTime = mktime(&tm); 138534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (UnixTime == -1){ 138634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Specified time is invalid or out of range"); 138734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 138834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 138934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return UnixTime; 139034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 139134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 139234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 139334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// The main program. 139434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 139534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#if 0 139634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectint main (int argc, char **argv) 139734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 139834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int argn; 139934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char * arg; 140034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project progname = argv[0]; 140134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 140234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (argn=1;argn<argc;argn++){ 140334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project arg = argv[argn]; 140434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (arg[0] != '-') break; // Filenames from here on. 140534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 140634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // General metadata options: 140734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!strcmp(arg,"-te")){ 140834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExifXferScrFile = argv[++argn]; 140934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 141034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-dc")){ 141134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteComments = TRUE; 141234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 141334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-de")){ 141434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteExif = TRUE; 141534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 141634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-di")){ 141734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteIptc = TRUE; 141834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 1419d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang }else if (!strcmp(arg,"-dx")){ 1420d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang DeleteXmp = TRUE; 1421d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang DoModify = TRUE; 142234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg, "-du")){ 142334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteUnknown = TRUE; 142434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 142534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg, "-purejpg")){ 142634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteExif = TRUE; 142734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteComments = TRUE; 142834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteIptc = TRUE; 142934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DeleteUnknown = TRUE; 1430d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang DeleteXmp = TRUE; 143134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 143234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-ce")){ 143334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project EditComment = TRUE; 143434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 143534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-cs")){ 143634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentSavefileName = argv[++argn]; 143734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-ci")){ 143834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentInsertfileName = argv[++argn]; 143934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 144034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-cl")){ 144134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CommentInsertLiteral = argv[++argn]; 144234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 144334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-mkexif")){ 144434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project CreateExifSection = TRUE; 144534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 144634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 144734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Output verbosity control 144834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-h")){ 144934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Usage(); 145034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-v")){ 145134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowTags = TRUE; 145234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-q")){ 145334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Quiet = TRUE; 145434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-V")){ 145534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Jhead version: "JHEAD_VERSION" Compiled: "__DATE__"\n"); 145634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(0); 145734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-exifmap")){ 145834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DumpExifMap = TRUE; 145934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-se")){ 146034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project SupressNonFatalErrors = TRUE; 146134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-c")){ 146234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowConcise = TRUE; 146334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-nofinfo")){ 146434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowFileInfo = 0; 146534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 146634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Thumbnail manipulation options 146734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-dt")){ 146834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project TrimExif = TRUE; 146934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 147034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-st")){ 147134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ThumbSaveName = argv[++argn]; 147234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoReadAction = TRUE; 147334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-rt")){ 147434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ThumbInsertName = argv[++argn]; 147534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 147634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-rgt", 4)){ 147734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RegenThumbnail = 160; 147834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project sscanf(arg+4, "%d", &RegenThumbnail); 147934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RegenThumbnail > 320){ 148034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Specified thumbnail geometry too big!"); 148134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 148234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 148334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 148434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Rotation tag manipulation 148534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-autorot")){ 148634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project AutoRotate = 1; 148734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 148834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-norot")){ 148934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project AutoRotate = 1; 149034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ZeroRotateTagOnly = 1; 149134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 149234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 149334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Date/Time manipulation options 149434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-n",2)){ 149534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RenameToDate = 1; 149634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoReadAction = TRUE; // Rename doesn't modify file, so count as read action. 149734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project arg+=2; 149834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (*arg == 'f'){ 149934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RenameToDate = 2; 150034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project arg++; 150134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 150234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (*arg){ 150334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // A strftime format string is supplied. 150434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strftime_args = arg; 1505d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang #ifdef _WIN32 1506d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang SlashToNative(strftime_args); 1507d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang #endif 150834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project //printf("strftime_args = %s\n",arg); 150934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 151034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-a")){ 151134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #ifndef _WIN32 151234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Error: -a only supported in Windows version"); 1513d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang #else 1514d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang RenameAssociatedFiles = TRUE; 1515d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang #endif 151634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-ft")){ 151734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Exif2FileTime = TRUE; 151834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoReadAction = TRUE; 151934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-ta",3)){ 152034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Time adjust feature. 152134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int hours, minutes, seconds, n; 152234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project minutes = seconds = 0; 152334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (arg[3] != '-' && arg[3] != '+'){ 152434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Error: -ta must be followed by +/- and a time"); 152534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 152634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project n = sscanf(arg+4, "%d:%d:%d", &hours, &minutes, &seconds); 152734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 152834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (n < 1){ 152934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Error: -ta must be immediately followed by time"); 153034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 153134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ExifTimeAdjust) ErrFatal("Can only use one of -da or -ta options at once"); 153234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExifTimeAdjust = hours*3600 + minutes*60 + seconds; 153334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (arg[3] == '-') ExifTimeAdjust = -ExifTimeAdjust; 153434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 153534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-da",3)){ 153634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Date adjust feature (large time adjustments) 153734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project time_t NewDate, OldDate = 0; 153834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char * pOldDate; 153934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project NewDate = ParseCmdDate(arg+3); 154034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project pOldDate = strstr(arg+1, "-"); 154134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (pOldDate){ 154234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project OldDate = ParseCmdDate(pOldDate+1); 154334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 154434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Must specifiy second date for -da option"); 154534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 154634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ExifTimeAdjust) ErrFatal("Can only use one of -da or -ta options at once"); 154734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExifTimeAdjust = NewDate-OldDate; 154834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 154934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-dsft",5)){ 155034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Set file time to date/time in exif 155134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FileTimeToExif = TRUE; 155234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 155334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-ds",3)){ 155434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Set date feature 155534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 155634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Check date validity and copy it. Could be incompletely specified. 155734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project strcpy(DateSet, "0000:01:01"); 155834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;arg[a+3];a++){ 155934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (isdigit(DateSet[a])){ 156034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!isdigit(arg[a+3])){ 156134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a = 0; 156234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 156334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 156434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 156534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (arg[a+3] != ':'){ 156634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project a=0; 156734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 156834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 156934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 157034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DateSet[a] = arg[a+3]; 157134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 157234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a < 4 || a > 10){ 157334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Date must be in format YYYY, YYYY:MM, or YYYY:MM:DD"); 157434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 157534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DateSetChars = a; 157634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 157734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!memcmp(arg,"-ts",3)){ 157834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Set the exif time. 157934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Time must be specified as "yyyy:mm:dd-hh:mm:ss" 158034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project char * c; 158134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project struct tm tm; 158234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 158334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project c = strstr(arg+1, "-"); 158434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (c) *c = ' '; // Replace '-' with a space. 158534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 158634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!Exif2tm(&tm, arg+3)){ 158734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("-ts option must be followed by time in format yyyy:mmm:dd-hh:mm:ss\n" 158834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project "Example: jhead -ts2001:01:01-12:00:00 foo.jpg"); 158934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 159034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 159134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExifTimeSet = mktime(&tm); 159234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 159334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ((int)ExifTimeSet == -1) ErrFatal("Time specified is out of range"); 159434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 159534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 159634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // File matching and selection 159734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-model")){ 159834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (argn+1 >= argc) Usage(); // No extra argument. 159934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FilterModel = argv[++argn]; 160034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-exonly")){ 160134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ExifOnly = 1; 160234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-orp")){ 160334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project PortraitOnly = 1; 160434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-orl")){ 160534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project PortraitOnly = -1; 160634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-cmd")){ 160734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (argn+1 >= argc) Usage(); // No extra argument. 160834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ApplyCommand = argv[++argn]; 160934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 161034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 161134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#ifdef MATTHIAS 161234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-ca")){ 161334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Its a literal comment. Add. 161434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project AddComment = argv[++argn]; 161534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 161634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-cr")){ 161734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Its a literal comment. Remove this keyword. 161834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project RemComment = argv[++argn]; 161934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 162034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else if (!strcmp(arg,"-ar")){ 162134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project AutoResize = TRUE; 162234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowConcise = TRUE; 162334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ApplyCommand = (char *)1; // Must be non null so it does commands. 162434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DoModify = TRUE; 162534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif // MATTHIAS 162634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 162734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Argument '%s' not understood\n",arg); 162834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Use jhead -h for list of arguments\n"); 162934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(-1); 163034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 163134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (argn >= argc){ 163234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Used an extra argument - becuase the last argument 163334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // used up an extr argument. 163434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Extra argument required"); 163534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 163634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 163734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (argn == argc){ 163834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("No files to process. Use -h for help"); 163934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 164034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 164134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ThumbSaveName != NULL && strcmp(ThumbSaveName, "&i") == 0){ 164234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: By specifying \"&i\" for the thumbail name, your original file\n" 164334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " will be overwitten. If this is what you really want,\n" 164434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " specify -st \"./&i\" to override this check\n"); 164534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(0); 164634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 164734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 164834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (RegenThumbnail){ 164934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ThumbSaveName || ThumbInsertName){ 165034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: Cannot regen and save or insert thumbnail in same run\n"); 165134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(0); 165234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 165334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 165434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 165534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (EditComment){ 165634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (CommentSavefileName != NULL || CommentInsertfileName != NULL){ 165734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Error: Cannot use -ce option in combination with -cs or -ci\n"); 165834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project exit(0); 165934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 166034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 166134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 166234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 166334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ExifXferScrFile){ 166434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (FilterModel || ApplyCommand){ 166534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrFatal("Error: Filter by model and/or applying command to files\n" 166634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project " invalid while transfering Exif headers"); 166734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 166834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 166934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 167034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FileSequence = 0; 167134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (;argn<argc;argn++){ 167234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project FilesMatched = FALSE; 167334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 167434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #ifdef _WIN32 1675d6a02c32e6fa83fad5794b0e19b1d28563e5a99bChih-Chung Chang SlashToNative(argv[argn]); 167634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Use my globbing module to do fancier wildcard expansion with recursive 167734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // subdirectories under Windows. 167834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project MyGlob(argv[argn], ProcessFile); 167934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #else 168034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Under linux, don't do any extra fancy globbing - shell globbing is 168134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // pretty fancy as it is - although not as good as myglob.c 168234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ProcessFile(argv[argn]); 168334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #endif 168434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 168534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (!FilesMatched){ 168634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project fprintf(stderr, "Error: No files matched '%s'\n",argv[argn]); 168734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 168834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 168934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 169034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (FileSequence == 0){ 169134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return EXIT_FAILURE; 169234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 169334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return EXIT_SUCCESS; 169434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 169534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 169634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif 169734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 169834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#endif // commented out -- security risk 169934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 1700