C Examples¶
Below are code snippets for completing various tasks using the C Interface to the Acquire Zarr library. Have an example you'd like to share with the community? Submit a GitHub issue and include "Example:" in your title.
Example: Zarr V2 with ZSTD compression to S3
/// @file zarrv2-compressed-s3.c
/// @brief Zarr V2 with ZSTD compression to S3
#include "acquire.zarr.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
// Configure S3
ZarrS3Settings s3 = {
.endpoint = "http://localhost:9000",
.bucket_name = "mybucket",
.access_key_id = "myaccesskey",
.secret_access_key = "mysecretkey"
};
// Configure compression
ZarrCompressionSettings compression = {
.compressor = ZarrCompressor_Blosc1,
.codec = ZarrCompressionCodec_BloscZstd,
.level = 1,
.shuffle = 1
};
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v2_s3.zarr",
.s3_settings = &s3,
.compression_settings = &compression,
.data_type = ZarrDataType_int32,
.version = ZarrVersion_2,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, c, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 4);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0, // Unlimited
.chunk_size_px = 32,
.shard_size_chunks = 1
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "c",
.type = ZarrDimensionType_Channel,
.array_size_px = 3,
.chunk_size_px = 3,
.shard_size_chunks = 1
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1
};
settings.dimensions[3] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 32,
.shard_size_chunks = 1
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
int32_t* frame = (int32_t*)malloc(width * height * sizeof(int32_t));
// Write frames
size_t bytes_written;
for (int i = 0; i < 10; i++) {
// Fill frame with sample data
for (size_t j = 0; j < width * height; j++) {
frame[j] = i * 1000 + j;
}
ZarrStatusCode status = ZarrStream_append(
stream,
frame,
width * height * sizeof(int32_t),
&bytes_written
);
if (status != ZarrStatusCode_Success) {
fprintf(stderr, "Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Basic Zarr V2 streaming to filesystem
/// @file zarrv2-raw-filesystem.c
/// @brief Basic Zarr V2 streaming to filesystem
#include "acquire.zarr.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v2.zarr",
.s3_settings = NULL,
.compression_settings = NULL,
.data_type = ZarrDataType_int32,
.version = ZarrVersion_2,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 3);
// Time dimension - unlimited size (0)
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0,
.chunk_size_px = 32,
.shard_size_chunks = 1
};
// Y dimension - 48 pixels
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1
};
// X dimension - 64 pixels
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 32,
.shard_size_chunks = 1
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
int32_t* frame = (int32_t*)malloc(width * height * sizeof(int32_t));
// Write some frames
size_t bytes_written;
for (int i = 0; i < 10; i++) {
// Fill frame with sample data
for (size_t j = 0; j < width * height; j++) {
frame[j] = i * 1000 + j;
}
ZarrStatusCode status = ZarrStream_append(
stream,
frame,
width * height * sizeof(int32_t),
&bytes_written
);
if (status != ZarrStatusCode_Success) {
fprintf(stderr, "Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Zarr V3 with LZ4 compression to filesystem
/// @file zarr-v3-compressed-filesystem.c
/// @brief Zarr V3 with LZ4 compression to filesystem
#include "acquire.zarr.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int
main()
{
// Configure compression
ZarrCompressionSettings compression = {
.compressor = ZarrCompressor_Blosc1,
.codec = ZarrCompressionCodec_BloscLZ4,
.level = 1,
.shuffle = 1,
};
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v3_compressed.zarr",
.s3_settings = NULL,
.compression_settings = &compression,
.data_type = ZarrDataType_uint16,
.version = ZarrVersion_3,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 3);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0,
.chunk_size_px = 5,
.shard_size_chunks = 2,
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1,
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 16,
.shard_size_chunks = 2,
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
int centerX = width / 2;
int centerY = height / 2;
uint16_t* frame = (uint16_t*)malloc(width * height * sizeof(uint16_t));
// Write frames
size_t bytes_written;
for (int t = 0; t < 50; t++) {
// Fill frame with a moving diagonal pattern
for (size_t y = 0; y < height; y++) {
int dy = y - centerY;
for (size_t x = 0; x < width; x++) {
// Create a diagonal pattern that moves with time
// and varies intensity based on position
int diagonal = (x + y + t * 8) % 32;
// Create intensity variation
uint16_t intensity;
if (diagonal < 16) {
intensity = (uint16_t)((diagonal * 4096)); // Ramp up
} else {
intensity = (uint16_t)((31 - diagonal) * 4096); // Ramp down
}
// Add some circular features
int dx = x - centerX;
int radius = (int)sqrt(dx*dx + dy*dy);
// Modulate the pattern with concentric circles
if (radius % 16 < 8) {
intensity = (uint16_t)(intensity * 0.7);
}
frame[y * width + x] = intensity;
}
}
ZarrStatusCode status = ZarrStream_append(
stream, frame, width * height * sizeof(uint16_t), &bytes_written);
if (status != ZarrStatusCode_Success) {
fprintf(stderr,
"Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Multiscale Zarr V3 with compressed data to S3
/// @file zarrv3-compressed-multiscale-s3.c
/// @brief Multiscale Zarr V3 with compressed data to S3
#include "acquire.zarr.h"
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
int
main()
{
// Configure compression
ZarrCompressionSettings compression = {
.compressor = ZarrCompressor_Blosc1,
.codec = ZarrCompressionCodec_BloscZstd,
.level = 1,
.shuffle = 1,
};
// Configure S3
ZarrS3Settings s3 = {
.endpoint = "http://192.168.1.57:9000",
.bucket_name = "acquire-test",
.access_key_id = "tv4MtRQPbtfwKxMusI0I",
.secret_access_key = "W85Cnb4qd7bhPaTsqkt8aEKoO3XtXm49o9nMtD5O",
};
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v3_compressed_multiscale_s3.zarr",
.s3_settings = &s3,
.compression_settings = &compression,
.data_type = ZarrDataType_uint16,
.version = ZarrVersion_3,
.multiscale = true,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, z, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 4);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0, // Unlimited
.chunk_size_px = 5,
.shard_size_chunks = 2,
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "z",
.type = ZarrDimensionType_Space,
.array_size_px = 10,
.chunk_size_px = 2,
.shard_size_chunks = 1,
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1,
};
settings.dimensions[3] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 16,
.shard_size_chunks = 2,
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
uint16_t* frame = (uint16_t*)malloc(width * height * sizeof(uint16_t));
// Write frames
size_t bytes_written;
for (int t = 0; t < 10; t++) {
// Fill frame with a moving diagonal pattern
for (size_t y = 0; y < height; y++) {
for (size_t x = 0; x < width; x++) {
// Create a diagonal pattern that moves with time
// and varies intensity based on position
int diagonal = (x + y + t * 8) % 32;
// Create intensity variation
uint16_t intensity;
if (diagonal < 16) {
intensity = (uint16_t)((diagonal * 4096)); // Ramp up
} else {
intensity = (uint16_t)((31 - diagonal) * 4096); // Ramp down
}
// Add some circular features
int centerX = width / 2;
int centerY = height / 2;
int dx = x - centerX;
int dy = y - centerY;
int radius = (int)sqrt(dx*dx + dy*dy);
// Modulate the pattern with concentric circles
if (radius % 16 < 8) {
intensity = (uint16_t)(intensity * 0.7);
}
frame[y * width + x] = intensity;
}
}
ZarrStatusCode status = ZarrStream_append(
stream, frame, width * height * sizeof(uint16_t), &bytes_written);
if (status != ZarrStatusCode_Success) {
fprintf(stderr,
"Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Stream data to a Zarr V3 store with Zstd compression data on S3
/// @file zarrv3-compressed-s3.c
/// @brief Stream data to a Zarr V3 store with Zstd compression data on S3
#include "acquire.zarr.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int
main()
{
// Configure compression
ZarrCompressionSettings compression = {
.compressor = ZarrCompressor_Blosc1,
.codec = ZarrCompressionCodec_BloscZstd,
.level = 1,
.shuffle = 1,
};
// Configure S3
ZarrS3Settings s3 = {
.endpoint = "http://localhost:9000",
.bucket_name = "mybucket",
.access_key_id = "myaccesskey",
.secret_access_key = "mysecretkey"
};
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v3_compressed_s3.zarr",
.s3_settings = &s3,
.compression_settings = &compression,
.data_type = ZarrDataType_uint16,
.version = ZarrVersion_3,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 3);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0, // Unlimited
.chunk_size_px = 5,
.shard_size_chunks = 2,
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1,
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 16,
.shard_size_chunks = 2,
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
uint16_t* frame = (uint16_t*)malloc(width * height * sizeof(uint16_t));
// Write frames
size_t bytes_written;
for (int t = 0; t < 50; t++) {
// Fill frame with a moving diagonal pattern
for (size_t y = 0; y < height; y++) {
for (size_t x = 0; x < width; x++) {
// Create a diagonal pattern that moves with time
// and varies intensity based on position
int diagonal = (x + y + t * 8) % 32;
// Create intensity variation
uint16_t intensity;
if (diagonal < 16) {
intensity = (uint16_t)((diagonal * 4096)); // Ramp up
} else {
intensity = (uint16_t)((31 - diagonal) * 4096); // Ramp down
}
// Add some circular features
int centerX = width / 2;
int centerY = height / 2;
int dx = x - centerX;
int dy = y - centerY;
int radius = (int)sqrt(dx*dx + dy*dy);
// Modulate the pattern with concentric circles
if (radius % 16 < 8) {
intensity = (uint16_t)(intensity * 0.7);
}
frame[y * width + x] = intensity;
}
}
ZarrStatusCode status = ZarrStream_append(
stream, frame, width * height * sizeof(uint16_t), &bytes_written);
if (status != ZarrStatusCode_Success) {
fprintf(stderr,
"Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Basic Zarr V3 streaming to filesystem
/// @file zarr-v3-raw-filesystem.c
/// @brief Basic Zarr V3 streaming to filesystem
#include "acquire.zarr.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int
main()
{
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v3.zarr",
.s3_settings = NULL,
.compression_settings = NULL,
.data_type = ZarrDataType_uint16,
.version = ZarrVersion_3,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 3);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0,
.chunk_size_px = 5,
.shard_size_chunks = 2,
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1,
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 16,
.shard_size_chunks = 2,
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
uint16_t* frame = (uint16_t*)malloc(width * height * sizeof(uint16_t));
// Write frames
size_t bytes_written;
for (int t = 0; t < 50; t++) {
// Fill frame with a moving diagonal pattern
for (size_t y = 0; y < height; y++) {
for (size_t x = 0; x < width; x++) {
// Create a diagonal pattern that moves with time
// and varies intensity based on position
int diagonal = (x + y + t * 8) % 32;
// Create intensity variation
uint16_t intensity;
if (diagonal < 16) {
intensity = (uint16_t)((diagonal * 4096)); // Ramp up
} else {
intensity = (uint16_t)((31 - diagonal) * 4096); // Ramp down
}
// Add some circular features
int centerX = width / 2;
int centerY = height / 2;
int dx = x - centerX;
int dy = y - centerY;
int radius = (int)sqrt(dx*dx + dy*dy);
// Modulate the pattern with concentric circles
if (radius % 16 < 8) {
intensity = (uint16_t)(intensity * 0.7);
}
frame[y * width + x] = intensity;
}
}
ZarrStatusCode status = ZarrStream_append(
stream, frame, width * height * sizeof(uint16_t), &bytes_written);
if (status != ZarrStatusCode_Success) {
fprintf(stderr,
"Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Uncompressed streaming to a Zarr V3 store on the filesystem, with multiple levels of detail.
/// @file zarrv3-raw-multiscale-filesystem.c
/// @brief Uncompressed streaming to a Zarr V3 store on the filesystem, with
/// multiple levels of detail.
#include "acquire.zarr.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
int
main()
{
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v3_multiscale.zarr",
.s3_settings = NULL,
.compression_settings = NULL,
.multiscale = true,
.data_type = ZarrDataType_uint16,
.version = ZarrVersion_3,
.max_threads = 0, // use all available threads
};
// Set up 5D array (t, c, z, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 5);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 10,
.chunk_size_px = 5,
.shard_size_chunks = 2,
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "c",
.type = ZarrDimensionType_Channel,
.array_size_px = 8,
.chunk_size_px = 4,
.shard_size_chunks = 2,
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "z",
.type = ZarrDimensionType_Space,
.array_size_px = 6,
.chunk_size_px = 2,
.shard_size_chunks = 1,
};
settings.dimensions[3] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1,
};
settings.dimensions[4] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 16,
.shard_size_chunks = 2,
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
uint16_t* frame = (uint16_t*)malloc(width * height * sizeof(uint16_t));
// Write frames
size_t bytes_written;
for (int i = 0; i < 10; i++) {
// Fill frame with sample data
for (size_t j = 0; j < width * height; j++) {
frame[j] = i * 1000 + j;
}
ZarrStatusCode status = ZarrStream_append(
stream, frame, width * height * sizeof(uint16_t), &bytes_written);
if (status != ZarrStatusCode_Success) {
fprintf(stderr,
"Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}
Example: Zarr V3 with uncompressed data to S3
/// @file zarrv3-raw-s3.c
/// @brief Zarr V3 with uncompressed data to S3
#include "acquire.zarr.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
// Configure S3
ZarrS3Settings s3 = {
.endpoint = "http://localhost:9000",
.bucket_name = "mybucket",
.access_key_id = "myaccesskey",
.secret_access_key = "mysecretkey"
};
// Configure stream settings
ZarrStreamSettings settings = {
.store_path = "output_v3_s3.zarr",
.s3_settings = &s3,
.compression_settings = NULL, // No compression
.data_type = ZarrDataType_uint16,
.version = ZarrVersion_3,
.max_threads = 0, // use all available threads
};
// Set up dimensions (t, z, y, x)
ZarrStreamSettings_create_dimension_array(&settings, 4);
settings.dimensions[0] = (ZarrDimensionProperties){
.name = "t",
.type = ZarrDimensionType_Time,
.array_size_px = 0, // Unlimited
.chunk_size_px = 5,
.shard_size_chunks = 2
};
settings.dimensions[1] = (ZarrDimensionProperties){
.name = "z",
.type = ZarrDimensionType_Space,
.array_size_px = 10,
.chunk_size_px = 2,
.shard_size_chunks = 1
};
settings.dimensions[2] = (ZarrDimensionProperties){
.name = "y",
.type = ZarrDimensionType_Space,
.array_size_px = 48,
.chunk_size_px = 16,
.shard_size_chunks = 1
};
settings.dimensions[3] = (ZarrDimensionProperties){
.name = "x",
.type = ZarrDimensionType_Space,
.array_size_px = 64,
.chunk_size_px = 16,
.shard_size_chunks = 2
};
// Create stream
ZarrStream* stream = ZarrStream_create(&settings);
// Free Dimension array
ZarrStreamSettings_destroy_dimension_array(&settings);
if (!stream) {
fprintf(stderr, "Failed to create stream\n");
return 1;
}
// Create sample data
const size_t width = 64;
const size_t height = 48;
uint16_t* frame = (uint16_t*)malloc(width * height * sizeof(uint16_t));
// Write frames
size_t bytes_written;
for (int i = 0; i < 10; i++) {
// Fill frame with sample data
for (size_t j = 0; j < width * height; j++) {
frame[j] = i * 1000 + j;
}
ZarrStatusCode status = ZarrStream_append(
stream,
frame,
width * height * sizeof(uint16_t),
&bytes_written
);
if (status != ZarrStatusCode_Success) {
fprintf(stderr, "Failed to append frame: %s\n",
Zarr_get_status_message(status));
break;
}
}
// Cleanup
free(frame);
ZarrStream_destroy(stream);
return 0;
}