' RENPHOT(4.0) Rename Digital Photo Image JPG Files 01/18/1999-10/25/2004 ' -------------------------------------------------------------------------- ' Copyright (C) 1999-2004 by Vladimir Veytsel www.davar.net ' Type --------------------------------------------------------------------- ' Procedure ' Description -------------------------------------------------------------- ' Program generates unique names for image files recorded by a digital ' camera basing on date-time stamps contained within files. Generated ' file names are unique only within the given year - it's not much of a ' trouble to separate files between years, while this limitation permits ' to maintain the most universal 8.3 naming standard. Ideally a digital ' camera itself should do this job, but file naming seems to be of a ' little concern for camera designers. ' Program reads all not entirely digitally named *.JPG files within the ' CURRENT directory and renames those that have recorded date and time ' stamp (non-zero). Recorded date and time can be adjusted by a fixed ' value to handle the situation when pictures were taken in a time zone ' different from one where camera clock was set, or to correct error of ' the camera clock. Along with file renaming program appends records ' to the DESCRIPT.ION file providing initial description approximations ' (with optional global comment) that can be adjusted manually later. ' Parameters (Up to 7 Positional Self-Delimited) --------------------------- ' 1. Global description comment to be added to every description line ' (might be handy as an event or place identification that can be ' later individually adjusted as necessary for selected images). ' 2. Date-time stamp delimiter recorded by the camera (Default: ":"). ' 3. Number of date-time stamp entry to select (Default: 2). Camera ' usually writes several dates (Olympus writes 3, for example) and ' certain investigation and trial might be required to determine what ' date-time stamp is the most reliable (for Olympus D400 it happens ' to be the 2-nd date). ' 4. Name of the last file from the previous memory cartridge in the form ' of an eight-digit number "MODAHRUT" (Default or invalid: none). ' This parameter might prove handy for downloading and renaming images ' from several successive memory cartridges in case of a high frequency ' of shots made at the end of one cartridge that results in the ' incremental shift of file name numbers, so that this shift carries ' over into the next cartridge. This might happen because it's ' necessary to download separate cartridges into separate directories ' - camera provides unique names only within its current cartridge. ' There's always a choice, of course, not to use this parameter, but ' to do necessary image file name adjustments manually when merging ' individual cartridge directories together. ' 5. Date translation pattern (Default: "MO/DA/CNYE") ' Date is recorded by the camera as "CNYE:MO:DA" (":" stands here ' for the camera-recorded date-time stamp delimiter), where: ' CN - Current century ' YE - Year of current century ' MO - Month of current year ' DA - Day of current month ' Pattern for the date to be written to the corresponding line of ' DESCRIPT.ION file can be composed of above listed date fields ' and any delimiters different from DAMOYECN characters, e.g.: ' MO/DA/CNYE or MO/DA/YE ' DA.MO.CNYE or DA.MO.YE ' CNYE-MO-DA or YE-MO-DA, etc. ' 6. Time translation pattern (Default: "HR:UT") ' Time is recorded by the camera as "HR:UT:SZ" (":" stands here ' for the camera-recorded date-time stamp delimiter), where: ' HR - Hour of current day ' UT - Minute of current hour ' SZ - Second of current minute ' Pattern for the time to be written to the corresponding line of ' DESCRIPT.ION file can be composed of above listed time fields ' and any delimiters different from HRUTSZ characters, e.g.: ' HR:UT:SZ or HR:UT ' HR.UT.SZ or HR.UT ' HR-UT/SZ or HR-UT, etc. ' 7. Time adjustment increment/decrement (Default: none), e.g.: ' +08:00 or -02:30 - Should have fixed sHR:UT format, when specified. ' HR<=12 and UT<=59 - Invalid parameter (format or value) is ignored. ' Time adjustment comes handy in case you've been travelling, and taking ' pictures in another time zone, but didn't adjust the camera clock ' (who does?). This might be a minor annoyance, but why not to fix it ' in the same run with image files' renaming? ' It's sufficient, of course, to have only hours for time zone adjustment; ' minutes are added just in case it would be desirable to correct an error ' of the camera clock. ' Be careful with the sign setting; you've got to have it "+", if ' pictures were taken East of the location where camera clock was set ' (things happen "earlier" there), and "-", if pictures were taken West. ' Note: In order to permit any symbols within global description comment, ' and to accommodate for any possible recorded date-time stamp ' delimiter, and any delimiters within date and time patterns, ' parameter string is treated as being self-delimited, i.e. its ' FIRST symbol is used as the delimiter of individual parameters. ' It is up to the user to specify delimiter with the parameters ' and to choose it carefully to avoid parameter misinterpretation. ' RENPHOT - All parameters defaulted ' RENPHOT _Comment, etc. - Symbol "_" is the delimiter ' RENPHOT /Comment, etc./: - Symbol "/" is the delimiter ' RENPHOT \Comment, etc.\:\1 - Symbol "\" is the delimiter ' RENPHOT |Comment, etc.|:|3|04121443 - Symbol "|" is the delimiter ' Action ------------------------------------------------------------------- ' - Reads date and time stamp from every *.JPG file in the CURRENT directory ' in the form of CNYE:MO:DA HR:UT:SZ (":" is assumed to be date delimiter). ' - Renames each file into MODAHRUT.JPG using data from date and time stamp. ' +>+>+>+> ' | | | v ' | | v Minute (can be incremented over 59 to 99) ' | v Hour (can be incremented over 23, if required) ' v Day ' Month ' - In case such name already exists, name is incremented by "+1" until ' proper vacant name slot is found (the ACTUAL time is placed in the ' description record). Such incrementing might move the minute field ' over 59 to 99 and under very rare circumstances hour field over 23. ' (It's not a big deal to keep file name always as a proper date, but ' it might tend to propagate the shift beyond month and even beyond year, ' which doesn't make any sense.) ' - Image description record is appended to DESCRIPT.ION file for future ' use as ACDSee and 4DOS description line. Description record has the ' following format (includes WeeK Day identification): ' MODAHRUT.JPG WKD MO/DA/CNYE HR:UT [<global_description_comment>] ' Note: Date and time are translated according to the default pattern ' in the above example. Alternative translation patterns can be ' specified. ' Notes -------------------------------------------------------------------- ' - Program is designed to operate within CURRENT directory. ' - Important presumption is that file names written by the camera are not ' entirely digital (E.g.: they start with "P" for Olympus). ' - If file name is entirely digital (except for ".JPG" extension) no ' action is taken for such file. This ensures that partially processed ' directories can be entirely reprocessed safely to rename only what is ' required. ' - Program relies on the metadata with the date-time stamp that gets ' written at the beginning of the *.JPG image file by a digital camera. ' If date and time stamp is not found or it is all zeros, no action is ' taken for such file (camera should be set to write date and time to ' image file). To check the presence of metadata and date-time stamp ' view *.JPG file as text. ' - Renaming of image files should be done right after unloading them from ' the camera to the computer. If you plan to use RENPHOT, it should be ' the very FIRST processing step. Image processing programs such as ' ACDSee or PhotoShop remove camera-recorded metadata (they give warning, ' however), and date-time stamp gets lost, making operation of RENPHOT ' impossible (running it anyway won't spoil anything - files simply won't ' be renamed). ' - Beginning of the date-time stamp is identified by the program as four ' successive digits starting with "19" or "20" followed by the date ' delimiter, E.g.: "19yy:" or "20yy:". ' - Program looks for date-time stamp only within first 1000 symbols of ' *.JPG file. If the number of date-time entry specified by the 3-rd ' parameter is not found, file is not renamed. ' External SubProgram Library ---------------------------------------------- $LINK "MODULE.PBL" ' External Function -------------------------------------------------------- DECLARE FUNCTION DAY2GRE$(Day.Numb&) DECLARE FUNCTION DIGITAL%(Strng$,Delim$) DECLARE FUNCTION GRE2DAY&(Greg.Date$) DECLARE FUNCTION PARSE% (Strng$,SubStr$(),Delim$) DECLARE FUNCTION TRANS$ (Strng$,Source$,Target$) DECLARE FUNCTION WEEKDAY$(Spec.Date$) ' Start Procedure ---------------------------------------------------------- DEFINT A-Z ' All defaulted variables are integer OPTION BASE 1 ' Default array indexation starts from "1" ' Constant ----------------------------------------------------------------- Q$=CHR$(34) ' Quotation mark ' Working Variable --------------------------------------------------------- DIM Parameter$(7) ' Get Control Parameters --------------------------------------------------- Parm$=COMMAND$ ' Parm$="" ' Parm$="_Comment 1, etc." ' Parm$="/Comment 2, etc./:" ' Parm$="\Comment 3, etc.\:\1" ' Parm$="|Comment 4, etc.|:|3|04121443" ' Parm$="+Comment 5, etc.+:+3+04121443+CNYE-MO-DA" ' Parm$="-Comment 6, etc.-:-3-04121443-DA.MO.CNYE-HR.UT.SZ" ' Parm$="*Comment 7, etc.*:*3*04121443" ' Parm$="/Comment 8, etc.//////+10:10" ' Parm$="/Comment 9, etc.//////-01:01" I=PARSE%(Parm$,Parameter$(),"*") ' Form Parameters' Actual Values ------------------------------------------- Descr$ =Parameter$(1) Delim$ =Parameter$(2) Entry=VAL(Parameter$(3)) Prev$ =Parameter$(4) Date.Pat$=Parameter$(5) Time.Pat$=Parameter$(6) Time.Adj$=Parameter$(7) ' Display Renaming Log Title ----------------------------------------------- PRINT "RENPHOT(4.0) Rename Digital Photo Image JPG Files ";DATE$; PRINT " ";LEFT$(TIME$, 5) PRINT STRING$(69,"-") ' Adjust Control Parameters ------------------------------------------------ IF (Delim$="") THEN Delim$=":" :Delim$=LEFT$(Delim$,1) IF (Entry =0 ) THEN Entry =2 IF (Date.Pat$="") THEN Date.Pat$="MO/DA/CNYE" IF (Time.Pat$="") THEN Time.Pat$="HR:UT" IF ((LEN(Prev$)<>8)OR _ (NOT(DIGITAL(Prev$,"")))) THEN Prev$="" END IF Rec.Dt.Tm.Pat$="CNYE"+Delim$+"MO"+Delim$+"DA HR"+Delim$+"UT"+Delim$+"SZ" IF (LEN(Time.Adj$)>0) THEN Sign.Adj$=LEFT$(Time.Adj$,1) IF ((LEN(Time.Adj$)=6) AND _ ' ----+- (VERIFY(Sign.Adj$,"-+")=0)AND _ ' +12:34 (MID$(Time.Adj$,4,1)=":") AND _ (DIGITAL(MID$(Time.Adj$,2,2)+RIGHT$(Time.Adj$,2),""))) THEN Hours.Adj =VAL( MID$(Time.Adj$,2,2)) Minutes.Adj=VAL(RIGHT$(Time.Adj$,2)) IF ((Hours.Adj<=12)AND _ (Minutes.Adj<=59)) THEN Minutes.Incr=Hours.Adj*60+Minutes.Adj IF (Sign.Adj$="-") THEN Minutes.Incr=Minutes.Incr*(-1) END IF PRINT "Note: Time of each picture will be adjusted by the value of ";Q$;Time.Adj$;Q$ ELSE PRINT "Invalid time adjustment parameter value[s]: ";Q$;Time.Adj$;Q$;" - Ignored" END IF ELSE PRINT "Invalid time adjustment parameter format: ";Q$;Time.Adj$;Q$;" - Ignored" END IF END IF ' Open Directory Description File ------------------------------------------ OPEN "DESCRIPT.ION" FOR APPEND AS #1 ' Process All Files in Current Directory (Having Non-Digital Name) --------- ON ERROR RESUME NEXT ' Bypass system action on file renaming error File.Name$=DIR$("*.JPG") ' Get first file name DO UNTIL (File.Name$="") IF (NOT(DIGITAL(LEFT$(File.Name$,8),""))) THEN GOSUB Process.File END IF File.Name$=DIR$ ' Get next file name LOOP ' Finish Program ----------------------------------------------------------- PRINT "********" CLOSE END Process.File: ' Routine --------------------------------------------------- GOSUB Get.Date.Time IF ((LEN(Date.Time$)>0)AND _ ' File contains date and time stamp (DIGITAL(Date.Time$," "+Delim$))) THEN GOSUB Form.New.Name IF ((New.Name$<>"00000000")AND _ (File.Name$<>New.Name$+".JPG")) THEN GOSUB Rename.File GOSUB Append.Descr END IF END IF RETURN ' From Process.File routine Get.Date.Time: ' Routine -------------------------------------------------- OPEN File.Name$ FOR BINARY AS #2 I&=1 FOR J=1 TO Entry Year$="****" FOR I&=I& TO 1000 ' Find the nearest date delimiter GET$ #2,1,Symb$ ' which follows 4 digits (19yy or 20yy) Year$=RIGHT$(Year$+Symb$,5) IF ((Symb$=Delim$) AND _ (DIGITAL(Year$,Delim$))AND _ (( LEFT$(Year$,2)="19")OR _ ( LEFT$(Year$,2)="20"))) THEN EXIT END IF NEXT I& IF (J<>Entry) THEN I&=I&+15 SEEK #2,I& ' Skip date and time stamp END IF NEXT J SEEK #2,I&-4+(Entry=1) GET$ #2,19,Date.Time$ CLOSE #2 ' ----+----1----+---- Time adjustment is below ' 2002:04:21 10:10:36 Date.Time$ format example File.Date.Time$=Date.Time$ ' Save for displaying in renaming log IF (Minutes.Incr<>0) THEN Minutes.Abs&=GRE2DAY&(MID$(Date.Time$, 6,5)+":" + _ LEFT$(Date.Time$, 4))*24*60+ _ VAL(MID$(Date.Time$,12,2)) *60+ _ VAL(MID$(Date.Time$,15,2)) Minutes.Abs&=Minutes.Abs&+Minutes.Incr Hours.Abs&=INT(Minutes.Abs&/60) MID$(Date.Time$,15,2)=RIGHT$("0"+LTRIM$(STR$(Minutes.Abs& MOD 60)),2) Days.Abs&=INT(Hours.Abs&/24) MID$(Date.Time$,12,2)=RIGHT$("0"+LTRIM$(STR$(Hours.Abs& MOD 24)),2) Adjusted.Date$=DAY2GRE$(Days.Abs&) MID$(Date.Time$,1,10)=RIGHT$(Adjusted.Date$,4)+":"+LEFT$(Adjusted.Date$,5) MID$(Date.Time$,8,1)=":" ' Adjust delimiter END IF RETURN ' From Get.Date.Time routine Form.New.Name: ' Routine -------------------------------------------------- New.Name$=TRANS$("MODAHRUT",Rec.Dt.Tm.Pat$,Date.Time$) IF (New.Name$=Prev$) THEN ' Increment name number to avoid duplicate New.Name$=RIGHT$("0"+LTRIM$(STR$(VAL(New.Name$)+1)),8) END IF RETURN ' From Form.New.Name routine Rename.File: ' Routine ---------------------------------------------------- Renamed=0 DO UNTIL (Renamed) NAME File.Name$ AS New.Name$+".JPG" IF (ERRTEST=58) THEN ' New.Name$ already exists New.Name$=RIGHT$("0"+LTRIM$(STR$(VAL(New.Name$)+1)),8) ELSE PRINT File.Name$;" --> ";New.Name$;".JPG ";File.Date.Time$ Renamed=-1 END IF LOOP RETURN ' From Rename.File routine Append.Descr: ' Routine --------------------------------------------------- PRINT #1,New.Name$;".JPG " ; _ WEEKDAY(TRANS$("MO-DA-YE",Rec.Dt.Tm.Pat$,Date.Time$));" "; _ TRANS$(Date.Pat$ ,Rec.Dt.Tm.Pat$,Date.Time$) ;" "; _ TRANS$(Time.Pat$ ,Rec.Dt.Tm.Pat$,Date.Time$);" "; _ Descr$ RETURN ' From Append.Descr routine