Commit 724ad426 for libheif
commit 724ad42638c025993a0de8b53b180e465397c500
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Mon May 18 21:17:15 2026 +0200
since image memory is now zero filled on allocation, we can remove zeroing broken tiles
diff --git a/libheif/image-items/grid.cc b/libheif/image-items/grid.cc
index 18e7bab4..b6a68bc1 100644
--- a/libheif/image-items/grid.cc
+++ b/libheif/image-items/grid.cc
@@ -310,7 +310,6 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
int progress_counter = 0;
bool cancelled = false;
std::shared_ptr<std::vector<Error> > warnings(new std::vector<Error>());
- std::vector<FailedTile> failed_tiles;
for (uint32_t y = 0; y < grid.get_rows() && !cancelled; y++) {
uint32_t x0 = 0;
@@ -327,7 +326,6 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
heif_error_Invalid_input,
heif_suberror_Missing_grid_images,
});
- failed_tiles.push_back({x0, y0});
reference_idx++;
x0 += tile_width;
continue;
@@ -341,7 +339,6 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
if (!options.strict_decoding && reference_idx != 0) {
// Skip missing tiles (unless it's the first one).
warnings->push_back(error);
- failed_tiles.push_back({x0, y0});
reference_idx++;
x0 += tile_width;
continue;
@@ -391,7 +388,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
}
}
- err = decode_and_paste_tile_image(tileID, x0, y0, img, options, progress_counter, warnings, failed_tiles, processed_ids);
+ err = decode_and_paste_tile_image(tileID, x0, y0, img, options, progress_counter, warnings, processed_ids);
if (err) {
return err;
}
@@ -439,7 +436,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
errs.push_back(std::async(std::launch::async,
&ImageItem_Grid::decode_and_paste_tile_image, this,
data.tileID, data.x_origin, data.y_origin, std::ref(img), options,
- std::ref(progress_counter), warnings, std::ref(failed_tiles), processed_ids));
+ std::ref(progress_counter), warnings, processed_ids));
}
// check for decoding errors in remaining tiles
@@ -464,9 +461,6 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
}
if (img) {
- for (const auto& tile : failed_tiles) {
- img->zero_region(tile.x0, tile.y0, tile_width, tile_height);
- }
img->add_warnings(*warnings.get());
}
@@ -490,26 +484,24 @@ Error ImageItem_Grid::decode_and_paste_tile_image(heif_item_id tileID, uint32_t
const heif_decoding_options& options,
int& progress_counter,
std::shared_ptr<std::vector<Error> > warnings,
- std::vector<FailedTile>& failed_tiles,
std::set<heif_item_id> processed_ids) const
{
std::shared_ptr<HeifPixelImage> tile_img;
#if ENABLE_PARALLEL_TILE_DECODING
- static std::mutex failedTilesMutex;
+ static std::mutex warningsMutex;
#endif
auto tileItem = get_context()->get_image(tileID, true);
if (!tileItem && !options.strict_decoding) {
- // We ignore missing images.
+ // We ignore missing images. The un-pasted canvas region stays zero from calloc().
#if ENABLE_PARALLEL_TILE_DECODING
- std::lock_guard<std::mutex> lock(failedTilesMutex);
+ std::lock_guard<std::mutex> lock(warningsMutex);
#endif
warnings->emplace_back(
heif_error_Invalid_input,
heif_suberror_Missing_grid_images,
"Missing grid image"
);
- failed_tiles.push_back({x0, y0});
return progress_and_return_ok(options, progress_counter);
}
@@ -521,12 +513,11 @@ Error ImageItem_Grid::decode_and_paste_tile_image(heif_item_id tileID, uint32_t
auto decodeResult = tileItem->decode_image(options, false, 0, 0, processed_ids);
if (!decodeResult) {
if (!options.strict_decoding) {
- // We ignore broken tiles.
+ // We ignore broken tiles. The un-pasted canvas region stays zero from calloc().
#if ENABLE_PARALLEL_TILE_DECODING
- std::lock_guard<std::mutex> lock(failedTilesMutex);
+ std::lock_guard<std::mutex> lock(warningsMutex);
#endif
warnings->push_back(decodeResult.error());
- failed_tiles.push_back({x0, y0});
return progress_and_return_ok(options, progress_counter);
}
diff --git a/libheif/image-items/grid.h b/libheif/image-items/grid.h
index 37021464..3e6f9052 100644
--- a/libheif/image-items/grid.h
+++ b/libheif/image-items/grid.h
@@ -170,17 +170,10 @@ private:
Result<std::shared_ptr<HeifPixelImage>> decode_grid_tile(const heif_decoding_options& options, uint32_t tx, uint32_t ty, std::set<heif_item_id> processed_ids) const;
- struct FailedTile {
- // Top-left pixel coordinates
- uint32_t x0;
- uint32_t y0;
- };
-
Error decode_and_paste_tile_image(heif_item_id tileID, uint32_t x0, uint32_t y0,
std::shared_ptr<HeifPixelImage>& inout_image,
const heif_decoding_options& options, int& progress_counter,
std::shared_ptr<std::vector<Error> > warnings,
- std::vector<FailedTile>& failed_tiles,
std::set<heif_item_id> processed_ids) const;
};
diff --git a/libheif/image/pixelimage.cc b/libheif/image/pixelimage.cc
index ba06fc0a..7827032b 100644
--- a/libheif/image/pixelimage.cc
+++ b/libheif/image/pixelimage.cc
@@ -1150,41 +1150,6 @@ Error HeifPixelImage::copy_image_to(const std::shared_ptr<const HeifPixelImage>&
}
-void HeifPixelImage::zero_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h)
-{
- uint32_t img_w = get_width();
- uint32_t img_h = get_height();
- heif_chroma chroma = get_chroma_format();
-
- std::set<enum heif_channel> channels = get_channel_set();
-
- for (heif_channel channel : channels) {
- uint32_t cx0 = channel_width(x0, chroma, channel);
- uint32_t cy0 = channel_height(y0, chroma, channel);
- uint32_t cw = channel_width(w, chroma, channel);
- uint32_t ch = channel_height(h, chroma, channel);
-
- // clamp to plane bounds
- uint32_t plane_w = channel_width(img_w, chroma, channel);
- uint32_t plane_h = channel_height(img_h, chroma, channel);
- if (cx0 >= plane_w || cy0 >= plane_h) {
- continue;
- }
- cw = std::min(cw, plane_w - cx0);
- ch = std::min(ch, plane_h - cy0);
-
- size_t stride = 0;
- uint8_t* data = get_channel_memory(channel, &stride);
- uint32_t bytes_per_pixel = get_storage_bits_per_pixel(channel) / 8;
- size_t width_bytes = static_cast<size_t>(cw) * bytes_per_pixel;
-
- for (uint32_t y = 0; y < ch; y++) {
- memset(data + static_cast<size_t>(cx0) * bytes_per_pixel + (cy0 + y) * stride, 0, width_bytes);
- }
- }
-}
-
-
Result<std::shared_ptr<HeifPixelImage>> HeifPixelImage::rotate_ccw(int angle_degrees, const heif_security_limits* limits)
{
// TODO: Bayer pattern, polarization patterns and sensor maps reference
diff --git a/libheif/image/pixelimage.h b/libheif/image/pixelimage.h
index 8f1bbdf3..e33d9f66 100644
--- a/libheif/image/pixelimage.h
+++ b/libheif/image/pixelimage.h
@@ -274,8 +274,6 @@ public:
Error copy_image_to(const std::shared_ptr<const HeifPixelImage>& source, uint32_t x0, uint32_t y0);
- void zero_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h);
-
Result<std::shared_ptr<HeifPixelImage>> rotate_ccw(int angle_degrees, const heif_security_limits* limits);
Result<std::shared_ptr<HeifPixelImage>> mirror_inplace(heif_transform_mirror_direction, const heif_security_limits* limits);