aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--julia/CrystFEL/src/image.jl39
-rw-r--r--julia/CrystFEL/src/peaklist.jl10
-rw-r--r--libcrystfel/src/image.c3
-rw-r--r--libcrystfel/src/image.h4
4 files changed, 32 insertions, 24 deletions
diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl
index 24c1c923..de79a556 100644
--- a/julia/CrystFEL/src/image.jl
+++ b/julia/CrystFEL/src/image.jl
@@ -36,6 +36,7 @@ mutable struct InternalImage
peak_resolution::Cdouble
peaklist::Ptr{InternalPeakList}
ida::Ptr{Cvoid}
+ owns_peaklist::Cint
end
@@ -63,11 +64,27 @@ function makecrystallist(listptr, n)
end
+function getpeaklist(image)
+ idata = unsafe_load(image.internalptr)
+ if (image.peaklist === nothing) || (idata.peaklist != image.peaklist.internalptr)
+ if idata.peaklist != C_NULL
+ image.peaklist = PeakList(idata.peaklist)
+ # From now on, Julia is completely responsible for freeing the peaklist
+ idata.owns_peaklist = 0
+ unsafe_store!(image.internalptr, idata)
+ else
+ image.peaklist = nothing
+ end
+ end
+ return image.peaklist
+end
+
+
function Base.getproperty(image::Image, name::Symbol)
if name === :internalptr
getfield(image, :internalptr)
elseif name === :peaklist
- getfield(image, :peaklist)
+ getpeaklist(image)
else
idata = unsafe_load(image.internalptr)
@@ -96,23 +113,13 @@ function set_peaklist(image, new_pl)
assert_type(new_pl, PeakList)
- if new_pl.in_image
- throw(ArgumentError("PeakList is already in an image. "*
- "Add a copy (use `deepcopy`) instead."))
- end
- new_pl.in_image = true
- old_pl = swapfield!(image, :peaklist, new_pl)
- if old_pl !== nothing
- old_pl.in_image = false
- # The old PeakList will now get GCed
- end
-
idata = unsafe_load(image.internalptr)
- old_i = swapfield!(idata, :peaklist, new_pl.internalptr)
- if old_pl === nothing || old_i == old_pl.internalptr
- unsafe_store!(image.internalptr, idata)
- # else someone else already set a new peaklist
+ if (idata.owns_peaklist == 0) && (idata.peaklist != C_NULL)
+ @ccall libcrystfel.image_feature_list_free(idata.peaklist::Ptr{InternalPeakList})::Cvoid
end
+ idata.peaklist = new_pl.internalptr
+ idata.owns_peaklist = 0
+ unsafe_store!(image.internalptr, idata)
end
diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl
index a676a7bf..d4354977 100644
--- a/julia/CrystFEL/src/peaklist.jl
+++ b/julia/CrystFEL/src/peaklist.jl
@@ -16,7 +16,6 @@ mutable struct InternalPeakList end
mutable struct PeakList
internalptr::Ptr{InternalPeakList}
- in_image # if true, this PeakList belongs to an Image struct
end
@@ -25,11 +24,8 @@ function PeakList()
if out == C_NULL
throw(ArgumentError("Failed to create peak list"))
end
- finalizer(PeakList(out, false)) do pl
- if !pl.in_image
- @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid
- # else it belongs to the image structure
- end
+ finalizer(PeakList(out)) do pl
+ @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid
end
end
@@ -39,7 +35,7 @@ function Base.deepcopy(peaklist::PeakList)
if out == C_NULL
throw(ErrorException("Failed to copy peak list"))
end
- PeakList(out, false)
+ PeakList(out)
end
function Base.length(peaklist::PeakList)
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c
index 3b4e04df..ab4518a9 100644
--- a/libcrystfel/src/image.c
+++ b/libcrystfel/src/image.c
@@ -1394,7 +1394,7 @@ void image_free(struct image *image)
int i, np;
if ( image == NULL ) return;
- image_feature_list_free(image->features);
+ if ( image->owns_peaklist ) image_feature_list_free(image->features);
free_all_crystals(image);
spectrum_free(image->spectrum);
cffree(image->filename);
@@ -1464,6 +1464,7 @@ struct image *image_new()
image->bw = -1.0;
image->peak_resolution = -1.0;
image->features = NULL;
+ image->owns_peaklist = 1;
return image;
}
diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h
index beb66810..74ff6eee 100644
--- a/libcrystfel/src/image.h
+++ b/libcrystfel/src/image.h
@@ -190,6 +190,10 @@ struct image
/** Re-usable data array structure, or NULL if not used */
ImageDataArrays *ida;
+ /** If set, then 'features' should be freed with the image.
+ * Otherwise, it is managed externally (e.g. by Julia) */
+ int owns_peaklist;
+
};
#ifdef __cplusplus