Skip to content

Instantly share code, notes, and snippets.

@ashwani-rathee
Created July 22, 2022 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ashwani-rathee/3f6b76ea6f9c85174ecd0794bfa8bf08 to your computer and use it in GitHub Desktop.
Save ashwani-rathee/3f6b76ea6f9c85174ecd0794bfa8bf08 to your computer and use it in GitHub Desktop.
Write EXIF data to any file
using Pkg
Pkg.activate(".")
include("./lib/LibExif.jl")
using .LibExif
using Images
using JpegTurbo
function init_tag(exif, ifd, tag)
exif1 = unsafe_load(exif)
entry = LibExif.exif_content_get_entry(exif1.ifd[1], tag)
if entry == C_NULL
entry = LibExif.exif_entry_new()
entry1 = unsafe_load(entry)
print(entry)
entry1.tag = tag;
LibExif.exif_content_add_entry(exif1.ifd[1], entry)
LibExif.exif_entry_initialize(entry, tag)
LibExif.exif_entry_unref(entry)
end
return entry
end
FILE_BYTE_ORDER = LibExif.EXIF_BYTE_ORDER_INTEL
image_jpg_x = 0x40
image_jpg_y = 0x40
# exif = LibExif.exif_data_new()
# LibExif.exif_data_set_option(exif, LibExif.EXIF_DATA_OPTION_FOLLOW_SPECIFICATION)
# LibExif.exif_data_set_data_type(exif, LibExif.EXIF_DATA_TYPE_COMPRESSED)
# LibExif.exif_data_set_byte_order(exif, LibExif.EXIF_BYTE_ORDER_INTEL)
# LibExif.exif_data_fix(exif)
# entry = init_tag(exif, LibExif.EXIF_IFD_EXIF, LibExif.EXIF_TAG_PIXEL_X_DIMENSION)
# entry1 = unsafe_load(entry)
# LibExif.exif_set_long(entry1.data, FILE_BYTE_ORDER, image_jpg_x)
# entry = init_tag(exif, LibExif.EXIF_IFD_EXIF, LibExif.EXIF_TAG_PIXEL_Y_DIMENSION)
# entry1 = unsafe_load(entry)
# LibExif.exif_set_long(entry1.data, FILE_BYTE_ORDER, image_jpg_y)
# entry = init_tag(exif, LibExif.EXIF_IFD_EXIF, LibExif.EXIF_TAG_COLOR_SPACE)
# entry1 = unsafe_load(entry)
# LibExif.exif_set_short(entry1.data, FILE_BYTE_ORDER, 1)
function test(exif1)
ifds = 1:5
numifds(ed) = 5
read_all = true
tags::Union{AbstractVector, Tuple} = Vector{LibExif.ExifTag}([])
ed = unsafe_load(exif1)
ifds = collect(ifds)
# ifds = read_all ? collect(1:numifds(ed)) : collect(ifds)
checkbounds(Bool, collect(1:numifds(ed)), ifds) || throw(BoundsError(collect(1:numifds(ed)), ifds))
result = Dict{String, Any}()
tags = read_all ? tags : Set(tags)
str = Vector{Cuchar}(undef, 1024)
for i in ifds
content_ptr = ed.ifd[i] # ques: do we need to unref these too?
if (content_ptr == C_NULL)
return error("Unable to read IFD:", i)
end
data = unsafe_load(content_ptr)
if data.count == 0 continue end
res = unsafe_wrap(Array, data.entries, data.count)
for i = 1:data.count
entry = unsafe_load(res[i])
condition = read_all ? read_all : entry.tag in tags
if condition
LibExif.exif_entry_get_value(Ref(entry), str, length(str))
tag = String(copy(str))[1:max(findfirst(iszero, str)-1, 1)]
if string(entry.tag) ∉ keys(result)
result[string(entry.tag)] = tag
end
end
if read_all == false
delete!(tags, entry.tag)
if tags == Set() break end
end
end
end
return result
end
exif1 = LibExif.exif_data_new_from_file("test/test_images/canon_makernote_variant_1.jpg")
exif = unsafe_load(exif1)
exif_header = Vector{Cuchar}(
[0xff, 0xd8, 0xff, 0xe1]
)
# exif_data = Vector{Cuchar}(undef, 1000)
exif_data = Ref{Ptr{Cuchar}}()
# exif_data = ["asdada", "Asdads"]
# ref_exif_data = pointer_from_objref(Ref(exif_data))
# ref_exif_data = pointer(exif_data)
exif_data_len = Cuint(length(exif_data))
ref_exif_data_len = Ref(exif_data_len)
img = Gray.(zeros(4, 3))
data = jpeg_encode(img)
# println(exif_data_len)
# println(ref_exif_data)
# println(ref_exif_data_len)
LibExif.exif_data_save_data(exif1, exif_data, ref_exif_data_len)
# println(test(exif1)) # this works
groups_vec = unsafe_wrap(Array, exif_data[], 5000)
len = findfirst([0xff,0xd8, 0xff, 0xd9], groups_vec)[4]
groups_vec = groups_vec[1:max(len, 1)]
open("sherlock-holmes2.jpg","w") do file
write(file, exif_header) # done
write(file, UInt8((len+2) >> 8))
write(file, UInt8((len+2) & 0xff))
write(file, groups_vec)
write(file, data[3:end])
end
@info "Tags read from written file" read_tags("sherlock-holmes2.jpg")
println("Decoded data")
@info "Data Decoded from written file" jpeg_decode("sherlock-holmes2.jpg")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment