Enable static linking, libczi is now a submodule.
This commit is contained in:
54
.github/workflows/publish.yml
vendored
Normal file
54
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: Publish
|
||||||
|
|
||||||
|
on: [push, pull_request, workflow_call]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
crates_io_publish:
|
||||||
|
name: Publish (crates.io)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 25
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: cargo-release Cache
|
||||||
|
id: cargo_release_cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.cargo/bin/cargo-release
|
||||||
|
key: ${{ runner.os }}-cargo-release
|
||||||
|
|
||||||
|
- run: cargo install cargo-release
|
||||||
|
if: steps.cargo_release_cache.outputs.cache-hit != 'true'
|
||||||
|
|
||||||
|
- name: cargo login
|
||||||
|
run: cargo login ${{ secrets.CRATES_IO_API_TOKEN }}
|
||||||
|
|
||||||
|
# allow-branch HEAD is because GitHub actions switches
|
||||||
|
# to the tag while building, which is a detached head
|
||||||
|
|
||||||
|
# Publishing is currently messy, because:
|
||||||
|
#
|
||||||
|
# * `peace_rt_model_core` exports `NativeError` or `WebError` depending on the target.
|
||||||
|
# * `peace_rt_model_web` fails to build when publishing the workspace for a native target.
|
||||||
|
# * `peace_rt_model_web` still needs its dependencies to be published before it can be
|
||||||
|
# published.
|
||||||
|
# * `peace_rt_model_hack` needs `peace_rt_model_web` to be published before it can be
|
||||||
|
# published.
|
||||||
|
#
|
||||||
|
# We *could* pass through `--no-verify` so `cargo` doesn't build the crate before publishing,
|
||||||
|
# which is reasonable, since this job only runs after the Linux, Windows, and WASM builds
|
||||||
|
# have passed.
|
||||||
|
- name: "cargo release publish"
|
||||||
|
run: |-
|
||||||
|
cargo release \
|
||||||
|
publish \
|
||||||
|
--workspace \
|
||||||
|
--all-features \
|
||||||
|
--allow-branch "main" \
|
||||||
|
--no-confirm \
|
||||||
|
--no-verify \
|
||||||
|
--execute
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libczi"]
|
||||||
|
path = libczi
|
||||||
|
url = https://github.com/ZEISS/libczi.git
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libczirw-sys"
|
name = "libczirw-sys"
|
||||||
version = "0.1.2"
|
version = "0.2.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85.1"
|
rust-version = "1.85.1"
|
||||||
authors = ["Wim Pomp <w.pomp@nki.nl>"]
|
authors = ["Wim Pomp <w.pomp@nki.nl>"]
|
||||||
@@ -15,8 +15,13 @@ links = "libCZIAPI"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
|
link-cplusplus = "1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
|
bindgen = "0.72.0"
|
||||||
cmake = "0.1.54"
|
cmake = "0.1.54"
|
||||||
git2 = "0.20.2"
|
regex = "1.11.1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
dynamic = []
|
||||||
@@ -4,4 +4,6 @@ Crate linking to [libCZIAPI](https://github.com/ZEISS/libczi).
|
|||||||
This crate attempts to provide save wrappers to objects and functions in libCZIAPI.
|
This crate attempts to provide save wrappers to objects and functions in libCZIAPI.
|
||||||
Direct often unsafe access using pointer is available through the sys module.
|
Direct often unsafe access using pointer is available through the sys module.
|
||||||
|
|
||||||
This code is licensed with an MIT license, but Zeiss' libCZI has a LGPL license.
|
By default, libCZIAPI will be statically linked. The feature 'dynamic' will switch it to dynamic linking.
|
||||||
|
|
||||||
|
This code is licensed with an MIT license, but Zeiss' libCZI which is included as a submodule has a LGPL license.
|
||||||
209
build.rs
209
build.rs
@@ -1,90 +1,171 @@
|
|||||||
use anyhow::Result;
|
extern crate bindgen;
|
||||||
|
|
||||||
|
use anyhow::{Error, Result};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::OpenOptions;
|
|
||||||
use std::io::{Read, Seek, Write};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
use bindgen::callbacks::ItemInfo;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
if env::var("DOCS_RS").is_err() {
|
if env::var("DOCS_RS").is_err() {
|
||||||
let out_dir = PathBuf::from(env::var("OUT_DIR")?).canonicalize()?;
|
let out_dir = PathBuf::from(env::var("OUT_DIR")?).canonicalize()?;
|
||||||
let libczi_dir = out_dir.join("libczirw");
|
let libczi_dir = PathBuf::from("libczi");
|
||||||
let rep = if !libczi_dir.exists() {
|
let libczi_src = libczi_dir.join("Src/libCZI");
|
||||||
git2::Repository::clone("https://github.com/ZEISS/libczi.git", &libczi_dir)
|
let libcziapi_inc = libczi_dir.join("Src/libCZIAPI/inc");
|
||||||
.expect("unable to clone libczirw")
|
let libcziapi_src = libczi_dir.join("Src/libCZIAPI/src");
|
||||||
} else {
|
let libcziapi_h = libcziapi_inc.join("libCZIApi.h");
|
||||||
git2::Repository::open(&libczi_dir)?
|
|
||||||
};
|
|
||||||
let (object, _) = rep.revparse_ext("494ac62f853de6ab86458f167fd85a03ee6d4f7e")?;
|
|
||||||
rep.checkout_tree(&object, None)?;
|
|
||||||
|
|
||||||
let dst = cmake::Config::new(&libczi_dir)
|
let dst = cmake::Config::new(&libczi_dir)
|
||||||
|
.cxxflag("-fms-extensions")
|
||||||
.define("LIBCZI_BUILD_UNITTESTS", "OFF")
|
.define("LIBCZI_BUILD_UNITTESTS", "OFF")
|
||||||
.define("LIBCZI_BUILD_CZICMD", "OFF")
|
.define("LIBCZI_BUILD_CZICMD", "OFF")
|
||||||
.define("LIBCZI_BUILD_DYNLIB", "OFF")
|
.define("LIBCZI_BUILD_DYNLIB", "OFF")
|
||||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_EIGEN3", "OFF")
|
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_EIGEN3", "OFF")
|
||||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_ZSTD", "OFF")
|
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_ZSTD", "OFF")
|
||||||
.define("LIBCZI_BUILD_CURL_BASED_STREAM", "OFF")
|
.define("LIBCZI_BUILD_CURL_BASED_STREAM", "OFF")
|
||||||
.define("LIBCZI_BUILD_PREFER_EXTERNAL_PACKAGE_LIBCURL", "OFF")
|
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_LIBCURL", "OFF")
|
||||||
.define("LIBCZI_BUILD_AZURESDK_BASED_STREAM", "OFF")
|
.define("LIBCZI_BUILD_AZURESDK_BASED_STREAM", "OFF")
|
||||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_RAPIDJSON", "OFF")
|
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_RAPIDJSON", "OFF")
|
||||||
.define("LIBCZI_BUILD_LIBCZIAPI", "ON")
|
.define("LIBCZI_BUILD_LIBCZIAPI", "ON")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// let libcziapi_inc = libczi_dir.join("Src/libCZIAPI/inc");
|
#[cfg(not(feature = "dynamic"))]
|
||||||
// let libczi_src = libczi_dir.join("Src/libCZI");
|
let bindings = {
|
||||||
// let libcziapi_src = libczi_dir.join("Src/libCZIAPI/src");
|
let mut libcziapi_a = out_dir.join("build/Src/libCZIAPI/liblibCZIAPIStatic.a");
|
||||||
// let libczi_h = libcziapi_inc.join("libCZIApi.h");
|
if !libcziapi_a.exists() {
|
||||||
|
libcziapi_a = out_dir.join("build/Src/libCZIAPI/liblibCZIAPIStatic.lib");
|
||||||
let import_export = libczi_dir.join("Src/libCZIAPI/inc/importexport.h");
|
}
|
||||||
{
|
bindgen::Builder::default().parse_callbacks(Box::new(DeMangler::new(libcziapi_a)?))
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.open(&import_export)
|
|
||||||
.expect("Could not open file");
|
|
||||||
|
|
||||||
let mut data = String::new();
|
|
||||||
file.read_to_string(&mut data).expect("Could not read file");
|
|
||||||
let data = data.replace(" __declspec(dllexport)", "");
|
|
||||||
let bytes = data.as_bytes();
|
|
||||||
(&file).rewind().expect("Could not rewind");
|
|
||||||
(&file).write_all(bytes).expect("Could not write file");
|
|
||||||
file.set_len(bytes.len() as u64)
|
|
||||||
.expect("Could not truncate");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// let bindings = bindgen::Builder::default()
|
#[cfg(feature = "dynamic")]
|
||||||
// .clang_args([
|
let bindings = bindgen::Builder::default();
|
||||||
// "-x",
|
|
||||||
// "c++",
|
|
||||||
// "-std=c++14",
|
|
||||||
// "-I",
|
|
||||||
// libcziapi_inc
|
|
||||||
// .to_str()
|
|
||||||
// .ok_or(Error::msg("cannot into string"))?,
|
|
||||||
// "-I",
|
|
||||||
// libcziapi_src
|
|
||||||
// .to_str()
|
|
||||||
// .ok_or(Error::msg("cannot into string"))?,
|
|
||||||
// "-I",
|
|
||||||
// libczi_src
|
|
||||||
// .to_str()
|
|
||||||
// .ok_or(Error::msg("cannot into string"))?,
|
|
||||||
// ])
|
|
||||||
// .header(libczi_h.to_str().ok_or(Error::msg("cannot into string"))?)
|
|
||||||
// .generate()
|
|
||||||
// .expect("Unable to generate bindings");
|
|
||||||
//
|
|
||||||
// bindings
|
|
||||||
// .write_to_file(out_dir.join("lib_czi_api.rs"))
|
|
||||||
// .expect("Couldn't write bindings!");
|
|
||||||
|
|
||||||
println!(
|
let bindings = bindings
|
||||||
"cargo:rustc-link-search=native={}",
|
.merge_extern_blocks(true)
|
||||||
dst.join("build/Src/libCZIAPI").display()
|
.clang_args([
|
||||||
);
|
"-fms-extensions",
|
||||||
println!("cargo:rustc-link-lib=libCZIAPI");
|
"-x",
|
||||||
|
"c++",
|
||||||
|
"-std=c++14",
|
||||||
|
"-I",
|
||||||
|
libcziapi_inc
|
||||||
|
.to_str()
|
||||||
|
.ok_or(Error::msg("cannot into string"))?,
|
||||||
|
"-I",
|
||||||
|
libcziapi_src
|
||||||
|
.to_str()
|
||||||
|
.ok_or(Error::msg("cannot into string"))?,
|
||||||
|
"-I",
|
||||||
|
libczi_src
|
||||||
|
.to_str()
|
||||||
|
.ok_or(Error::msg("cannot into string"))?,
|
||||||
|
])
|
||||||
|
.header(
|
||||||
|
libcziapi_h
|
||||||
|
.to_str()
|
||||||
|
.ok_or(Error::msg("cannot into string"))?,
|
||||||
|
)
|
||||||
|
.generate()?;
|
||||||
|
|
||||||
|
bindings.write_to_file(out_dir.join("lib_czi_api.rs"))?;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
{
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-search=native={}",
|
||||||
|
dst.join("build/Src/libCZIAPI").display()
|
||||||
|
);
|
||||||
|
println!("cargo:rustc-link-lib=static=libCZIAPIStatic");
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-search=native={}",
|
||||||
|
dst.join("build/Src/libCZI").display()
|
||||||
|
);
|
||||||
|
let profile = env::var("PROFILE")?;
|
||||||
|
match profile.as_str() {
|
||||||
|
"debug" => println!("cargo:rustc-link-lib=static=libCZIStaticd"),
|
||||||
|
"release" => println!("cargo:rustc-link-lib=static=libCZIStatic"),
|
||||||
|
_ => return Err(Error::msg(format!("unsupported profile: {}", profile))),
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-search=native={}",
|
||||||
|
dst.join("lib").display()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-search=native={}",
|
||||||
|
dst.join("lib64").display()
|
||||||
|
);
|
||||||
|
println!("cargo:rustc-link-lib=static=zstd");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dynamic")]
|
||||||
|
{
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-search=native={}",
|
||||||
|
dst.join("build/Src/libCZIAPI").display()
|
||||||
|
);
|
||||||
|
println!("cargo:rustc-link-lib=libCZIAPI");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
println!("cargo::rerun-if-changed=build.rs");
|
println!("cargo::rerun-if-changed=build.rs");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct DeMangler {
|
||||||
|
map: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
impl DeMangler {
|
||||||
|
fn new(a_file: PathBuf) -> Result<Self> {
|
||||||
|
let cmd = std::process::Command::new("nm").arg(&a_file).output()?;
|
||||||
|
let pat = Regex::new(r"^[\da-f]*\s[A-Z]\s(.*_Z(\d+)(libCZI_.*))$")?;
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
for line in std::str::from_utf8(&cmd.stdout)?.lines() {
|
||||||
|
if let Some(caps) = pat.captures(line.trim()) {
|
||||||
|
if let (Some(symbol), Some(n), Some(name)) = (caps.get(1), caps.get(2), caps.get(3))
|
||||||
|
{
|
||||||
|
let n: usize = n.as_str().parse()?;
|
||||||
|
let name = name.as_str();
|
||||||
|
let demangled = name[..n].to_string();
|
||||||
|
let mangled = symbol.as_str().to_string();
|
||||||
|
if let Some(existing_mangled) = map.get(&demangled) {
|
||||||
|
if existing_mangled != &mangled {
|
||||||
|
return Err(Error::msg(format!(
|
||||||
|
"conflicting mangled symbols for {} in {}: {}, {}",
|
||||||
|
demangled,
|
||||||
|
a_file.to_str().unwrap(),
|
||||||
|
existing_mangled,
|
||||||
|
mangled
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
map.insert(demangled, mangled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Self { map })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "dynamic"))]
|
||||||
|
impl bindgen::callbacks::ParseCallbacks for DeMangler {
|
||||||
|
fn generated_link_name_override(&self, item_info: ItemInfo<'_>) -> Option<String> {
|
||||||
|
self.map.get(item_info.name).cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
1
libczi
Submodule
1
libczi
Submodule
Submodule libczi added at 494ac62f85
@@ -640,7 +640,13 @@ impl LockedBitmap {
|
|||||||
/// \\param \[out\] ptr Pointer to the memory location where the bitmap is to be copied to.
|
/// \\param \[out\] ptr Pointer to the memory location where the bitmap is to be copied to.
|
||||||
///
|
///
|
||||||
/// \\returns A LibCZIApiErrorCode.
|
/// \\returns A LibCZIApiErrorCode.
|
||||||
pub fn copy(&self, width: u32, height: u32, pixel_type: PixelType, stride: u32) -> Result<Bitmap> {
|
pub fn copy(
|
||||||
|
&self,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
pixel_type: PixelType,
|
||||||
|
stride: u32,
|
||||||
|
) -> Result<Bitmap> {
|
||||||
let mut data = MaybeUninit::<Self>::uninit();
|
let mut data = MaybeUninit::<Self>::uninit();
|
||||||
LibCZIApiError::try_from(unsafe {
|
LibCZIApiError::try_from(unsafe {
|
||||||
libCZI_BitmapCopyTo(
|
libCZI_BitmapCopyTo(
|
||||||
|
|||||||
@@ -3,60 +3,61 @@ use crate::sys::*;
|
|||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
|
||||||
/// CZI-reader object.
|
/// CZI-reader object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CziReader(pub (crate) CziReaderObjectHandle);
|
pub struct CziReader(pub(crate) CziReaderObjectHandle);
|
||||||
|
|
||||||
/// sub-block object.
|
/// sub-block object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SubBlock(pub (crate) SubBlockObjectHandle);
|
pub struct SubBlock(pub(crate) SubBlockObjectHandle);
|
||||||
|
|
||||||
/// input stream object.
|
/// input stream object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InputStream(pub (crate) InputStreamObjectHandle);
|
pub struct InputStream(pub(crate) InputStreamObjectHandle);
|
||||||
|
|
||||||
/// output stream object.
|
/// output stream object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct OutputStream(pub (crate) OutputStreamObjectHandle);
|
pub struct OutputStream(pub(crate) OutputStreamObjectHandle);
|
||||||
|
|
||||||
/// memory allocation object - which is a pointer to a memory block, which must be
|
/// memory allocation object - which is a pointer to a memory block, which must be
|
||||||
/// freed with 'libCZI_Free'.
|
/// freed with 'libCZI_Free'.
|
||||||
/// TODO(JBL): this is not really used so far, should be removed I guess.
|
/// TODO(JBL): this is not really used so far, should be removed I guess.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MemoryAllocation(pub (crate) MemoryAllocationObjectHandle);
|
pub struct MemoryAllocation(pub(crate) MemoryAllocationObjectHandle);
|
||||||
|
|
||||||
/// bitmap object.
|
/// bitmap object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Bitmap(pub (crate) BitmapObjectHandle);
|
pub struct Bitmap(pub(crate) BitmapObjectHandle);
|
||||||
|
|
||||||
/// metadata segment object.
|
/// metadata segment object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MetadataSegment(pub (crate) MetadataSegmentObjectHandle);
|
pub struct MetadataSegment(pub(crate) MetadataSegmentObjectHandle);
|
||||||
|
|
||||||
/// attachment object.
|
/// attachment object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Attachment(pub (crate) AttachmentObjectHandle);
|
pub struct Attachment(pub(crate) AttachmentObjectHandle);
|
||||||
|
|
||||||
/// writer object.
|
/// writer object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CziWriter(pub (crate) CziWriterObjectHandle);
|
pub struct CziWriter(pub(crate) CziWriterObjectHandle);
|
||||||
|
|
||||||
/// single-channel-scaling-tile-accessor.
|
/// single-channel-scaling-tile-accessor.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SingleChannelScalingTileAccessor(pub (crate) SingleChannelScalingTileAccessorObjectHandle);
|
pub struct SingleChannelScalingTileAccessor(
|
||||||
|
pub(crate) SingleChannelScalingTileAccessorObjectHandle,
|
||||||
|
);
|
||||||
|
|
||||||
/// document info object.
|
/// document info object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CziDocumentInfo(pub (crate) CziDocumentInfoHandle);
|
pub struct CziDocumentInfo(pub(crate) CziDocumentInfoHandle);
|
||||||
|
|
||||||
/// display settings object.
|
/// display settings object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisplaySettings(pub (crate) DisplaySettingsHandle);
|
pub struct DisplaySettings(pub(crate) DisplaySettingsHandle);
|
||||||
|
|
||||||
/// channel display settings object.
|
/// channel display settings object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ChannelDisplaySettings(pub (crate) ChannelDisplaySettingsHandle);
|
pub struct ChannelDisplaySettings(pub(crate) ChannelDisplaySettingsHandle);
|
||||||
|
|
||||||
macro_rules! impl_struct {
|
macro_rules! impl_struct {
|
||||||
($($n:ident: $t:ty: $s:ty $(,)?)*) => {
|
($($n:ident: $t:ty: $s:ty $(,)?)*) => {
|
||||||
|
|||||||
163
src/interop.rs
163
src/interop.rs
@@ -8,45 +8,45 @@ use std::mem::{ManuallyDrop, MaybeUninit};
|
|||||||
/// This struct contains the version information of the libCZIApi-library. For versioning libCZI, SemVer2 (<https://semver.org/>) is used.
|
/// This struct contains the version information of the libCZIApi-library. For versioning libCZI, SemVer2 (<https://semver.org/>) is used.
|
||||||
/// Note that the value of the tweak version number does not have a meaning (as far as SemVer2 is concerned).
|
/// Note that the value of the tweak version number does not have a meaning (as far as SemVer2 is concerned).
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LibCZIVersionInfo(pub (crate) LibCZIVersionInfoInterop);
|
pub struct LibCZIVersionInfo(pub(crate) LibCZIVersionInfoInterop);
|
||||||
|
|
||||||
/// This struct gives information about the build of the libCZIApi-library.
|
/// This struct gives information about the build of the libCZIApi-library.
|
||||||
/// Note that all strings must be freed by the caller (using libCZI_Free).
|
/// Note that all strings must be freed by the caller (using libCZI_Free).
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LibCZIBuildInformation(pub (crate) LibCZIBuildInformationInterop);
|
pub struct LibCZIBuildInformation(pub(crate) LibCZIBuildInformationInterop);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InputStreamClassInfo(pub (crate) InputStreamClassInfoInterop);
|
pub struct InputStreamClassInfo(pub(crate) InputStreamClassInfoInterop);
|
||||||
|
|
||||||
/// This structure gives additional information about an error that occurred in the external stream.
|
/// This structure gives additional information about an error that occurred in the external stream.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ExternalStreamErrorInfo(pub (crate) ExternalStreamErrorInfoInterop);
|
pub struct ExternalStreamErrorInfo(pub(crate) ExternalStreamErrorInfoInterop);
|
||||||
|
|
||||||
/// This structure contains information about externally provided functions for reading data from an input stream,
|
/// This structure contains information about externally provided functions for reading data from an input stream,
|
||||||
/// and it is used to construct a stream-object to be used with libCZI.
|
/// and it is used to construct a stream-object to be used with libCZI.
|
||||||
/// Note on lifetime: The function pointers must remain valid until the function 'close_function' is called. The lifetime
|
/// Note on lifetime: The function pointers must remain valid until the function 'close_function' is called. The lifetime
|
||||||
/// may extend beyond calling the 'libCZI_ReleaseInputStream' function for the corresponding stream-object.
|
/// may extend beyond calling the 'libCZI_ReleaseInputStream' function for the corresponding stream-object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ExternalInputStreamStruct(pub (crate) ExternalInputStreamStructInterop);
|
pub struct ExternalInputStreamStruct(pub(crate) ExternalInputStreamStructInterop);
|
||||||
|
|
||||||
/// This structure contains information about externally provided functions for writing data to an output stream,
|
/// This structure contains information about externally provided functions for writing data to an output stream,
|
||||||
/// and it is used to construct a stream-object to be used with libCZI.
|
/// and it is used to construct a stream-object to be used with libCZI.
|
||||||
/// Note on lifetime: The function pointers must remain valid until the function 'close_function' is called. The lifetime
|
/// Note on lifetime: The function pointers must remain valid until the function 'close_function' is called. The lifetime
|
||||||
/// may extend beyond calling the 'libCZI_ReleaseOutputStream' function for the corresponding stream-object.
|
/// may extend beyond calling the 'libCZI_ReleaseOutputStream' function for the corresponding stream-object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ExternalOutputStreamStruct(pub (crate) ExternalOutputStreamStructInterop);
|
pub struct ExternalOutputStreamStruct(pub(crate) ExternalOutputStreamStructInterop);
|
||||||
|
|
||||||
/// This structure gather the information needed to create a reader object.
|
/// This structure gather the information needed to create a reader object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ReaderOpenInfo(pub (crate) ReaderOpenInfoInterop);
|
pub struct ReaderOpenInfo(pub(crate) ReaderOpenInfoInterop);
|
||||||
|
|
||||||
/// This structure describes a rectangle, given by its top-left corner and its width and height.
|
/// This structure describes a rectangle, given by its top-left corner and its width and height.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct IntRect(pub (crate) IntRectInterop);
|
pub struct IntRect(pub(crate) IntRectInterop);
|
||||||
|
|
||||||
/// This structure describes a size, given by its width and height.
|
/// This structure describes a size, given by its width and height.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct IntSize(pub (crate) IntSizeInterop);
|
pub struct IntSize(pub(crate) IntSizeInterop);
|
||||||
|
|
||||||
/// This structure gives the bounds for a set of dimensions.
|
/// This structure gives the bounds for a set of dimensions.
|
||||||
/// The bit at position `i` in `dimensions_valid` indicates whether the interval for dimension `i+1` is valid. So, bit 0
|
/// The bit at position `i` in `dimensions_valid` indicates whether the interval for dimension `i+1` is valid. So, bit 0
|
||||||
@@ -56,7 +56,7 @@ pub struct IntSize(pub (crate) IntSizeInterop);
|
|||||||
/// An example would be: `dimensions_valid` = 0b00000011, `start` = { 0, 2 }, `size` = { 5, 6 }. This would mean that the
|
/// An example would be: `dimensions_valid` = 0b00000011, `start` = { 0, 2 }, `size` = { 5, 6 }. This would mean that the
|
||||||
/// dimension 'Z' is valid, and the interval is [0, 5], and the dimension 'C' is valid, and the interval is [2, 8].
|
/// dimension 'Z' is valid, and the interval is [0, 5], and the dimension 'C' is valid, and the interval is [2, 8].
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DimBounds(pub (crate) DimBoundsInterop);
|
pub struct DimBounds(pub(crate) DimBoundsInterop);
|
||||||
|
|
||||||
/// This structure gives the coordinates (of a sub-block) for a set of dimension.
|
/// This structure gives the coordinates (of a sub-block) for a set of dimension.
|
||||||
/// The bit at position `i` in `dimensions_valid` indicates whether the coordinate for dimension `i+1` is valid. So, bit 0
|
/// The bit at position `i` in `dimensions_valid` indicates whether the coordinate for dimension `i+1` is valid. So, bit 0
|
||||||
@@ -66,35 +66,35 @@ pub struct DimBounds(pub (crate) DimBoundsInterop);
|
|||||||
/// An example would be: `dimensions_valid` = 0b00000011, `value` = { 0, 2 }. This would mean that the
|
/// An example would be: `dimensions_valid` = 0b00000011, `value` = { 0, 2 }. This would mean that the
|
||||||
/// dimension 'Z' is valid, and the coordinate for 'Z' is 0, and the dimension 'C' is valid, and the coordinate for 'C' is 2.
|
/// dimension 'Z' is valid, and the coordinate for 'Z' is 0, and the dimension 'C' is valid, and the coordinate for 'C' is 2.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Coordinate(pub (crate) CoordinateInterop);
|
pub struct Coordinate(pub(crate) CoordinateInterop);
|
||||||
|
|
||||||
/// This structure contains the bounding boxes for a scene.
|
/// This structure contains the bounding boxes for a scene.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BoundingBoxes(pub (crate) BoundingBoxesInterop);
|
pub struct BoundingBoxes(pub(crate) BoundingBoxesInterop);
|
||||||
|
|
||||||
/// This structure contains basic statistics about an CZI-document.
|
/// This structure contains basic statistics about an CZI-document.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SubBlockStatistics(pub (crate) SubBlockStatisticsInterop);
|
pub struct SubBlockStatistics(pub(crate) SubBlockStatisticsInterop);
|
||||||
|
|
||||||
/// This structure extends on the basic statistics about an CZI-document, and includes per-scene statistics.
|
/// This structure extends on the basic statistics about an CZI-document, and includes per-scene statistics.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SubBlockStatisticsEx(pub (crate) SubBlockStatisticsInteropEx);
|
pub struct SubBlockStatisticsEx(pub(crate) SubBlockStatisticsInteropEx);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MetadataAsXml(pub (crate) MetadataAsXmlInterop);
|
pub struct MetadataAsXml(pub(crate) MetadataAsXmlInterop);
|
||||||
|
|
||||||
/// Information about the bitmap represented by a bitmap-object.
|
/// Information about the bitmap represented by a bitmap-object.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BitmapInfo(pub (crate) BitmapInfoInterop);
|
pub struct BitmapInfo(pub(crate) BitmapInfoInterop);
|
||||||
|
|
||||||
/// This structure contains information about a locked bitmap-object, allowing direct
|
/// This structure contains information about a locked bitmap-object, allowing direct
|
||||||
/// access to the pixel data.
|
/// access to the pixel data.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BitmapLockInfo(pub (crate) BitmapLockInfoInterop);
|
pub struct BitmapLockInfo(pub(crate) BitmapLockInfoInterop);
|
||||||
|
|
||||||
/// This structure contains the information about a sub-block.
|
/// This structure contains the information about a sub-block.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SubBlockInfo(pub (crate) SubBlockInfoInterop);
|
pub struct SubBlockInfo(pub(crate) SubBlockInfoInterop);
|
||||||
|
|
||||||
/// This structure contains the information about an attachment.
|
/// This structure contains the information about an attachment.
|
||||||
/// Note that performance reasons we use a fixed-size array for the name. In the rare case that the name is too long to fit into the
|
/// Note that performance reasons we use a fixed-size array for the name. In the rare case that the name is too long to fit into the
|
||||||
@@ -102,35 +102,35 @@ pub struct SubBlockInfo(pub (crate) SubBlockInfoInterop);
|
|||||||
/// In addition, the field 'name_in_case_of_overflow' then contains the full text, allocated with 'libCZI_AllocateString' (and responsibility
|
/// In addition, the field 'name_in_case_of_overflow' then contains the full text, allocated with 'libCZI_AllocateString' (and responsibility
|
||||||
/// for releasing the memory is with the caller).
|
/// for releasing the memory is with the caller).
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AttachmentInfo(pub (crate) AttachmentInfoInterop);
|
pub struct AttachmentInfo(pub(crate) AttachmentInfoInterop);
|
||||||
|
|
||||||
/// This structure contains the information about file-header.
|
/// This structure contains the information about file-header.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FileHeaderInfo(pub (crate) FileHeaderInfoInterop);
|
pub struct FileHeaderInfo(pub(crate) FileHeaderInfoInterop);
|
||||||
|
|
||||||
/// This structure is used to pass the subblock information to libCZIAPI, describing a subblock to be added to a CZI-file.
|
/// This structure is used to pass the subblock information to libCZIAPI, describing a subblock to be added to a CZI-file.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AddSubBlockInfo(pub (crate) AddSubBlockInfoInterop);
|
pub struct AddSubBlockInfo(pub(crate) AddSubBlockInfoInterop);
|
||||||
|
|
||||||
/// This structure is used to pass the attachment information to libCZIAPI, describing an attachment to be added to a CZI-file.
|
/// This structure is used to pass the attachment information to libCZIAPI, describing an attachment to be added to a CZI-file.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AddAttachmentInfo(pub (crate) AddAttachmentInfoInterop);
|
pub struct AddAttachmentInfo(pub(crate) AddAttachmentInfoInterop);
|
||||||
|
|
||||||
/// This structure is used to pass the metadata information to libCZIAPI.
|
/// This structure is used to pass the metadata information to libCZIAPI.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct WriteMetadataInfo(pub (crate) WriteMetadataInfoInterop);
|
pub struct WriteMetadataInfo(pub(crate) WriteMetadataInfoInterop);
|
||||||
|
|
||||||
/// This structure is used to pass the accessor options to libCZIAPI.
|
/// This structure is used to pass the accessor options to libCZIAPI.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AccessorOptions(pub (crate) AccessorOptionsInterop);
|
pub struct AccessorOptions(pub(crate) AccessorOptionsInterop);
|
||||||
|
|
||||||
/// This structure gathers all information about a channel for the purpose of multi-channel-composition.
|
/// This structure gathers all information about a channel for the purpose of multi-channel-composition.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CompositionChannelInfo(pub (crate) CompositionChannelInfoInterop);
|
pub struct CompositionChannelInfo(pub(crate) CompositionChannelInfoInterop);
|
||||||
|
|
||||||
/// This structure gathers the information about the scaling.
|
/// This structure gathers the information about the scaling.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ScalingInfo(pub (crate) ScalingInfoInterop);
|
pub struct ScalingInfo(pub(crate) ScalingInfoInterop);
|
||||||
|
|
||||||
macro_rules! impl_ptr {
|
macro_rules! impl_ptr {
|
||||||
($($n:ident: $t:ty: $s:ty $(,)?)*) => {
|
($($n:ident: $t:ty: $s:ty $(,)?)*) => {
|
||||||
@@ -488,8 +488,83 @@ impl SubBlockStatistics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SubBlockStatisticsEx {
|
||||||
|
// pub fn new(
|
||||||
|
// sub_block_count: i32,
|
||||||
|
// min_m_index: i32,
|
||||||
|
// max_m_index: i32,
|
||||||
|
// bounding_box: IntRect,
|
||||||
|
// bounding_box_layer0: IntRect,
|
||||||
|
// dim_bounds: DimBounds,
|
||||||
|
// per_scenes_bounding_boxes: Vec<BoundingBoxes>
|
||||||
|
// ) -> Self {
|
||||||
|
// Self(SubBlockStatisticsInteropEx {
|
||||||
|
// sub_block_count,
|
||||||
|
// min_m_index,
|
||||||
|
// max_m_index,
|
||||||
|
// bounding_box: bounding_box.0,
|
||||||
|
// bounding_box_layer0: bounding_box_layer0.0,
|
||||||
|
// dim_bounds: dim_bounds.0,
|
||||||
|
// number_of_per_scenes_bounding_boxes: per_scenes_bounding_boxes.len() as i32,
|
||||||
|
// per_scenes_bounding_boxes: unsafe { transmute::<Vec<BoundingBoxes>, __IncompleteArrayField<BoundingBoxesInterop>>(per_scenes_bounding_boxes) },
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
pub fn get_sub_block_count(&self) -> i32 {
|
||||||
|
self.0.sub_block_count
|
||||||
|
}
|
||||||
|
pub fn get_min_m_index(&self) -> i32 {
|
||||||
|
self.0.min_m_index
|
||||||
|
}
|
||||||
|
pub fn get_max_m_index(&self) -> i32 {
|
||||||
|
self.0.max_m_index
|
||||||
|
}
|
||||||
|
pub fn get_bounding_box(&self) -> IntRect {
|
||||||
|
IntRect(self.0.bounding_box)
|
||||||
|
}
|
||||||
|
pub fn get_bounding_box_layer0(&self) -> IntRect {
|
||||||
|
IntRect(self.0.bounding_box_layer0)
|
||||||
|
}
|
||||||
|
pub fn get_dim_bounds(&self) -> DimBounds {
|
||||||
|
DimBounds(self.0.dim_bounds)
|
||||||
|
}
|
||||||
|
pub fn get_number_of_per_scenes_bounding_boxes(&self) -> i32 {
|
||||||
|
self.0.number_of_per_scenes_bounding_boxes
|
||||||
|
}
|
||||||
|
// pub fn get_per_scenes_bounding_boxes(&self) -> Vec<BoundingBoxes> {
|
||||||
|
// unsafe { transmute(&self.0.per_scenes_bounding_boxes) }.clone()
|
||||||
|
// }
|
||||||
|
pub fn set_sub_block_count(&mut self, sub_block_count: i32) {
|
||||||
|
self.0.sub_block_count = sub_block_count;
|
||||||
|
}
|
||||||
|
pub fn set_min_m_index(&mut self, min_m_index: i32) {
|
||||||
|
self.0.min_m_index = min_m_index;
|
||||||
|
}
|
||||||
|
pub fn set_max_m_index(&mut self, max_m_index: i32) {
|
||||||
|
self.0.max_m_index = max_m_index;
|
||||||
|
}
|
||||||
|
pub fn set_bounding_box(&mut self, bounding_box: IntRect) {
|
||||||
|
self.0.bounding_box = bounding_box.0
|
||||||
|
}
|
||||||
|
pub fn set_bounding_box_layer0(&mut self, bounding_box_layer0: IntRect) {
|
||||||
|
self.0.bounding_box_layer0 = bounding_box_layer0.0
|
||||||
|
}
|
||||||
|
pub fn set_dim_bounds(&mut self, dim_bounds: DimBounds) {
|
||||||
|
self.0.dim_bounds = dim_bounds.0
|
||||||
|
}
|
||||||
|
pub fn set_number_of_per_scenes_bounding_boxes(
|
||||||
|
&mut self,
|
||||||
|
number_of_per_scenes_bounding_boxes: i32,
|
||||||
|
) {
|
||||||
|
self.0.number_of_per_scenes_bounding_boxes = number_of_per_scenes_bounding_boxes;
|
||||||
|
}
|
||||||
|
// pub fn set_per_scenes_bounding_boxes(&mut self, per_scenes_bounding_boxes: Vec<BoundingBoxes>) {
|
||||||
|
// self.0.number_of_per_scenes_bounding_boxes = per_scenes_bounding_boxes.len() as i32;
|
||||||
|
// self.0.per_scenes_bounding_boxes = unsafe { transmute(per_scenes_bounding_boxes) };
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
impl MetadataAsXml {
|
impl MetadataAsXml {
|
||||||
fn get_data(&self) -> Result<String> {
|
pub fn get_data(&self) -> Result<String> {
|
||||||
let xml_data = unsafe {
|
let xml_data = unsafe {
|
||||||
Vec::from_raw_parts(
|
Vec::from_raw_parts(
|
||||||
self.0.data as *mut u8,
|
self.0.data as *mut u8,
|
||||||
@@ -697,12 +772,8 @@ impl AddSubBlockInfo {
|
|||||||
physical_height: i32,
|
physical_height: i32,
|
||||||
pixel_type: PixelType,
|
pixel_type: PixelType,
|
||||||
compression_mode_raw: i32,
|
compression_mode_raw: i32,
|
||||||
size_data: u32,
|
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
stride: u32,
|
|
||||||
size_metadata: u32,
|
|
||||||
metadata: &[u8],
|
metadata: &[u8],
|
||||||
size_attachment: u32,
|
|
||||||
attachment: &[u8],
|
attachment: &[u8],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let data = ManuallyDrop::new(data.to_vec());
|
let data = ManuallyDrop::new(data.to_vec());
|
||||||
@@ -721,12 +792,12 @@ impl AddSubBlockInfo {
|
|||||||
physical_height,
|
physical_height,
|
||||||
pixel_type: pixel_type.into(),
|
pixel_type: pixel_type.into(),
|
||||||
compression_mode_raw,
|
compression_mode_raw,
|
||||||
size_data,
|
size_data: data.len() as u32,
|
||||||
data: data.as_ptr() as *const c_void,
|
data: data.as_ptr() as *const c_void,
|
||||||
stride,
|
stride: 1,
|
||||||
size_metadata,
|
size_metadata: metadata.len() as u32,
|
||||||
metadata: metadata.as_ptr() as *const c_void,
|
metadata: metadata.as_ptr() as *const c_void,
|
||||||
size_attachment,
|
size_attachment: attachment.len() as u32,
|
||||||
attachment: attachment.as_ptr() as *const c_void,
|
attachment: attachment.as_ptr() as *const c_void,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -832,25 +903,16 @@ impl AddSubBlockInfo {
|
|||||||
pub fn set_compression_mode_raw(&mut self, compression_mode_raw: i32) {
|
pub fn set_compression_mode_raw(&mut self, compression_mode_raw: i32) {
|
||||||
self.0.compression_mode_raw = compression_mode_raw
|
self.0.compression_mode_raw = compression_mode_raw
|
||||||
}
|
}
|
||||||
pub fn set_size_data(&mut self, size_data: u32) {
|
|
||||||
self.0.size_data = size_data
|
|
||||||
}
|
|
||||||
pub fn set_data(&mut self, data: &[u8]) {
|
pub fn set_data(&mut self, data: &[u8]) {
|
||||||
let data = ManuallyDrop::new(data.to_vec());
|
let data = ManuallyDrop::new(data.to_vec());
|
||||||
self.0.data = data.as_ptr() as *const c_void;
|
self.0.data = data.as_ptr() as *const c_void;
|
||||||
self.0.size_data = data.len() as u32;
|
self.0.size_data = data.len() as u32;
|
||||||
}
|
}
|
||||||
pub fn set_size_metadata(&mut self, size_metadata: u32) {
|
|
||||||
self.0.size_metadata = size_metadata
|
|
||||||
}
|
|
||||||
pub fn set_metadata(&mut self, metadata: &[u8]) {
|
pub fn set_metadata(&mut self, metadata: &[u8]) {
|
||||||
let metadata = ManuallyDrop::new(metadata.to_vec());
|
let metadata = ManuallyDrop::new(metadata.to_vec());
|
||||||
self.0.metadata = metadata.as_ptr() as *const c_void;
|
self.0.metadata = metadata.as_ptr() as *const c_void;
|
||||||
self.0.size_metadata = metadata.len() as u32;
|
self.0.size_metadata = metadata.len() as u32;
|
||||||
}
|
}
|
||||||
pub fn set_size_attachment(&mut self, size_attachment: u32) {
|
|
||||||
self.0.size_attachment = size_attachment
|
|
||||||
}
|
|
||||||
pub fn set_attachment(&mut self, attachment: &[u8]) {
|
pub fn set_attachment(&mut self, attachment: &[u8]) {
|
||||||
let attachment = ManuallyDrop::new(attachment.to_vec());
|
let attachment = ManuallyDrop::new(attachment.to_vec());
|
||||||
self.0.attachment = attachment.as_ptr() as *const c_void;
|
self.0.attachment = attachment.as_ptr() as *const c_void;
|
||||||
@@ -863,7 +925,6 @@ impl AddAttachmentInfo {
|
|||||||
guid: [u8; 16],
|
guid: [u8; 16],
|
||||||
content_file_type: [u8; 8],
|
content_file_type: [u8; 8],
|
||||||
name: [u8; 80],
|
name: [u8; 80],
|
||||||
size_attachment_data: u32,
|
|
||||||
attachment_data: &[u8],
|
attachment_data: &[u8],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
|
let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
|
||||||
@@ -871,7 +932,7 @@ impl AddAttachmentInfo {
|
|||||||
guid,
|
guid,
|
||||||
contentFileType: content_file_type,
|
contentFileType: content_file_type,
|
||||||
name,
|
name,
|
||||||
size_attachment_data,
|
size_attachment_data: attachment_data.len() as u32,
|
||||||
attachment_data: attachment_data.as_ptr() as *const c_void,
|
attachment_data: attachment_data.as_ptr() as *const c_void,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -905,9 +966,6 @@ impl AddAttachmentInfo {
|
|||||||
pub fn set_name(&mut self, name: [u8; 80]) {
|
pub fn set_name(&mut self, name: [u8; 80]) {
|
||||||
self.0.name = name
|
self.0.name = name
|
||||||
}
|
}
|
||||||
pub fn set_size_attachment_data(&mut self, size_attachment_data: u32) {
|
|
||||||
self.0.size_attachment_data = size_attachment_data
|
|
||||||
}
|
|
||||||
pub fn set_attachment_data(&mut self, attachment_data: &[u8]) {
|
pub fn set_attachment_data(&mut self, attachment_data: &[u8]) {
|
||||||
let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
|
let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
|
||||||
self.0.attachment_data = attachment_data.as_ptr() as *const c_void;
|
self.0.attachment_data = attachment_data.as_ptr() as *const c_void;
|
||||||
@@ -916,10 +974,10 @@ impl AddAttachmentInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WriteMetadataInfo {
|
impl WriteMetadataInfo {
|
||||||
pub fn new(size_metadata: u32, metadata: &[u8]) -> Self {
|
pub fn new(metadata: &[u8]) -> Self {
|
||||||
let metadata = ManuallyDrop::new(metadata.to_vec());
|
let metadata = ManuallyDrop::new(metadata.to_vec());
|
||||||
Self(WriteMetadataInfoInterop {
|
Self(WriteMetadataInfoInterop {
|
||||||
size_metadata,
|
size_metadata: metadata.len() as u32,
|
||||||
metadata: metadata.as_ptr() as *const c_void,
|
metadata: metadata.as_ptr() as *const c_void,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -935,9 +993,6 @@ impl WriteMetadataInfo {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_size_metadata(&mut self, size_metadata: u32) {
|
|
||||||
self.0.size_metadata = size_metadata
|
|
||||||
}
|
|
||||||
pub fn set_metadata(&mut self, metadata: &[u8]) {
|
pub fn set_metadata(&mut self, metadata: &[u8]) {
|
||||||
let metadata = ManuallyDrop::new(metadata.to_vec());
|
let metadata = ManuallyDrop::new(metadata.to_vec());
|
||||||
self.0.metadata = metadata.as_ptr() as *const c_void;
|
self.0.metadata = metadata.as_ptr() as *const c_void;
|
||||||
|
|||||||
28
src/lib.rs
28
src/lib.rs
@@ -1,3 +1,5 @@
|
|||||||
|
extern crate link_cplusplus;
|
||||||
|
|
||||||
mod functions;
|
mod functions;
|
||||||
mod handle;
|
mod handle;
|
||||||
mod interop;
|
mod interop;
|
||||||
@@ -7,7 +9,7 @@ pub mod sys;
|
|||||||
pub use functions::*;
|
pub use functions::*;
|
||||||
pub use handle::*;
|
pub use handle::*;
|
||||||
pub use interop::*;
|
pub use interop::*;
|
||||||
pub use misc::{LibCZIApiError, RawDataType, PixelType};
|
pub use misc::{LibCZIApiError, PixelType, RawDataType};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -15,6 +17,7 @@ mod tests {
|
|||||||
use crate::interop::{LibCZIBuildInformation, ReaderOpenInfo};
|
use crate::interop::{LibCZIBuildInformation, ReaderOpenInfo};
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{Error, Result};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_libczi_xml() -> Result<()> {
|
fn test_libczi_xml() -> Result<()> {
|
||||||
@@ -37,9 +40,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_libczi_pyramid_statistics() -> Result<()> {
|
fn test_libczi_pyramid_statistics() -> Result<()> {
|
||||||
let path = env::home_dir()
|
let path = PathBuf::from("test-files/Experiment-2029.czi");
|
||||||
.unwrap()
|
|
||||||
.join("code/rust/ndbioimage/tests/files/Experiment-2029.czi");
|
|
||||||
assert!(path.exists());
|
assert!(path.exists());
|
||||||
let czi = CziReader::create()?;
|
let czi = CziReader::create()?;
|
||||||
let stream = InputStream::create_from_file_utf8(
|
let stream = InputStream::create_from_file_utf8(
|
||||||
@@ -54,9 +55,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_libczi_document_info() -> Result<()> {
|
fn test_libczi_document_info() -> Result<()> {
|
||||||
let path = env::home_dir()
|
let path = PathBuf::from("test-files/Experiment-2029.czi");
|
||||||
.unwrap()
|
|
||||||
.join("code/rust/ndbioimage/tests/files/Experiment-2029.czi");
|
|
||||||
assert!(path.exists());
|
assert!(path.exists());
|
||||||
let czi = CziReader::create()?;
|
let czi = CziReader::create()?;
|
||||||
let stream = InputStream::create_from_file_utf8(
|
let stream = InputStream::create_from_file_utf8(
|
||||||
@@ -67,16 +66,25 @@ mod tests {
|
|||||||
let metadata_segment = czi.get_metadata_segment()?;
|
let metadata_segment = czi.get_metadata_segment()?;
|
||||||
let document_info = metadata_segment.get_czi_document_info()?;
|
let document_info = metadata_segment.get_czi_document_info()?;
|
||||||
let general_document_info = document_info.get_general_document_info()?;
|
let general_document_info = document_info.get_general_document_info()?;
|
||||||
println!("xml: {}", &general_document_info[..general_document_info.len().min(100)]);
|
println!(
|
||||||
|
"xml: {}",
|
||||||
|
&general_document_info[..general_document_info.len().min(100)]
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lib_czi_build_information() -> Result<()> {
|
fn test_lib_czi_build_information() -> Result<()> {
|
||||||
let build_info = LibCZIBuildInformation::get()?;
|
let build_info = LibCZIBuildInformation::get()?;
|
||||||
println!("compiler information: {:?}", build_info.get_compiler_information());
|
println!(
|
||||||
|
"compiler information: {:?}",
|
||||||
|
build_info.get_compiler_information()
|
||||||
|
);
|
||||||
println!("repository url: {:?}", build_info.get_repository_url());
|
println!("repository url: {:?}", build_info.get_repository_url());
|
||||||
println!("repository branch: {:?}", build_info.get_repository_branch());
|
println!(
|
||||||
|
"repository branch: {:?}",
|
||||||
|
build_info.get_repository_branch()
|
||||||
|
);
|
||||||
println!("repository tag: {:?}", build_info.get_repository_tag());
|
println!("repository tag: {:?}", build_info.get_repository_tag());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use anyhow::{anyhow, Error, Result};
|
use anyhow::{Error, Result, anyhow};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|||||||
@@ -7,4 +7,8 @@
|
|||||||
#![allow(rustdoc::invalid_html_tags)]
|
#![allow(rustdoc::invalid_html_tags)]
|
||||||
#![allow(clippy::missing_safety_doc)]
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
|
||||||
|
#[cfg(docsrs)]
|
||||||
include!("lib_czi_api.rs");
|
include!("lib_czi_api.rs");
|
||||||
|
|
||||||
|
#[cfg(not(docsrs))]
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/lib_czi_api.rs"));
|
||||||
|
|||||||
BIN
test-files/Experiment-2029.czi
Normal file
BIN
test-files/Experiment-2029.czi
Normal file
Binary file not shown.
Reference in New Issue
Block a user