since it was needed to answer a coding question, I worked a bit on JPG comment.
Here is the result:
Save it as JPGComment.pbi
Code: Select all
Procedure.q JPGComment_Search(Filename$)
Dim Buffer.a(1)
Result.q = 0
File = ReadFile(#PB_Any, Filename$)
If File
EOI = #False
Length.l = 0
FilePos.q = 0
Repeat
If ReadData(File, @Buffer(0), 2) = 2
FilePos + 2
If Buffer(0) = $FF
;Debug "Filepos: " + Hex(FilePos)
;Debug Hex(Buffer(1))
Select Buffer(1)
Case $D8 ; SOI
Case $D9 ; EOI
EOI = #True
Case $DA ; SOS
EOI = #True
Case $FE ; COM
Result = FilePos - 2
EOI = #True
Default
If ReadData(File, @Buffer(0), 2) = 2
Length = Buffer(0) << 8 | Buffer(1)
FilePos + Length
FileSeek(File, FilePos)
EndIf
EndSelect
EndIf
EndIf
If Eof(File)
EOI = #True
EndIf
Until EOI
CloseFile(File)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s JPGComment_Read(Filename$)
Result$ = ""
CommentPos.q = JPGComment_Search(Filename$)
If CommentPos
File = ReadFile(#PB_Any, Filename$)
If File
If FileSeek(File, CommentPos + 4)
Result$ = ReadString(File)
EndIf
CloseFile(File)
EndIf
EndIf
ProcedureReturn Result$
EndProcedure
Procedure JPGComment_Write(Filename$, Comment$)
Result = #False
File = ReadFile(#PB_Any, Filename$)
If File
Size = Lof(File)
*Buffer = AllocateMemory(Size)
If *Buffer
If ReadData(File, *Buffer, Size) = Size
CloseFile(File)
If PeekU(*Buffer) = $D8FF
; to be a bit more conform
InsertPos = 2
If PeekU(*Buffer + 2) = $E0FF ; APP0
If PeekU(*Buffer + 6) = $464A ; "JF"
InsertPos = 4 + ((PeekA(*Buffer + 4) << 8) + PeekA(*Buffer + 5))
EndIf
EndIf
File = CreateFile(#PB_Any, Filename$ + ".tmp")
If File
WriteData(File, *Buffer, InsertPos)
WriteByte(File, $FF)
WriteByte(File, $FE)
CommentLength = Len(Comment$) + 2 + 1
WriteByte(File, CommentLength >> 8)
WriteByte(File, CommentLength & $FF)
WriteString(File, Comment$, #PB_Ascii)
WriteByte(File, $00)
WriteData(File, *Buffer + InsertPos, Size - InsertPos)
CloseFile(File)
If DeleteFile(Filename$)
If RenameFile(Filename$ + ".tmp", Filename$)
Result = #True
EndIf
EndIf
EndIf
EndIf
EndIf
FreeMemory(*Buffer)
EndIf
If IsFile(File) : CloseFile(File) : EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure JPGComment_Replace(Filename$, Comment$)
Result = #False
CommentPos.q = JPGComment_Search(Filename$)
If CommentPos
File = ReadFile(#PB_Any, Filename$)
If File
Size = Lof(File)
*Buffer = AllocateMemory(Size)
If *Buffer
If ReadData(File, *Buffer, Size) = Size
CloseFile(File)
File = CreateFile(#PB_Any, Filename$ + ".tmp")
If File
WriteData(File, *Buffer, CommentPos)
If Len(Comment$)
WriteByte(File, $FF)
WriteByte(File, $FE)
NewCommentLength = Len(Comment$) + 2 + 1
WriteByte(File, NewCommentLength >> 8)
WriteByte(File, NewCommentLength & $FF)
WriteString(File, Comment$, #PB_Ascii)
WriteByte(File, $00)
EndIf
CommentLength = Len(PeekS(*Buffer + CommentPos + 4))
WriteData(File, *Buffer + CommentPos + 4 + CommentLength + 1, Size - CommentPos - 4 - CommentLength - 1)
CloseFile(File)
If DeleteFile(Filename$)
If RenameFile(Filename$ + ".tmp", Filename$)
Result = #True
EndIf
EndIf
EndIf
EndIf
FreeMemory(*Buffer)
EndIf
If IsFile(File) : CloseFile(File) : EndIf
EndIf
Else ; no comment in jpg
If Len(Comment$) ; a valid comment
If JPGComment_Write(Filename$, Comment$) : Result = #True : EndIf
Else ; no comment
Result = #True
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure JPGComment_Delete(Filename$)
Result = JPGComment_Replace(Filename$, "")
ProcedureReturn Result
EndProcedure
;JPGComment_Filename$ = "c:\tmp\1.jpg"
;Debug Hex(JPGComment_Search(JPGComment_Filename$))
;Debug JPGComment_Read(JPGComment_Filename$)
;Debug JPGComment_Write(JPGComment_Filename$, "Write")
;Debug JPGComment_Read(JPGComment_Filename$)
;Debug JPGComment_Replace(JPGComment_Filename$, "Replace")
;Debug JPGComment_Read(JPGComment_Filename$)
;Debug JPGComment_Delete(JPGComment_Filename$)
;Debug JPGComment_Read(JPGComment_Filename$)
Save it as JPGCommenter.pb
Code: Select all
IncludeFile "JPGComment.pbi"
Procedure AddComment(Directory$, Comment$)
If ExamineDirectory(0, Directory$, "*.jpg")
While NextDirectoryEntry(0)
FileName$ = Directory$ + DirectoryEntryName(0)
StatusBarText(0, 0, Filename$)
JPGComment_Replace(Filename$, Comment$)
Wend
EndIf
EndProcedure
OpenWindow(0, 0, 0, 500, 150, "JPG Commenter V1.10", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(0, 10, 10, 50, 20, "Comment:")
StringGadget(1, 70, 10, 350, 20, "")
TextGadget(2, 10, 40, 50, 20, "Directory:")
TextGadget(3, 70, 40, 350, 20, "", #PB_Text_Border)
ButtonGadget(4, 440, 40, 50, 20, "...")
ButtonGadget(5, 200, 80, 100, 30, "Start")
DisableGadget(5, #True)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(500)
Exit = #False
Directory$ = ""
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 4
Directory$ = PathRequester("Choose a directory", Directory$)
If Len(Directory$)
SetGadgetText(3, Directory$)
DisableGadget(5, #False)
Else
SetGadgetText(3, "")
DisableGadget(5, #True)
EndIf
Case 5
DisableGadget(5, #True)
AddComment(Directory$, GetGadgetText(1))
DisableGadget(5, #False)
EndSelect
Case #PB_Event_CloseWindow
Exit = #True
EndSelect
Until Exit
Have fun

Bernd