Page 1 of 1

Photo Exif date sync file date

Posted: Wed Sep 28, 2011 8:26 am
by oryaaaaa
Simple software, then post tips. "Exif Sync"

File modify date set by Photo image Exif date.

Code: Select all

Enumeration
  #Window_Sync
  #ProgressBar_Sync
  #Text_Sync
  #Statusbar
  #FileA
EndEnumeration

Structure FileMate
  Filename.s
  ModifyDate.s
EndStructure

Global NewList FileAll.FileMate()
Global *imageAdress = AllocateMemory(8192)

Procedure Open_Window_Sync()
  If OpenWindow(#Window_Sync, 274, 134, 602, 92, "EXIF SYNC",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateStatusBar(#Statusbar, WindowID(#Window_Sync))
      AddStatusBarField(602)
    EndIf
    
    If CreateGadgetList(WindowID(#Window_Sync))
      ProgressBarGadget(#ProgressBar_Sync, 0, 30, 600, 30, 0, 10, #PB_ProgressBar_Smooth)
      TextGadget(#Text_Sync, 2, 2, 596, 25, "")
      
    EndIf
  EndIf
EndProcedure

Procedure.w xchEndianW(e.w) 
  ProcedureReturn (e & $FF) << 8 + (e >> 8) & $FF 
EndProcedure 

Procedure xchEndianL(e.l) 
  ProcedureReturn (e & $FF) << 24 + (e & $FF00) << 8 + (e >> 8) & $FF00 + (e >> 24) & $FF 
EndProcedure 

Procedure.b GetCameraModel(Filenamepath.s) 
  StatusBarText(#Statusbar, 0, Filenamepath)
  ReadFile(#FileA,Filenamepath)
  ReadData(#FileA, *imageAdress, 8192)
  CloseFile(#FileA)
  
  Protected OffsetField.l = *imageAdress +3
  Protected Header.b, wordOrder.l, tifFormat.l, ifd1.l, nFields.l, currentTag.l, flg.b
  Protected fieldType.l, fieldLength.l, fieldValue.l, currentloc.l, cam$
  If PeekB(OffsetField) &$FF = $E1 
    Header = 12 
  Else 
    Header = 30 
  EndIf 
  OffsetField = *imageAdress + Header
  wordOrder = PeekW(OffsetField)
  OffsetField + 2
  If wordOrder = $4949 Or wordOrder = $4D4D 
    If wordOrder = $4949 
      tifFormat = PeekW(OffsetField)
    Else 
      tifFormat = xchEndianW(PeekW(OffsetField))
    EndIf 
    OffsetField + 2
    If tifFormat = $2A 
      If wordOrder = $4949 
        ifd1 = PeekL(OffsetField) 
      Else 
        ifd1 = xchEndianL(PeekL(OffsetField) )
      EndIf 
      OffsetField + 4
      OffsetField = *imageAdress + ifd1 + Header
      If wordOrder = $4949 
        nFields = PeekW(OffsetField) 
      Else 
        nFields = xchEndianW(PeekW(OffsetField)) 
      EndIf 
      OffsetField + 2
      For i = 1 To nFields
        If wordOrder = $4949 
          currentTag = PeekW(OffsetField) 
        Else 
          currentTag = xchEndianW(PeekW(OffsetField)) 
        EndIf 
        OffsetField + 2
        flg=#True
        Select currentTag 
          Case 306
            cam$ = "ModifyDate: "
          Default
            flg=#False
        EndSelect 
        If flg=#True
          If wordOrder = $4949 
            fieldType = PeekW(OffsetField) 
          Else 
            fieldType = xchEndianW(PeekW(OffsetField)) 
          EndIf 
          OffsetField + 2
          fieldLength = PeekL(OffsetField) 
          OffsetField + 4
          If fieldLength <= 4 
            currentloc = OffsetField
            ;            AddGadgetItem(#ListView, -1, PeekS(OffsetField,0, #PB_Ascii)) 
            OffsetField + 4 
          Else 
            currentloc = OffsetField
            If wordOrder = $4949 
              fieldValue = PeekL(OffsetField) 
            Else 
              fieldValue = xchEndianL(PeekL(OffsetField)) 
            EndIf 
            OffsetField = *imageAdress + fieldValue + Header
            Select cam$
              Case "ModifyDate: "
                FileAll()\ModifyDate =  PeekS(OffsetField, 255, #PB_Ascii)
                ProcedureReturn #True
            EndSelect 
            OffsetField = currentloc + 4 
          EndIf 
        Else 
          OffsetField +10 
        EndIf 
      Next 
    EndIf 
  EndIf
  If FileAll()\ModifyDate=""
    SetGadgetAttribute(#ProgressBar_Sync, #PB_ProgressBar_Maximum, ListSize(FileAll())-1) 
    DeleteElement(FileAll())
    ProcedureReturn #False
  EndIf
EndProcedure 

Procedure AnalyzeHDD_Photo(Path.s, Filename.s)
  Protected i.l,pFlg.l
  StatusBarText(#Statusbar, 0, Path)
  Protected dir.l = ExamineDirectory(#PB_Any, Path, "*.*")
  Protected File.s
  While NextDirectoryEntry(dir)
      Select DirectoryEntryType(dir)
        Case #PB_DirectoryEntry_Directory
          If Len(DirectoryEntryName(dir))>2
            AnalyzeHDD_Photo(Path+DirectoryEntryName(dir)+"\",Filename)  
          EndIf
        Case #PB_DirectoryEntry_File
          File.s = DirectoryEntryName(dir)
          If UCase(Right(File,4))=".JPG" And Left(File,1)<>"."
            AddElement(FileAll())
            FileAll()\Filename = Path+File 
          EndIf
      EndSelect
    Wend
    FinishDirectory(dir) 
EndProcedure

Procedure Main()
  Protected filepath.s, PhotoDate.l
  Open_Window_Sync()
  filepath = PathRequester("EXIF SYNC", "")
  If Len(filepath)>2
    SetGadgetText(#Text_Sync, "Searching photos include exif")
    While WindowEvent() : Wend
    AnalyzeHDD_Photo(filepath, "")
    SetGadgetAttribute(#ProgressBar_Sync, #PB_ProgressBar_Maximum, ListSize(FileAll()))
    ForEach FileAll()
      If GetCameraModel(FileAll()\Filename)
        PhotoDate = ParseDate("%yyyy.%mm.%dd %hh:%ii:%ss", FileAll()\ModifyDate)
        SetFileDate(FileAll()\Filename, #PB_Date_Created, PhotoDate)
        SetFileDate(FileAll()\Filename, #PB_Date_Accessed, PhotoDate)
        SetFileDate(FileAll()\Filename, #PB_Date_Modified, PhotoDate)
        SetGadgetState(#ProgressBar_Sync, ListIndex(FileAll())+1)
        SetGadgetText(#Text_Sync, "Current "+Str(ListIndex(FileAll())+1)+ " /  Total "+Str(ListSize(FileAll())))
        StatusBarText(#Statusbar, 0, FileAll()\Filename)
        While WindowEvent() = #PB_Event_CloseWindow :Delay(1): Wend 
      EndIf
    Next
    SetGadgetText(#Text_Sync, "Current "+Str(ListIndex(FileAll())+1)+ " /  Total "+Str(ListSize(FileAll())))
    MessageRequester("EXIF SYNC", "Finish", #MB_OK|#MB_ICONINFORMATION)
  Else
    MessageRequester("EXIF SYNC", "Don't search photos!", #MB_OK|#MB_ICONERROR)
  EndIf 
EndProcedure

Main()

FreeMemory(*imageAdress)

End

Re: Photo Exif date sync file date

Posted: Mon Oct 03, 2011 9:39 am
by oryaaaaa
Faster code 8)

fix and add this code.

Code: Select all

Structure FileMate
  Filename.s
  CreateDate.s
  ModifyDate.s
  Digitized.s
EndStructure

Global NewList FileAll.FileMate()

Procedure.b GetCameraModel2(Filenamepath.s) 
  StatusBarText(#Statusbar, 0, Filenamepath)
  ReadFile(#FileA,Filenamepath)
  ReadData(#FileA, *imageAdress, 8192)
  CloseFile(#FileA)
  
  Protected i.l, SelectType.b
  
  SelectType = 1
  For i=0 To 8192
    If PeekB(*imageAdress+i)=$3A
      If PeekB(*imageAdress+i+3)=$3A
        If PeekB(*imageAdress+i+9)=$3A
          If PeekB(*imageAdress+i+12)=$3A
            Select SelectType
              Case 1
                FileAll()\ModifyDate = PeekS(*imageAdress+i-4, 19)
                SelectType+1
              Case 2
                FileAll()\CreateDate = PeekS(*imageAdress+i-4, 19)
                SelectType+1
              Case 3
                FileAll()\Digitized = PeekS(*imageAdress+i-4, 19)
                Break
            EndSelect
          EndIf  
        EndIf 
      EndIf
    EndIf
  Next
  If FileAll()\ModifyDate=""
    SetGadgetAttribute(#ProgressBar_Sync, #PB_ProgressBar_Maximum, ListSize(FileAll())-1) 
    DeleteElement(FileAll())
    ProcedureReturn #False
  Else
    ProcedureReturn #True
  EndIf 
EndProcedure

Re: Photo Exif date sync file date

Posted: Mon Oct 03, 2011 10:12 am
by c4s
Might be faster but I would prefer your first code because - as far as I can see - it tries to actually parse the JPG/Exif data instead of simply looking for a magic number...

Re: Photo Exif date sync file date

Posted: Fri Sep 21, 2012 9:46 pm
by CONVERT
Thanks Oryaaaaa.

I used some part of your code to mix with an other code in
viewtopic.php?f=13&t=15592&p=391340&sid ... fb#p391340

to get the creation date of a jpg, direct from a Panasonic Lumix camera (byteOrder = $4949) or after a rotation by the Microsoft viewer (byteOrder = $4D4D).