Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ Release 3.2 (target: Sept 2026?) -- compared to 3.1
* *ImageCache/TextureSystem*:
- *api/TS*: `IBA::make_texture()` now honors "maketx:threads" hint [#5014](https://github.com/AcademySoftwareFoundation/OpenImageIO/pull/5014) (3.2.0.0, 3.1.10.0)
* New global attribute queries via OIIO::getattribute():
- `limits:resolution` (default: 1048576) is a new settable/queryable global
attribute that caps the maximum number of pixels along any single image
dimension. `ImageInput::check_open` rejects files exceeding it. This
complements `limits:imagesize_MB` to catch corrupt headers that are tiny
in one dimension but absurdly large in another, which can defeat the
total-pixel-memory check.
* Miscellaneous API changes:
- *api*: Versioned namespace to preserve ABI compatibility between minor releases [#4869](https://github.com/AcademySoftwareFoundation/OpenImageIO/pull/4869) (3.2.0.0)
- *fmath.h*: `degrees()` and `radians()` are now `constexpr`. [#5151](https://github.com/AcademySoftwareFoundation/OpenImageIO/pull/5151) (3.2.0.1, 3.1.13.0)
Expand Down
14 changes: 14 additions & 0 deletions src/include/OpenImageIO/imageio.h
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,8 @@ class OIIO_API ImageInput {
/// implied by `range`.
/// * Whether the channel count is within the `"limits:channels"` OIIO
/// attribute.
/// * Whether any single dimension (width, height, depth) is within the
/// `"limits:resolution"` OIIO attribute.
/// * The total uncompressed pixel data size is expected to be within the
/// `"limits:imagesize_MB"` OIIO attribute.
/// * The full_{width,height,depth} are valid and within the range.
Expand Down Expand Up @@ -3904,6 +3906,18 @@ OIIO_API std::string geterror(bool clear = true);
/// you should raise this limit. Setting the limit to 0 means having no
/// limit.
///
/// - `int limits:resolution` (1048576)
///
/// When nonzero, the maximum number of pixels allowed along any single
/// dimension (width, height, or depth) of an image. Images whose headers
/// indicate a larger dimension might be assumed to be corrupted or
/// malicious files. This complements `limits:imagesize_MB` by catching a
/// header that is small in one dimension but absurdly large in another,
/// which could otherwise slip under the total-size limit. The default is
/// 1048576 (2^20). In situations when images with a larger single
/// dimension are expected to be encountered, you should raise this limit.
/// Setting the limit to 0 means having no limit. (Added in version 3.2.)
///
/// - `int log_times` (0)
///
/// When the `"log_times"` attribute is nonzero, `ImageBufAlgo` functions
Expand Down
1 change: 1 addition & 0 deletions src/include/imageio_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern int png_linear_premult;
extern int enable_hwy;
extern int limit_channels;
extern int limit_imagesize_MB;
extern int limit_resolution;
extern int imagebuf_print_uncaught_errors;
extern int imagebuf_use_imagecache;
extern int imageinput_strict;
Expand Down
17 changes: 17 additions & 0 deletions src/libOpenImageIO/imageinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,23 @@ ImageInput::check_open(const ImageSpec& spec, ROI range, uint64_t /*flags*/)
spec.nchannels, OIIO::pvt::limit_channels);
return false;
}
if (OIIO::pvt::limit_resolution
&& (spec.width > OIIO::pvt::limit_resolution
|| spec.height > OIIO::pvt::limit_resolution
|| spec.depth > OIIO::pvt::limit_resolution)) {
if (spec.depth > 1) {
errorfmt(
"{} image dimension {}x{}x{} exceeds \"limits:resolution\" = {} for a single dimension. Possible corrupt input?\nIf you're sure this is a valid file, raise the OIIO global attribute \"limits:resolution\".",
format_name(), spec.width, spec.height, spec.depth,
OIIO::pvt::limit_resolution);
} else {
errorfmt(
"{} image dimension {}x{} exceeds \"limits:resolution\" = {} for a single dimension. Possible corrupt input?\nIf you're sure this is a valid file, raise the OIIO global attribute \"limits:resolution\".",
format_name(), spec.width, spec.height,
OIIO::pvt::limit_resolution);
}
return false;
}
if (OIIO::pvt::limit_imagesize_MB
&& spec.image_bytes(true)
> OIIO::pvt::limit_imagesize_MB * imagesize_t(1024 * 1024)) {
Expand Down
9 changes: 9 additions & 0 deletions src/libOpenImageIO/imageio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ int enable_hwy = 0; // Not enabled at build time
int limit_channels(1024);
int limit_imagesize_MB(std::min(32 * 1024,
int(Sysutil::physical_memory() >> 20)));
int limit_resolution(1 << 20); // max pixels along any single dimension
int imageinput_strict(0);
ustring font_searchpath(Sysutil::getenv("OPENIMAGEIO_FONTS"));
ustring plugin_searchpath(OIIO_DEFAULT_PLUGIN_SEARCHPATH);
Expand Down Expand Up @@ -431,6 +432,10 @@ attribute(string_view name, TypeDesc type, const void* val)
limit_imagesize_MB = *(const int*)val;
return true;
}
if (name == "limits:resolution" && type == TypeInt) {
limit_resolution = *(const int*)val;
return true;
}
if (name == "oiio:print_uncaught_errors" && type == TypeInt) {
oiio_print_uncaught_errors = *(const int*)val;
return true;
Expand Down Expand Up @@ -625,6 +630,10 @@ getattribute(string_view name, TypeDesc type, void* val)
*(int*)val = limit_imagesize_MB;
return true;
}
if (name == "limits:resolution" && type == TypeInt) {
*(int*)val = limit_resolution;
return true;
}
if (name == "tiff:multithread" && type == TypeInt) {
*(int*)val = tiff_multithread;
return true;
Expand Down
1 change: 1 addition & 0 deletions testsuite/oiiotool-control/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ oiiotool ERROR: -set : Invalid variable name "3"
Full command line was:
> oiiotool -echo "This should make an error:" -set 3 5
Expr getattribute(limits:channels) = 1024
Expr getattribute(limits:resolution) = 1.04858e+06
Testing if with true cond (expect output):
inside if clause, i=42
done
Expand Down
1 change: 1 addition & 0 deletions testsuite/oiiotool-control/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@

# Test getattribute in an expression
command += oiiotool ('-echo "Expr getattribute(\"limits:channels\") = {getattribute(\"limits:channels\")}"')
command += oiiotool ('-echo "Expr getattribute(\"limits:resolution\") = {getattribute(\"limits:resolution\")}"')

# Test --if --else --endif
command += oiiotool ('-echo "Testing if with true cond (expect output):" -set i 42 -if "{i}" -echo " inside if clause, i={i}" -endif -echo " done" -echo " "')
Expand Down
Loading