Commit f1058b4e for libheif
commit f1058b4e881d6d0a9711f759e404c7ea9633e399
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Sun May 17 18:42:09 2026 +0200
all typed heif_image_get_component_X() function now return number of elements per row instead of stride
diff --git a/heifio/decoder_tiff.cc b/heifio/decoder_tiff.cc
index d19bc457..5d112606 100644
--- a/heifio/decoder_tiff.cc
+++ b/heifio/decoder_tiff.cc
@@ -717,7 +717,7 @@ static heif_error readMonoFloat(TIFF* tif, heif_image** image)
*image = nullptr;
return {heif_error_Invalid_input, heif_suberror_Unspecified, "Failed to read TIFF scanline"};
}
- memcpy(reinterpret_cast<uint8_t*>(plane) + row * stride, buf, width * sizeof(float));
+ memcpy(plane + row * stride, buf, width * sizeof(float));
}
_TIFFfree(buf);
@@ -748,13 +748,13 @@ static heif_error readMonoSignedInt(TIFF* tif, uint16_t bps, heif_image** image)
return err;
}
- size_t stride;
+ size_t row_elements; // int8 or int16 elements per row, depending on bps
uint8_t* plane;
if (bps == 8) {
- plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int8(*image, component_idx, &stride));
+ plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int8(*image, component_idx, &row_elements));
}
else {
- plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int16(*image, component_idx, &stride));
+ plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int16(*image, component_idx, &row_elements));
}
if (!plane) {
heif_image_release(*image);
@@ -763,6 +763,7 @@ static heif_error readMonoSignedInt(TIFF* tif, uint16_t bps, heif_image** image)
}
int bytesPerSample = bps > 8 ? 2 : 1;
+ size_t row_bytes = row_elements * bytesPerSample;
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(tif));
for (uint32_t row = 0; row < height; row++) {
if (TIFFReadScanline(tif, buf, row, 0) < 0) {
@@ -771,7 +772,7 @@ static heif_error readMonoSignedInt(TIFF* tif, uint16_t bps, heif_image** image)
*image = nullptr;
return {heif_error_Invalid_input, heif_suberror_Unspecified, "Failed to read TIFF scanline"};
}
- memcpy(plane + row * stride, buf, width * bytesPerSample);
+ memcpy(plane + row * row_bytes, buf, width * bytesPerSample);
}
_TIFFfree(buf);
@@ -1067,8 +1068,8 @@ static heif_error readTiledContiguous(TIFF* tif, uint32_t width, uint32_t height
uint32_t actual_h = std::min(tile_height, height - ty * tile_height);
for (uint32_t row = 0; row < actual_h; row++) {
- uint8_t* dst = reinterpret_cast<uint8_t*>(out_plane) + (size_t)(ty * tile_height + row) * out_stride
- + (size_t)tx * tile_width * sizeof(float);
+ float* dst = out_plane + (size_t)(ty * tile_height + row) * out_stride
+ + (size_t)tx * tile_width;
float* src = reinterpret_cast<float*>(tile_buf.data() + (size_t)row * tile_width * sizeof(float));
memcpy(dst, src, actual_w * sizeof(float));
}
@@ -1099,13 +1100,13 @@ static heif_error readTiledContiguous(TIFF* tif, uint32_t width, uint32_t height
return err;
}
- size_t out_stride;
+ size_t row_elements; // int8 or int16 elements per row, depending on bps
uint8_t* out_plane;
if (bps == 8) {
- out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int8(*out_image, component_idx, &out_stride));
+ out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int8(*out_image, component_idx, &row_elements));
}
else {
- out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int16(*out_image, component_idx, &out_stride));
+ out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int16(*out_image, component_idx, &row_elements));
}
if (!out_plane) {
heif_image_release(*out_image);
@@ -1114,6 +1115,7 @@ static heif_error readTiledContiguous(TIFF* tif, uint32_t width, uint32_t height
}
int bytesPerSample = bps > 8 ? 2 : 1;
+ size_t row_bytes = row_elements * bytesPerSample;
tmsize_t tile_buf_size = TIFFTileSize(tif);
std::vector<uint8_t> tile_buf(tile_buf_size);
@@ -1134,7 +1136,7 @@ static heif_error readTiledContiguous(TIFF* tif, uint32_t width, uint32_t height
uint32_t actual_h = std::min(tile_height, height - ty * tile_height);
for (uint32_t row = 0; row < actual_h; row++) {
- uint8_t* dst = out_plane + ((size_t)ty * tile_height + row) * out_stride
+ uint8_t* dst = out_plane + ((size_t)ty * tile_height + row) * row_bytes
+ (size_t)tx * tile_width * bytesPerSample;
uint8_t* src = tile_buf.data() + (size_t)row * tile_width * bytesPerSample;
memcpy(dst, src, actual_w * bytesPerSample);
@@ -1665,7 +1667,7 @@ heif_error TiledTiffReader::readTile(uint32_t tx, uint32_t ty, int output_bit_de
}
for (uint32_t row = 0; row < actual_h; row++) {
- uint8_t* dst = reinterpret_cast<uint8_t*>(out_plane) + row * out_stride;
+ float* dst = out_plane + row * out_stride;
float* src = reinterpret_cast<float*>(tile_buf.data() + row * m_tile_width * sizeof(float));
memcpy(dst, src, actual_w * sizeof(float));
}
@@ -1692,13 +1694,13 @@ heif_error TiledTiffReader::readTile(uint32_t tx, uint32_t ty, int output_bit_de
return err;
}
- size_t out_stride;
+ size_t row_elements; // int8 or int16 elements per row, depending on bps
uint8_t* out_plane;
if (m_bits_per_sample == 8) {
- out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int8(*out_image, component_idx, &out_stride));
+ out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int8(*out_image, component_idx, &row_elements));
}
else {
- out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int16(*out_image, component_idx, &out_stride));
+ out_plane = reinterpret_cast<uint8_t*>(heif_image_get_component_int16(*out_image, component_idx, &row_elements));
}
if (!out_plane) {
heif_image_release(*out_image);
@@ -1707,6 +1709,7 @@ heif_error TiledTiffReader::readTile(uint32_t tx, uint32_t ty, int output_bit_de
}
int bytesPerSample = m_bits_per_sample > 8 ? 2 : 1;
+ size_t row_bytes = row_elements * bytesPerSample;
tmsize_t tile_buf_size = TIFFTileSize(tif);
std::vector<uint8_t> tile_buf(tile_buf_size);
@@ -1719,7 +1722,7 @@ heif_error TiledTiffReader::readTile(uint32_t tx, uint32_t ty, int output_bit_de
}
for (uint32_t row = 0; row < actual_h; row++) {
- uint8_t* dst = out_plane + row * out_stride;
+ uint8_t* dst = out_plane + row * row_bytes;
uint8_t* src = tile_buf.data() + row * m_tile_width * bytesPerSample;
memcpy(dst, src, actual_w * bytesPerSample);
}
diff --git a/libheif/api/libheif/heif_brands.h b/libheif/api/libheif/heif_brands.h
index 68cd89f9..85177ced 100644
--- a/libheif/api/libheif/heif_brands.h
+++ b/libheif/api/libheif/heif_brands.h
@@ -250,6 +250,7 @@ typedef uint32_t heif_brand2;
#define heif_brand2_avci heif_fourcc('a','v','c','i')
#define heif_brand2_avcs heif_fourcc('a','v','c','s')
+//NEWAPI
/**
* Unified ID namespace (`unif`) brand.
*
diff --git a/libheif/api/libheif/heif_context.h b/libheif/api/libheif/heif_context.h
index f4a488b4..a9d35e9d 100644
--- a/libheif/api/libheif/heif_context.h
+++ b/libheif/api/libheif/heif_context.h
@@ -298,6 +298,7 @@ void heif_context_debug_dump_boxes_to_file(heif_context* ctx, int fd);
// ====================================================================================================
// Mini format (experimental)
+//NEWAPI
// Enable writing in the compact 'mini' box format (ISO/IEC 23008-12 DAmd2).
// When enabled, the output file will use a single 'mini' box instead of the standard
// meta+mdat box structure, if the file content is compatible with the mini format.
diff --git a/libheif/api/libheif/heif_decoding.h b/libheif/api/libheif/heif_decoding.h
index 3f1e8902..6f73f642 100644
--- a/libheif/api/libheif/heif_decoding.h
+++ b/libheif/api/libheif/heif_decoding.h
@@ -39,6 +39,7 @@ extern "C" {
LIBHEIF_API
void heif_context_set_max_decoding_threads(heif_context* ctx, int max_threads);
+//NEWAPI
// Returns the current maximum number of background threads used for parallel tile decoding.
// This reflects either the library default or the value last passed to
// heif_context_set_max_decoding_threads().
diff --git a/libheif/api/libheif/heif_encoding.h b/libheif/api/libheif/heif_encoding.h
index eba9f75a..7e6bb165 100644
--- a/libheif/api/libheif/heif_encoding.h
+++ b/libheif/api/libheif/heif_encoding.h
@@ -270,6 +270,7 @@ typedef enum heif_orientation
} heif_orientation;
+//NEWAPI
LIBHEIF_API
heif_orientation heif_orientation_concat(heif_orientation first, heif_orientation second);
@@ -315,6 +316,7 @@ typedef struct heif_encoding_options
// version 8 options
+ //NEWAPI
// Set this to enable compression for 'unci' images encoded through heif_context_encode_image().
// Default: heif_unci_compression_off
heif_unci_compression unci_compression;
@@ -375,6 +377,7 @@ LIBHEIF_API
void heif_context_add_compatible_brand(heif_context* ctx,
heif_brand2 compatible_brand);
+//NEWAPI
/**
* Enable the unified ID namespace ('unif' brand).
*
diff --git a/libheif/api/libheif/heif_error.h b/libheif/api/libheif/heif_error.h
index c0de48f1..85916ba4 100644
--- a/libheif/api/libheif/heif_error.h
+++ b/libheif/api/libheif/heif_error.h
@@ -191,6 +191,7 @@ typedef enum heif_suberror_code
heif_suberror_No_moov_box = 151,
+ //NEWAPI
// The colr (NCLX) box and the codec bitstream VUI/color signalling disagree.
// Per ISO/IEC 14496-12 and ISO/IEC 23000-22 (MIAF) the colr box takes precedence,
// but the conflict is reported as a warning.
diff --git a/libheif/api/libheif/heif_image.h b/libheif/api/libheif/heif_image.h
index a6c08378..7fc8f1ae 100644
--- a/libheif/api/libheif/heif_image.h
+++ b/libheif/api/libheif/heif_image.h
@@ -105,6 +105,7 @@ typedef enum heif_colorspace
// Images of this type are always planar and use heif_chroma_planar.
heif_colorspace_custom = 3,
+ //NEWAPI
// Images of this type are filter-array (CFA / Bayer) mosaics. The single
// mosaicked plane is described as heif_chroma_planar.
heif_colorspace_filter_array = 4
@@ -125,9 +126,11 @@ typedef enum heif_channel
heif_channel_filter_array = 11,
heif_channel_depth = 12,
heif_channel_disparity = 13,
+ //NEWAPI
heif_channel_unknown = 65535
} heif_channel;
+//NEWAPI
/**
* OMAF Image projection.
*
@@ -363,9 +366,11 @@ void heif_image_set_pixel_aspect_ratio(heif_image*, uint32_t aspect_h, uint32_t
LIBHEIF_API
void heif_image_handle_set_pixel_aspect_ratio(heif_image_handle*, uint32_t aspect_h, uint32_t aspect_v);
+//NEWAPI
LIBHEIF_API
heif_omaf_image_projection heif_image_get_omaf_image_projection(const heif_image*);
+//NEWAPI
LIBHEIF_API
void heif_image_set_omaf_image_projection(const heif_image*, heif_omaf_image_projection image_projection);
diff --git a/libheif/api/libheif/heif_image_handle.h b/libheif/api/libheif/heif_image_handle.h
index d883bfcc..f3f4e642 100644
--- a/libheif/api/libheif/heif_image_handle.h
+++ b/libheif/api/libheif/heif_image_handle.h
@@ -122,21 +122,25 @@ heif_context* heif_image_handle_get_context(const heif_image_handle* handle);
LIBHEIF_API
const char* heif_image_handle_get_gimi_content_id(const heif_image_handle* handle);
+//NEWAPI
LIBHEIF_API
void heif_image_handle_set_gimi_content_id(heif_image_handle* handle, const char* content_id);
// --- cmpd component queries
+//NEWAPI
// Returns the number of components in the cmpd box, or 0 if no cmpd property exists.
LIBHEIF_API
uint32_t heif_image_handle_get_number_of_cmpd_components(const heif_image_handle*);
+//NEWAPI
// Returns the component_type for the given cmpd component index.
// Returns 0 if out of range or no cmpd property.
LIBHEIF_API
uint16_t heif_image_handle_get_cmpd_component_type(const heif_image_handle*, uint32_t component_idx);
+//NEWAPI
// Returns the component_type_uri for the given cmpd component index (component_type >= 0x8000).
// Returns NULL if the component does not have a URI.
// The returned string must be freed with heif_string_release().
@@ -146,16 +150,19 @@ const char* heif_image_handle_get_cmpd_component_type_uri(const heif_image_handl
// --- GIMI component content IDs (handle-level)
+//NEWAPI
// Returns non-zero (count of content IDs) if an ItemComponentContentIDProperty is set, 0 otherwise.
LIBHEIF_API
int heif_image_handle_has_gimi_component_content_ids(const heif_image_handle*);
+//NEWAPI
// Returns the GIMI component content ID for the given component index.
// Returns NULL if no ItemComponentContentIDProperty is set or index is out of range.
// The returned string must be freed with heif_string_release().
LIBHEIF_API
const char* heif_image_handle_get_gimi_component_content_id(const heif_image_handle*, uint32_t component_idx);
+//NEWAPI
// Set a GIMI component content ID for a single component.
// If an ItemComponentContentIDProperty does not yet exist, one will be created.
// The content IDs array is resized as needed (new entries default to empty).
diff --git a/libheif/api/libheif/heif_plugin.h b/libheif/api/libheif/heif_plugin.h
index 77123039..b90cbeb7 100644
--- a/libheif/api/libheif/heif_plugin.h
+++ b/libheif/api/libheif/heif_plugin.h
@@ -73,6 +73,7 @@ typedef struct heif_decoder_plugin_options
int strict_decoding; // bool
int num_threads; // 0 - undefined, use decoder default
+ //NEWAPI
// --- added in plugin_api_version 6 ---
// Security limits the plugin must enforce for image allocations during decoding.
// The pointee must outlive the decoder instance (typically the context's limits).
diff --git a/libheif/api/libheif/heif_properties.h b/libheif/api/libheif/heif_properties.h
index 41487eb4..d04c74a9 100644
--- a/libheif/api/libheif/heif_properties.h
+++ b/libheif/api/libheif/heif_properties.h
@@ -231,9 +231,11 @@ heif_error heif_camera_extrinsic_matrix_get_rotation_matrix(const heif_camera_ex
// ------------------------- OMAF projection information -------------------------
// To test whether projection information is present, compare the getter's result
// against heif_omaf_image_projection_flat.
+//NEWAPI
LIBHEIF_API
heif_omaf_image_projection heif_image_handle_get_omaf_image_projection(const heif_image_handle* handle);
+//NEWAPI
LIBHEIF_API
heif_error heif_image_handle_set_omaf_image_projection(const heif_image_handle* handle, heif_omaf_image_projection image_projection);
diff --git a/libheif/api/libheif/heif_security.h b/libheif/api/libheif/heif_security.h
index 0777baa0..ef4bc319 100644
--- a/libheif/api/libheif/heif_security.h
+++ b/libheif/api/libheif/heif_security.h
@@ -72,10 +72,12 @@ typedef struct heif_security_limits
// --- version 4
+ //NEWAPI
uint32_t max_bad_pixels;
// --- version 5
+ //NEWAPI
// Internal: when libheif derives a limits struct from another one (e.g. to
// tighten the maximum image size for a specific decode), this points back to
// the registered context whose total-memory budget the allocation should be
diff --git a/libheif/api/libheif/heif_sequences.h b/libheif/api/libheif/heif_sequences.h
index 3637cba4..85480ff2 100644
--- a/libheif/api/libheif/heif_sequences.h
+++ b/libheif/api/libheif/heif_sequences.h
@@ -159,6 +159,7 @@ int heif_track_has_alpha_channel(const heif_track*);
LIBHEIF_API
uint32_t heif_track_get_timescale(const heif_track*);
+//NEWAPI
/**
* Special return value of `heif_track_get_number_of_repetitions()` indicating that
* the editlist requests indefinite repetition (the mvhd duration is the ISOBMFF
@@ -191,6 +192,7 @@ uint32_t heif_track_get_timescale(const heif_track*);
* timeline exactly once. Use the value returned by this function to decide how often
* to replay the track at the application level.
*/
+//NEWAPI
LIBHEIF_API
uint32_t heif_track_get_number_of_repetitions(const heif_track*);
diff --git a/libheif/api/libheif/heif_uncompressed.cc b/libheif/api/libheif/heif_uncompressed.cc
index bd07dd54..74f1be23 100644
--- a/libheif/api/libheif/heif_uncompressed.cc
+++ b/libheif/api/libheif/heif_uncompressed.cc
@@ -744,27 +744,37 @@ uint8_t* heif_image_get_component(heif_image* image, uint32_t component_idx, siz
}
+// Typed accessors: convert the internal byte stride to element count for the
+// public API. libheif's allocator pads rows to a 16-byte boundary (see
+// pixelimage.cc), which is a multiple of sizeof(T) for every supported T
+// (<= 16 bytes), so the division is always exact.
#define heif_image_get_component_X(name, type) \
const type* heif_image_get_component_ ## name ## _readonly(const struct heif_image* image, \
uint32_t component_idx, \
- size_t* out_stride) \
+ size_t* out_row_elements) \
{ \
if (!image || !image->image) { \
- if (out_stride) *out_stride = 0; \
+ if (out_row_elements) *out_row_elements = 0; \
return nullptr; \
} \
- return image->image->get_component_memory<type>(component_idx, out_stride); \
+ size_t byte_stride = 0; \
+ const type* p = image->image->get_component_memory<type>(component_idx, &byte_stride); \
+ if (out_row_elements) *out_row_elements = byte_stride / sizeof(type); \
+ return p; \
} \
\
type* heif_image_get_component_ ## name (struct heif_image* image, \
uint32_t component_idx, \
- size_t* out_stride) \
+ size_t* out_row_elements) \
{ \
if (!image || !image->image) { \
- if (out_stride) *out_stride = 0; \
+ if (out_row_elements) *out_row_elements = 0; \
return nullptr; \
} \
- return image->image->get_component_memory<type>(component_idx, out_stride); \
+ size_t byte_stride = 0; \
+ type* p = image->image->get_component_memory<type>(component_idx, &byte_stride); \
+ if (out_row_elements) *out_row_elements = byte_stride / sizeof(type); \
+ return p; \
}
heif_image_get_component_X(uint16, uint16_t)
diff --git a/libheif/api/libheif/heif_uncompressed.h b/libheif/api/libheif/heif_uncompressed.h
index 6808cf3a..e8489745 100644
--- a/libheif/api/libheif/heif_uncompressed.h
+++ b/libheif/api/libheif/heif_uncompressed.h
@@ -37,6 +37,7 @@ extern "C" {
// heif_uncompressed_component_type and heif_bayer_pattern_pixel are defined in heif_uncompressed_types.h.
+//NEWAPI
// Set a Bayer / filter array pattern on an image.
// The pattern is a 2D array of component indices with dimensions pattern_width x pattern_height.
// The number of entries in patternPixels must be pattern_width * pattern_height.
@@ -51,11 +52,13 @@ heif_error heif_image_set_bayer_pattern(heif_image*,
uint16_t pattern_height,
const heif_bayer_pattern_pixel* patternPixels);
+//NEWAPI
LIBHEIF_API
heif_error heif_image_add_bayer_component(heif_image*,
uint16_t component_type,
uint32_t* out_component_id);
+//NEWAPI
// Returns whether the image has a Bayer / filter array pattern.
// If the image has a pattern, out_pattern_width and out_pattern_height are set.
// Either output pointer may be NULL if the caller does not need that value.
@@ -65,6 +68,7 @@ int heif_image_get_bayer_pattern_size(const heif_image*,
uint16_t* out_pattern_width,
uint16_t* out_pattern_height);
+//NEWAPI
// Get the Bayer / filter array pattern pixels.
// The caller must provide an array large enough for pattern_width * pattern_height entries
// (use heif_image_get_bayer_pattern_size() to query the dimensions first).
@@ -80,14 +84,17 @@ heif_error heif_image_get_bayer_pattern(const heif_image*,
// On the wire this is the IEEE 754 bit pattern 0xFFFFFFFF (a signaling NaN).
// Test with heif_polarization_angle_is_no_filter() below, or with isnan()/std::isnan().
+//NEWAPI
// Returns a float with the 0xFFFFFFFF bit pattern (NaN) representing "no polarization filter".
LIBHEIF_API
float heif_polarization_angle_no_filter(void);
+//NEWAPI
// Returns non-zero if the given angle has the "no filter" bit pattern (0xFFFFFFFF).
LIBHEIF_API
int heif_polarization_angle_is_no_filter(float angle);
+//NEWAPI
// Add a polarization pattern to an image.
// component_indices: array of component indices this pattern applies to (may be NULL if num_component_indices == 0,
// meaning the pattern applies to all components).
@@ -102,10 +109,12 @@ heif_error heif_image_add_polarization_pattern(heif_image*,
uint16_t pattern_height,
const float* polarization_angles);
+//NEWAPI
// Returns the number of polarization patterns on this image (0 if none).
LIBHEIF_API
int heif_image_get_number_of_polarization_patterns(const heif_image*);
+//NEWAPI
// Get the sizes/dimensions of a polarization pattern (to allocate arrays for the data query).
LIBHEIF_API
heif_error heif_image_get_polarization_pattern_info(const heif_image*,
@@ -114,6 +123,7 @@ heif_error heif_image_get_polarization_pattern_info(const heif_image*,
uint16_t* out_pattern_width,
uint16_t* out_pattern_height);
+//NEWAPI
// Get the actual data of a polarization pattern.
// Caller must provide pre-allocated arrays:
// out_component_indices: num_component_indices entries (may be NULL if num_component_indices == 0)
@@ -124,6 +134,7 @@ heif_error heif_image_get_polarization_pattern_data(const heif_image*,
uint32_t* out_component_indices,
float* out_polarization_angles);
+//NEWAPI
// Find the polarization pattern index that applies to a given component index.
// Returns the pattern index (>= 0), or -1 if no pattern matches.
// A pattern with an empty component list (component_count == 0) matches all components.
@@ -136,6 +147,7 @@ int heif_image_get_polarization_pattern_index_for_component(const heif_image*,
// struct heif_bad_pixel is defined in heif_uncompressed_types.h.
+//NEWAPI
// Add a sensor bad pixels map to an image.
// component_indices: array of component indices this map applies to (may be NULL if num_component_indices == 0,
// meaning the map applies to all components).
@@ -152,10 +164,12 @@ heif_error heif_image_add_sensor_bad_pixels_map(heif_image*,
uint32_t num_bad_pixels,
const heif_bad_pixel* bad_pixels);
+//NEWAPI
// Returns the number of sensor bad pixels maps on this image (0 if none).
LIBHEIF_API
int heif_image_get_number_of_sensor_bad_pixels_maps(const heif_image*);
+//NEWAPI
// Get the sizes of a sensor bad pixels map (to allocate arrays for the data query).
LIBHEIF_API
heif_error heif_image_get_sensor_bad_pixels_map_info(const heif_image*,
@@ -166,6 +180,7 @@ heif_error heif_image_get_sensor_bad_pixels_map_info(const heif_image*,
uint32_t* out_num_bad_columns,
uint32_t* out_num_bad_pixels);
+//NEWAPI
// Get the actual data of a sensor bad pixels map.
// Caller must provide pre-allocated arrays:
// out_component_indices: num_component_indices entries (may be NULL if num_component_indices == 0)
@@ -183,6 +198,7 @@ heif_error heif_image_get_sensor_bad_pixels_map_data(const heif_image*,
// --- Sensor non-uniformity correction (ISO 23001-17, Section 6.1.6)
+//NEWAPI
// Add a sensor non-uniformity correction table to an image.
// component_indices: array of component indices this NUC applies to (may be NULL if num_component_indices == 0,
// meaning it applies to all components).
@@ -199,10 +215,12 @@ heif_error heif_image_add_sensor_nuc(heif_image*,
const float* nuc_gains,
const float* nuc_offsets);
+//NEWAPI
// Returns the number of sensor NUC tables on this image (0 if none).
LIBHEIF_API
int heif_image_get_number_of_sensor_nucs(const heif_image*);
+//NEWAPI
// Get the sizes of a sensor NUC table (to allocate arrays for the data query).
LIBHEIF_API
heif_error heif_image_get_sensor_nuc_info(const heif_image*,
@@ -212,6 +230,7 @@ heif_error heif_image_get_sensor_nuc_info(const heif_image*,
uint32_t* out_image_width,
uint32_t* out_image_height);
+//NEWAPI
// Get the actual data of a sensor NUC table.
// Caller must provide pre-allocated arrays:
// out_component_indices: num_component_indices entries (may be NULL if num_component_indices == 0)
@@ -229,15 +248,18 @@ heif_error heif_image_get_sensor_nuc_data(const heif_image*,
// --- Chroma sample location (ISO 23001-17, Section 6.1.4)
+//NEWAPI
// Set the chroma sample location on an image.
// chroma_location must be in the range 0-6 (see heif_chroma420_sample_location).
LIBHEIF_API
heif_error heif_image_set_chroma_location(heif_image*, uint8_t chroma_location);
+//NEWAPI
// Returns non-zero if the image has a chroma sample location set.
LIBHEIF_API
int heif_image_has_chroma_location(const heif_image*);
+//NEWAPI
// Returns the chroma sample location (0-6), or 0 if none is set.
LIBHEIF_API
uint8_t heif_image_get_chroma_location(const heif_image*);
@@ -287,30 +309,38 @@ heif_error heif_context_add_empty_unci_image(heif_context* ctx,
// --- index-based component access (for ISO 23001-17 multi-component images)
+//NEWAPI
// Returns the number of components that have pixel data (planes) in this image.
LIBHEIF_API
uint32_t heif_image_get_number_of_used_components(const heif_image*);
+//NEWAPI
// Fills `out_component_indices` with the valid component indices.
// The caller must allocate an array of at least heif_image_get_number_of_used_components() elements.
LIBHEIF_API
void heif_image_get_used_component_ids(const heif_image*, uint32_t* out_component_ids);
+//NEWAPI
LIBHEIF_API
heif_channel heif_image_get_component_channel(const heif_image*, uint32_t component_idx);
+//NEWAPI
LIBHEIF_API
uint32_t heif_image_get_component_width(const heif_image*, uint32_t component_idx);
+//NEWAPI
LIBHEIF_API
uint32_t heif_image_get_component_height(const heif_image*, uint32_t component_idx);
+//NEWAPI
LIBHEIF_API
int heif_image_get_component_bits_per_pixel(const heif_image*, uint32_t component_idx);
+//NEWAPI
LIBHEIF_API
uint16_t heif_image_get_component_type(const heif_image*, uint32_t component_idx);
+//NEWAPI
// Returns the datatype (unsigned/signed integer, floating point, or complex
// number) of the given component.
LIBHEIF_API
@@ -327,21 +357,26 @@ heif_component_datatype heif_image_get_component_datatype(const heif_image*, uin
// decoded, so the same numerical id can be used to address a component on
// either side of the API.
+//NEWAPI
LIBHEIF_API
uint32_t heif_image_handle_get_number_of_components(const heif_image_handle*);
+//NEWAPI
// Fills `out_component_ids` with the valid component IDs.
// The caller must allocate an array of at least
// heif_image_handle_get_number_of_components() elements.
LIBHEIF_API
void heif_image_handle_get_used_component_ids(const heif_image_handle*, uint32_t* out_component_ids);
+//NEWAPI
LIBHEIF_API
uint16_t heif_image_handle_get_component_type(const heif_image_handle*, uint32_t component_id);
+//NEWAPI
LIBHEIF_API
int heif_image_handle_get_component_bits_per_pixel(const heif_image_handle*, uint32_t component_id);
+//NEWAPI
LIBHEIF_API
heif_component_datatype heif_image_handle_get_component_datatype(const heif_image_handle*, uint32_t component_id);
@@ -349,6 +384,7 @@ heif_component_datatype heif_image_handle_get_component_datatype(const heif_imag
//LIBHEIF_API
//heif_error heif_image_get_component_indices_of_interleaved_channel(const heif_image* image, uint32_t* component_indices, uint8_t* nComponents_in_out);
+//NEWAPI
LIBHEIF_API
heif_error heif_image_add_component(heif_image* image,
int width, int height,
@@ -357,84 +393,111 @@ heif_error heif_image_add_component(heif_image* image,
int bit_depth,
uint32_t* out_component_idx);
-// All component-data getters return the row stride in bytes via out_stride
-// (regardless of the element type). When using a typed pointer for indexing,
-// divide the stride by sizeof(element).
+// Untyped uint8 component data getters: stride is in BYTES per row.
+//NEWAPI
LIBHEIF_API
const uint8_t* heif_image_get_component_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+//NEWAPI
LIBHEIF_API
uint8_t* heif_image_get_component(heif_image*, uint32_t component_idx, size_t* out_stride);
+// Typed component data getters: `out_row_elements` is the number of T elements
+// per row, not bytes. Index with `data[y * row_elements + x]` (no casts, no
+// sizeof). libheif allocates rows with element-aligned padding, so this count
+// is always exact for the named type T.
+//NEWAPI
LIBHEIF_API
-const uint16_t* heif_image_get_component_uint16_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const uint16_t* heif_image_get_component_uint16_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-uint16_t* heif_image_get_component_uint16(heif_image*, uint32_t component_idx, size_t* out_stride);
+uint16_t* heif_image_get_component_uint16(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const uint32_t* heif_image_get_component_uint32_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const uint32_t* heif_image_get_component_uint32_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-uint32_t* heif_image_get_component_uint32(heif_image*, uint32_t component_idx, size_t* out_stride);
+uint32_t* heif_image_get_component_uint32(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const uint64_t* heif_image_get_component_uint64_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const uint64_t* heif_image_get_component_uint64_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-uint64_t* heif_image_get_component_uint64(heif_image*, uint32_t component_idx, size_t* out_stride);
+uint64_t* heif_image_get_component_uint64(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const int8_t* heif_image_get_component_int8_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const int8_t* heif_image_get_component_int8_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-int8_t* heif_image_get_component_int8(heif_image*, uint32_t component_idx, size_t* out_stride);
+int8_t* heif_image_get_component_int8(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const int16_t* heif_image_get_component_int16_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const int16_t* heif_image_get_component_int16_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-int16_t* heif_image_get_component_int16(heif_image*, uint32_t component_idx, size_t* out_stride);
+int16_t* heif_image_get_component_int16(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const int32_t* heif_image_get_component_int32_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const int32_t* heif_image_get_component_int32_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-int32_t* heif_image_get_component_int32(heif_image*, uint32_t component_idx, size_t* out_stride);
+int32_t* heif_image_get_component_int32(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const int64_t* heif_image_get_component_int64_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const int64_t* heif_image_get_component_int64_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-int64_t* heif_image_get_component_int64(heif_image*, uint32_t component_idx, size_t* out_stride);
+int64_t* heif_image_get_component_int64(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const float* heif_image_get_component_float32_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const float* heif_image_get_component_float32_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-float* heif_image_get_component_float32(heif_image*, uint32_t component_idx, size_t* out_stride);
+float* heif_image_get_component_float32(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const double* heif_image_get_component_float64_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const double* heif_image_get_component_float64_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-double* heif_image_get_component_float64(heif_image*, uint32_t component_idx, size_t* out_stride);
+double* heif_image_get_component_float64(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const heif_complex32* heif_image_get_component_complex32_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const heif_complex32* heif_image_get_component_complex32_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-heif_complex32* heif_image_get_component_complex32(heif_image*, uint32_t component_idx, size_t* out_stride);
+heif_complex32* heif_image_get_component_complex32(heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-const heif_complex64* heif_image_get_component_complex64_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);
+const heif_complex64* heif_image_get_component_complex64_readonly(const heif_image*, uint32_t component_idx, size_t* out_row_elements);
+//NEWAPI
LIBHEIF_API
-heif_complex64* heif_image_get_component_complex64(heif_image*, uint32_t component_idx, size_t* out_stride);
+heif_complex64* heif_image_get_component_complex64(heif_image*, uint32_t component_idx, size_t* out_row_elements);
// --- GIMI component content IDs (set before encoding)
+//NEWAPI
// Set a GIMI component content ID for the component with the given
// component_id (as minted by heif_image_add_component / returned via the
// component access API). Pass an empty string to clear a previously set id.
diff --git a/libheif/api/libheif/heif_uncompressed_types.h b/libheif/api/libheif/heif_uncompressed_types.h
index 3601e853..73274519 100644
--- a/libheif/api/libheif/heif_uncompressed_types.h
+++ b/libheif/api/libheif/heif_uncompressed_types.h
@@ -29,6 +29,7 @@ extern "C" {
// --- ISO 23001-17 component types (Table 1)
+//NEWAPI
typedef enum heif_unci_component_type
{
heif_unci_component_type_monochrome = 0,
@@ -53,6 +54,7 @@ typedef enum heif_unci_component_type
// --- Bayer / filter array pattern
+//NEWAPI
typedef struct heif_bayer_pattern_pixel
{
uint32_t component_id;
@@ -62,11 +64,13 @@ typedef struct heif_bayer_pattern_pixel
// --- Sensor bad pixels map (ISO 23001-17, Section 6.1.7)
+//NEWAPI
struct heif_bad_pixel { uint32_t row; uint32_t column; };
// --- Chroma sample location (ISO 23091-2 / ITU-T H.273 + ISO 23001-17)
+//NEWAPI
typedef enum heif_chroma420_sample_location {
// values 0-5 according to ISO 23091-2 / ITU-T H.273
heif_chroma420_sample_location_00_05 = 0,
@@ -121,6 +125,7 @@ typedef struct heif_unci_image_parameters
// component_format byte (used by the uncC box of the uncompressed codec).
// This is an internal convenience and should not be relied upon.
+//NEWAPI
typedef enum heif_component_datatype
{
heif_component_datatype_unsigned_integer = 0,
@@ -130,11 +135,13 @@ typedef enum heif_component_datatype
heif_component_datatype_undefined = 0xFF
} heif_component_datatype;
+//NEWAPI
typedef struct heif_complex32
{
float real, imaginary;
} heif_complex32;
+//NEWAPI
typedef struct heif_complex64
{
double real, imaginary;
diff --git a/tests/uncompressed_encode_multicomponent.cc b/tests/uncompressed_encode_multicomponent.cc
index 3d39926a..a8fc754b 100644
--- a/tests/uncompressed_encode_multicomponent.cc
+++ b/tests/uncompressed_encode_multicomponent.cc
@@ -260,7 +260,6 @@ static heif_image* create_and_fill_image(heif_component_datatype datatype, int b
size_t stride = 0;
T* data = get_component_ptr<T>(image, id, &stride);
REQUIRE(data != nullptr);
- stride /= sizeof(T);
REQUIRE(stride >= kWidth);
for (uint32_t y = 0; y < kHeight; y++) {
@@ -322,7 +321,6 @@ static void verify_image_data(const heif_image* image)
size_t stride = 0;
const T* data = get_component_ptr_readonly<T>(image, c, &stride);
REQUIRE(data != nullptr);
- stride /= sizeof(T);
for (uint32_t y = 0; y < kHeight; y++) {
for (uint32_t x = 0; x < kWidth; x++) {
@@ -473,7 +471,6 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
size_t stride = 0;
uint16_t* data = heif_image_get_component_uint16(image, idx0, &stride);
REQUIRE(data != nullptr);
- stride /= sizeof(uint16_t);
for (uint32_t y = 0; y < kH; y++) {
for (uint32_t x = 0; x < kW; x++) {
data[y * stride + x] = static_cast<uint16_t>(y * kW + x + 100);
@@ -486,7 +483,6 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
size_t stride = 0;
uint16_t* data = heif_image_get_component_uint16(image, idx1, &stride);
REQUIRE(data != nullptr);
- stride /= sizeof(uint16_t);
for (uint32_t y = 0; y < kH; y++) {
for (uint32_t x = 0; x < kW; x++) {
data[y * stride + x] = static_cast<uint16_t>((y * kW + x + 200) & kMaxVal14);
@@ -532,7 +528,6 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
size_t stride = 0;
const uint16_t* data = heif_image_get_component_uint16_readonly(decoded, idx0, &stride);
REQUIRE(data != nullptr);
- stride /= sizeof(uint16_t);
for (uint32_t y = 0; y < kH; y++) {
for (uint32_t x = 0; x < kW; x++) {
uint16_t expected = static_cast<uint16_t>(y * kW + x + 100);
@@ -547,7 +542,6 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
size_t stride = 0;
const uint16_t* data = heif_image_get_component_uint16_readonly(decoded, idx1, &stride);
REQUIRE(data != nullptr);
- stride /= sizeof(uint16_t);
for (uint32_t y = 0; y < kH; y++) {
for (uint32_t x = 0; x < kW; x++) {
uint16_t expected = static_cast<uint16_t>((y * kW + x + 200) & kMaxVal14);