Skip to content
Merged
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
7 changes: 6 additions & 1 deletion src/cineon.imageio/cineoninput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@ CineonInput::open(const std::string& name, ImageSpec& newspec)
m_stream = new InStream();
if (!m_stream->Open(name.c_str())) {
errorfmt("Could not open file \"{}\"", name);
close();
return false;
}

m_cin.SetInStream(m_stream);
if (!m_cin.ReadHeader()) {
errorfmt("Could not read header");
close();
return false;
}

Expand Down Expand Up @@ -126,7 +128,10 @@ CineonInput::open(const std::string& name, ImageSpec& newspec)
case 2: typedesc = TypeDesc::UINT16; break;
case 3:
case 4: typedesc = TypeDesc::UINT32; break;
default: errorfmt("Unsupported bit depth {}", maxbits); return false;
default:
errorfmt("Unsupported bit depth {}", maxbits);
close();
return false;
}
m_spec = ImageSpec(m_cin.header.Width(), m_cin.header.Height(), nchannels,
typedesc);
Expand Down
17 changes: 14 additions & 3 deletions src/dds.imageio/ddsinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,10 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
ioseek(0);

static_assert(sizeof(dds_header) == 128, "dds header size does not match");
if (!ioread(&m_dds, sizeof(m_dds), 1))
if (!ioread(&m_dds, sizeof(m_dds), 1)) {
close();
return false;
}

if (bigendian()) {
// DDS files are little-endian
Expand Down Expand Up @@ -481,6 +483,7 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
|| (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP
&& !(m_dds.caps.flags1 & DDS_CAPS1_COMPLEX))) {
errorfmt("Invalid DDS header, possibly corrupt file");
close();
return false;
}

Expand All @@ -494,13 +497,16 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
& (DDS_PF_RGB | DDS_PF_LUMINANCE | DDS_PF_ALPHA
| DDS_PF_ALPHAONLY)))) {
errorfmt("Image with no data");
close();
return false;
}

// read optional DX10 header
if (m_dds.fmt.fourCC == DDS_4CC_DX10) {
if (!ioread(&m_dx10, sizeof(m_dx10), 1))
if (!ioread(&m_dx10, sizeof(m_dx10), 1)) {
close();
return false;
}

/*std::cerr << "[dds:dx10] dxgiFormat: " << m_dx10.dxgiFormat << "\n";
std::cerr << "[dds:dx10] resourceDimension: " << m_dx10.resourceDimension << "\n";
Expand Down Expand Up @@ -557,13 +563,15 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
if (!GetDxgiFormatChannelMasks(m_dx10.dxgiFormat,
m_dds.fmt.masks)) {
errorfmt("Unsupported DXGI format: {}", m_dx10.dxgiFormat);
close();
return false;
}
break;
}
} break;
default:
errorfmt("Unsupported compression type: {}", m_dds.fmt.fourCC);
close();
return false;
}
}
Expand Down Expand Up @@ -627,6 +635,7 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
if (m_compression == Compression::None && (m_Bpp < 1 || m_Bpp > 16)) {
errorfmt("Invalid DDS bytes-per-pixel ({}). Possible corrupt input?",
m_Bpp);
close();
return false;
}

Expand All @@ -648,8 +657,10 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
} else
m_nfaces = 1;

if (!seek_subimage(0, 0))
if (!seek_subimage(0, 0)) {
close();
return false;
}
newspec = spec();
return true;
}
Expand Down
6 changes: 5 additions & 1 deletion src/dicom.imageio/dicominput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ DICOMInput::open(const std::string& name, ImageSpec& newspec,

bool ok = seek_subimage(0, 0);
newspec = spec();
return ok;
if (!ok) {
close();
return false;
}
return true;
}


Expand Down
1 change: 1 addition & 0 deletions src/dpx.imageio/dpxinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ DPXInput::open(const std::string& name, ImageSpec& newspec)
m_stream = new InStream(ioproxy());
if (!m_stream) {
errorfmt("Could not open file \"{}\"", name);
close();
return false;
}

Expand Down
10 changes: 10 additions & 0 deletions src/ffmpeg.imageio/ffmpeginput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
}
if (!valid_extension) {
errorfmt("\"{}\" could not open input", name);
close();
return false;
}

Expand All @@ -241,10 +242,12 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
if (avformat_open_input(&m_format_context, file_name, NULL, NULL) != 0) {
// avformat_open_input allocs format_context
errorfmt("\"{}\" could not open input", file_name);
close();
return false;
}
if (avformat_find_stream_info(m_format_context, NULL) < 0) {
errorfmt("\"{}\" could not find stream info", file_name);
close();
return false;
}
m_video_stream = -1;
Expand All @@ -259,6 +262,7 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
}
if (m_video_stream == -1) {
errorfmt("\"{}\" could not find a valid videostream", file_name);
close();
return false;
}
for (unsigned int i = 0; i < m_format_context->nb_streams; i++) {
Expand All @@ -276,12 +280,14 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
m_codec = avcodec_find_decoder(par->codec_id);
if (!m_codec) {
errorfmt("\"{}\" can't find decoder", file_name);
close();
return false;
}

m_codec_context = avcodec_alloc_context3(m_codec);
if (!m_codec_context) {
errorfmt("\"{}\" can't allocate decoder context", file_name);
close();
return false;
}

Expand All @@ -290,11 +296,13 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
ret = avcodec_parameters_to_context(m_codec_context, par);
if (ret < 0) {
errorfmt("\"{}\" unsupported codec", file_name);
close();
return false;
}

if (avcodec_open2(m_codec_context, m_codec, NULL) < 0) {
errorfmt("\"{}\" could not open codec", file_name);
close();
return false;
}
if (!strcmp(m_codec_context->codec->name, "mjpeg")
Expand Down Expand Up @@ -497,6 +505,7 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
m_codec_context->height, ffmpeg_image_align);
if (rgb_buffer_size <= 0) {
errorfmt("\"{}\" invalid FFmpeg RGB buffer size", file_name);
close();
return false;
}
m_rgb_buffer.resize(static_cast<size_t>(rgb_buffer_size), 0);
Expand All @@ -508,6 +517,7 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
NULL, NULL, NULL);
if (!m_sws_rgb_context) {
errorfmt("\"{}\" could not create FFmpeg scaling context", file_name);
close();
return false;
}

Expand Down
9 changes: 7 additions & 2 deletions src/fits.imageio/fitsinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,19 @@ FitsInput::open(const std::string& name, ImageSpec& spec)
// moving back to the start of the file
if (Filesystem::fseek(m_fd, 0, SEEK_SET)) {
errorfmt("Seek error");
close();
return false;
}

if (!subimage_search())
if (!subimage_search()) {
close();
return false;
}

if (!set_spec_info())
if (!set_spec_info()) {
close();
return false;
}

spec = m_spec;
return true;
Expand Down
5 changes: 5 additions & 0 deletions src/heif.imageio/heifinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,19 @@ HeifInput::open(const std::string& name, ImageSpec& newspec,
} catch (const heif::Error& err) {
std::string e = err.get_message();
errorfmt("{}", e.empty() ? "unknown exception" : e.c_str());
close();
return false;
} catch (const std::exception& err) {
std::string e = err.what();
errorfmt("{}", e.empty() ? "unknown exception" : e.c_str());
close();
return false;
}

bool ok = seek_subimage(0, 0);
newspec = spec();
if (!ok)
close();
return ok;
}

Expand All @@ -226,6 +230,7 @@ HeifInput::close()
m_ihandle = heif::ImageHandle();
m_ctx.reset();
m_reader.reset();
m_item_ids.clear();
m_subimage = -1;
m_num_subimages = 0;
m_associated_alpha = true;
Expand Down
5 changes: 4 additions & 1 deletion src/ico.imageio/icoinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,10 @@ ICOInput::open(const std::string& name, ImageSpec& newspec,

ioseek(0);

if (!ioread(&m_ico, 1, sizeof(m_ico)))
if (!ioread(&m_ico, 1, sizeof(m_ico))) {
close();
return false;
}

if (bigendian()) {
// ICOs are little endian
Expand All @@ -148,6 +150,7 @@ ICOInput::open(const std::string& name, ImageSpec& newspec,
}
if (m_ico.reserved != 0 || m_ico.type != 1) {
errorfmt("File failed ICO header check");
close();
return false;
}

Expand Down
4 changes: 3 additions & 1 deletion src/iff.imageio/iffinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,10 @@ IffInput::open(const std::string& name, ImageSpec& spec)

// Validity check resolutions and check for decompression bombs.
if (!check_open(m_spec, { 0, 1 << 16, 0, 1 << 16, 0, 1, 0, 5 })
|| !check_compression_ratio(m_spec, ioproxy()->size()))
|| !check_compression_ratio(m_spec, ioproxy()->size())) {
close();
return false;
}

spec = m_spec;
return true;
Expand Down
8 changes: 8 additions & 0 deletions src/include/OpenImageIO/imageio.h
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,11 @@ class OIIO_API ImageInput {
///
/// @returns
/// `true` if the file was found and opened successfully.
///
/// If `open()` returns `false`, the ImageInput will be left in the same
/// state as a newly constructed, unopened ImageInput (as if `close()` had
/// been called). Callers may assume this and are not responsible for
/// calling `close()` after a failed `open()`.
OIIO_NODISCARD_ERROR virtual bool open (const std::string& name,
ImageSpec &newspec) = 0;

Expand Down Expand Up @@ -1208,6 +1213,9 @@ class OIIO_API ImageInput {
///
/// @returns
/// `true` if the file was found and opened successfully.
///
/// Same close-on-failure contract as `open(name,newspec)`: a `false`
/// return must leave the ImageInput as if `close()` had been called.
OIIO_NODISCARD_ERROR virtual bool open (const std::string& name,
ImageSpec &newspec,
const ImageSpec& config OIIO_MAYBE_UNUSED) {
Expand Down
20 changes: 16 additions & 4 deletions src/jpeg.imageio/jpeginput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)
std::string proxytype = m_io->proxytype();
if (proxytype != "file" && proxytype != "memreader") {
errorfmt("JPEG reader can't handle proxy type {}", proxytype);
close();
return false;
}

Expand Down Expand Up @@ -266,6 +267,7 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)
// read the file parameters
if (jpeg_read_header(&m_cinfo, FALSE) != JPEG_HEADER_OK || m_fatalerr) {
errorfmt("Bad JPEG header for \"{}\"", filename());
close();
return false;
}

Expand All @@ -287,21 +289,27 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)
TypeDesc::UINT8);

// Validity check resolutions.
if (!check_open(m_spec, { 0, 1 << 16, 0, 1 << 16, 0, 1, 0, 3 }))
if (!check_open(m_spec, { 0, 1 << 16, 0, 1 << 16, 0, 1, 0, 3 })) {
close();
return false;
}

// check_open's size cap still admits dimensions that are absurd for a tiny
// file, so also bound the declared-vs-compressed ratio.
imagesize_t filesize = m_io ? m_io->size() : Filesystem::file_size(name);
if (!check_compression_ratio(m_spec, filesize))
if (!check_compression_ratio(m_spec, filesize)) {
close();
return false;
}

if (m_raw)
m_coeffs = jpeg_read_coefficients(&m_cinfo);
else
jpeg_start_decompress(&m_cinfo); // start working
if (m_fatalerr)
if (m_fatalerr) {
close();
return false;
}
m_next_scanline = 0; // next scanline we'll read

// The output dimensions ought to match the header's, but re-validate if
Expand All @@ -311,8 +319,10 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)
m_spec = ImageSpec(m_cinfo.output_width, m_cinfo.output_height,
nchannels, TypeDesc::UINT8);
if (!check_open(m_spec, { 0, 1 << 16, 0, 1 << 16, 0, 1, 0, 3 })
|| !check_compression_ratio(m_spec, filesize))
|| !check_compression_ratio(m_spec, filesize)) {
close();
return false;
}
}

// Assume JPEG is in sRGB unless the Exif or XMP tags say otherwise.
Expand Down Expand Up @@ -342,6 +352,7 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)
bool ok = decode_exif(exif, m_spec);
if (!ok && OIIO::get_int_attribute("imageinput:strict")) {
errorfmt("Could not decode Exif");
close();
return false;
}
scan_for_thumbnail(exif);
Expand All @@ -356,6 +367,7 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)
string_view((const char*)m->data, m->data_length));
if (!ok && OIIO::get_int_attribute("imageinput:strict")) {
errorfmt("Corrupted IPTC data");
close();
return false;
}
} else if (m->marker == JPEG_COM) {
Expand Down
1 change: 1 addition & 0 deletions src/jpeg2000.imageio/jpeg2000input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ Jpeg2000Input::open(const std::string& name, ImageSpec& p_spec)
if (!ok && OIIO::get_int_attribute("imageinput:strict")) {
errorfmt("Possible corrupt file, could not decode ICC profile: {}\n",
errormsg);
close();
return false;
}
}
Expand Down
Loading
Loading