Go to:  Davar site entry | Site contents | Site index | Personal Computer | PowerBASIC | Text bottom

RENPHOT  PowerBASIC  Procedure


This is the latest 16-bit publication of RENPHOT(5.0) developed in 2008.  Previous RENPHOT(4.0) provides same options with the exception of provisions for easy transition between 8.3 names ans LFNs.  This page presents only souce code (and *.EXE download) of RENPHOT(5.0); for debugging details check RENPHOT(4.0) description page — their essentials are basically the same for both versions.

Latest 32-bit publication of RENPHOT(7.1) provides different target files naming and partially different set of options.

RENPHOT procedure (external 16-bit program executable from DOS/Windows command session) generates unique names for image files recorded by a digital camera basing on date-time stamps contained within files.

Direct dependencies:

DAY2GRE$ Convert absolute day number into Gregorian date
DIGITAL% Check character string for digital value (predicate)
GRE2DAY& Convert Gregorian date into absolute day number
PARSE% Parse character string into substring array
TRANS$ Translate character string symbols
WEEKDAY$ Form day of a week abbreviated name

Indirect dependencies:

COMPRES$ Compress character string
LEAP% Check year for leap value (predicate)
VALDGRE% Check date for valid Gregorian value (predicate)

You can get more details about RENPHOT program origins, design and usage in the Download section.

 RENPHOT  Source  Program

      ' RENPHOT(5.0)  Rename Digital Photo Image JPG Files   01/18/1999-09/28/2008
      ' --------------------------------------------------------------------------
      ' Copyright (C) 1999-2008 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.

      '  - Version 5.0 was modified (2008) to write 3 auxiliary files in addition
      '    to renaming image files and writing DESCRIPT.ION file for the ACDSeee.
      '    First two files permit an easy transition from 8.3 names to LFNs,
      '    if LFNs are preferable to 8.3 image file names.
      '    (NB: Renaming batch is supposed to be run in the CURRENT directory).

      '    REN_LFN.BAT   - Batch file to rename each RENPHOT 8.3 renamed file into
      '                    Long File Name file (run it in Windows Prompt, not DOS).
      '                    Sample REN_LFN.BAT record:
      '                    REN 08081221.JPG 2008-08-08_12-21-13.JPG

      '    DESCRIPT.LFN  - DESCRIPT.ION for Long File Names
      '                    Delete original 8.3-based DESCRIPT.ION and rename LFN-based
      '                    DESCRIPT.LFN into DESCRIPT.ION for ACDSee accessibility.
      '                    Sample DESCRIPT.LFN record:
      '                    2008-08-08_12-21-13.JPG Fri 08/08/2008 12:21  Comment for LFN

      '    Third file is a model for LFN to 8.3 renaming batch for rather rare case
      '    of merging two image directories with close date-time stamps and multiple
      '    shots take within same minutes (multiple cameras taking shots during same
      '    period of time).

      '    Image directory merging involves the following steps:

      '    - Download images from each camera into a separate directory.
      '    - Leave original camera image names in the first directory as-is.
      '      E.g.: IMG_4251.JPG
      '    - Globally rename original camera image names in the second directory.
      '      E.g.: IMG_3768.JPG --> ABC_3768.JPG
      '      Use command "REN IMG*.* ABC*.*" with "ABC" as a new file name prefix.
      '    - Repeat previous step for each subsequent directory to be merged, choosing
      '      choosing a unique file name prefix for each source directory files.
      '    - Move files from all directories into the first one - to become merged dir
      '      (no naming conflicts could occur here due to differences in prefixes).
      '    - Run RENPHOT (without parameters) in the merged directory.
      '    - Run REN_LFN.BAT in the merged directory (in Windows Prompt, not DOS).
      '      Name conflicts (shots taken within the same second) are very unlikely;
      '      if some happen, names should be adjusted manually using any file manager,
      '      and corresponding changes should be made to LFN[s] in REN_8-3.BAT file.
      '    - Adjust merged REN_8-3.BAT file as described below.
      '    - Run REN_8-N.BAT in the merged directory (in Windows Prompt, not DOS).
      '    - Delete *.BAT and DESCRIPT.* files in the merged directory.
      '    - Run RENPHOT (with proper global comment and any other parameters that
      '      might be necessary) in the merged directory - resultant file names will
      '      reflect chronologically correct shooting sequence.

      '    NB: For proper sequencing of files in the merges directory it is essential
      '        that camera clocks are synchronized BEFORE collaborative shooting.  If
      '        this wasn't done in the due time, necessary time adjustments could be
      '        made using RENPHOT time adjustment parameter (see description above).
      '        In this it would be necessary to run RENPHOT (with time adjustment an
      '        commenting in each individual directory, and then proceed with manual
      '        merging of REN_8-N.BAT and DESCRIPT.ION files.

      '    REN_8-3.BAT   - Batch file model for renaming LFNs into properly ordered
      '                    not fully digital (processable by RENPHOT) 8.3 names.
      '                    (adjust it with text editor having good block manipulation
      '                    capabilities, and run it in Windows Prompt, not DOS).
      '                    Sample REN_LFN.BAT record:
      '                    REN 2008-08-08_12-21-13.JPG I0000050.JPG

      '    Adjustment of REN_8-3.BAT should be done as follows (QuickEdit or
      '    TextPad in block mode can handle this easily):

      '    - Cut 3-rd column (8.3 file name) and place it BELOW main text body.
      '    - Sort main text body by 2-nd column (LFN name - full date-time stamp).
      '    - Return 8.3 file name column starting at the top of main text body.
      '    - Remove empty lines at the end of the file.

      '    Note:  An answer to an obvious question "Why bother at all with all this?"
      '           Indeed, using a simple mechanism of switching from 8.3 file names
      '           to LFNs resolves the merging problem nicely just by eliminating it.

      '           I have several reasons to stick to the 8.3 naming model:

      '           The first reason is purely personal - a sheer bulk of accumulated
      '           and properly commented photo archive makes global move to LFNs a
      '           huge task - RENPHOT mechanism of global commenting can handle this
      '           OK, but individual (manual) comment adjustment would be hard to
      '           recover.  Whenever this is necessary there's an easy way to switch
      '           from 8.3 names LFNs (full LFNs) - see DSC2REN that handles the
      '           task basin only on DESCRIPT.ION file data.

      '           Another reason is objective - most of DVD/DIVX players that are
      '           quite handy for browsing through photos and slide shows on big
      '           TV screen still display only (as of 2008) 8.3 file names.  Thus
      '           having meaningful 8.3 file names is far more preferable for
      '           navigation than otherwise auto-truncated to 8.3 LFNs.

      '           And finally, in terms of maintaining photo archive as as I do it
      '           (chronologically with major separation of years), LFNs have indeed
      '           absolutely no advantage over 8.3 file names in combination with
      '           DESCRIPT.ION file that I like anyway for it's simplicity and
      '           convenience.  For some rare exceptions DSC2REN mentioned above
      '           stands nicely to the task.

      ' 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 (their early versions) could 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$=""
      '    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"
      '    Parm$="/Comment for LFN"


      ' Form Parameters' Actual Values -------------------------------------------

           Descr$   =Parameter$(1)
           Delim$   =Parameter$(2)
           Prev$    =Parameter$(4)

      ' Display Renaming Log Title -----------------------------------------------

           PRINT "RENPHOT(5.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
           END IF

           Rec.Dt.Tm.Pat$="CNYE"+Delim$+"MO"+Delim$+"DA HR"+Delim$+"UT"+Delim$+"SZ"

           IF (LEN(Time.Adj$)>0) THEN
              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))
                 IF ((Hours.Adj<=12)AND _
                     (Minutes.Adj<=59)) THEN
                    IF (Sign.Adj$="-") THEN
                    END IF
                    PRINT "Note: Time of each picture will be adjusted by the value of ";Q$;Time.Adj$;Q$
                    PRINT "Invalid time adjustment parameter value[s]: ";Q$;Time.Adj$;Q$;"  - Ignored"
                 END IF
                 PRINT "Invalid time adjustment parameter format: ";Q$;Time.Adj$;Q$;"  - Ignored"
              END IF
           END IF

      ' Open Directory Description File ------------------------------------------

           OPEN "REN_8-3.BAT"  FOR APPEND AS #5

      ' 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

      ' Finish Program -----------------------------------------------------------

           PRINT "********"

      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

           FOR J=1 TO Entry
               FOR I&=I& TO 1000    ' Find the nearest date delimiter
                   GET$ #2,1,Symb$  ' which follows 4 digits (19yy or 20yy)
                   IF ((Symb$=Delim$)         AND _
                       (DIGITAL(Year$,Delim$))AND _
                       (( LEFT$(Year$,2)="19")OR  _
                        ( LEFT$(Year$,2)="20"))) THEN
                   END IF
               NEXT I&
               IF (J<>Entry) THEN
                  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
           Long.File.Name$=TRANS$(TRANS$(File.Date.Time$,Delim$,"-")," ","_")

           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+ _


              MID$(Date.Time$,15,2)=RIGHT$("0"+LTRIM$(STR$(Minutes.Abs& MOD 60)),2)
      	MID$(Date.Time$,12,2)=RIGHT$("0"+LTRIM$(STR$(Hours.Abs& MOD 24)),2)
              MID$(Date.Time$,8,1)=":"  ' Adjust delimiter
           END IF

           RETURN  ' From Get.Date.Time routine

      Form.New.Name:  ' Routine --------------------------------------------------


           IF (New.Name$=Prev$) THEN  ' Increment name number to avoid duplicate
           END IF

           RETURN  ' From Form.New.Name routine

      Rename.File:  ' Routine ----------------------------------------------------

           DO UNTIL (Renamed)
              NAME File.Name$ AS New.Name$+".JPG"
              IF (ERRTEST=58) THEN  ' New.Name$ already exists
                 PRINT File.Name$;" --> ";New.Name$;".JPG  ";File.Date.Time$
                 PRINT #3,"REN ";New.Name$;".JPG ";Long.File.Name$;".JPG"
                 PRINT #5,"REN ";Long.File.Name$;".JPG I";File.Number$;"0.JPG"
              END IF

           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$);"  "; _

           PRINT #4,Long.File.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$);"  "; _

           RETURN  ' From Append.Descr routine

View [and save] RENPHOT.BAS text       Download RENPHOT.EXE file
(Use [Back] button or [Alt]+[CL] to return here from the viewed text)
To make RENPHOT.BAS source text compilable
change globally of "&lt;" into "<" signs and "&amp;" into "&" signs.
Copyright © 19992008 by
Go to:  Davar site entry | Site contents | Site index | Personal Computer | PowerBASIC | Text top