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
4 changes: 4 additions & 0 deletions src/dds.imageio/ddsinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,10 @@ DDSInput::seek_subimage(int subimage, int miplevel)

m_subimage = subimage;
m_miplevel = miplevel;

if ((m_dds.flags & DDS_MIPMAPCOUNT) && (int)m_dds.mipmaps > 1)
m_spec.attribute("oiio:miplevels", (int)m_dds.mipmaps);

return true;
}

Expand Down
12 changes: 12 additions & 0 deletions src/doc/builtinplugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ red & green channels).
- string
- For environment maps, which cube faces are present (e.g., ``"+x -x
+y -y"`` if *x* & *y* faces are present, but not *z*).
* - ``oiio:miplevels``
- int
- The number of MIP levels, only for MIP-mapped files with more than
one level.

```

Expand Down Expand Up @@ -1660,6 +1664,10 @@ The official OpenEXR site is <http://www.openexr.com/>.
* - ``oiio:subimages``
- int
- The number of "parts" (subimages) in the file.
* - ``oiio:miplevels``
- int
- The number of MIP levels of the part (subimage), only for MIP-mapped
parts with more than one level.
* - ``smpte:TimeCode``
- int[2]
- SMPTE time code (vecsemantics will be marked as TIMECODE)
Expand Down Expand Up @@ -2271,6 +2279,10 @@ Ptex files at all.
* - ``wrapmode``
- string
- the wrap mode as specified by the Ptex file.
* - ``oiio:miplevels``
- int
- The number of MIP levels of the face (subimage), only when the face
has more than one level.
* - *other*
-
- Any other arbitrary metadata in the Ptex file will be stored directly
Expand Down
8 changes: 8 additions & 0 deletions src/doc/stdmetadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ OpenImageIO understands.
to find out how many there are.
```

```{eval-rst}
.. option:: "oiio:miplevels" : int

The number of MIP levels of the subimage, only present for images
stored in a MIP-mapped layout with more than one MIP level, and absent
for non-MIP-mapped images.
```

```{eval-rst}
.. option:: "oiio:SourcePath" : string
"oiio:SourceFileFormat" : string
Expand Down
3 changes: 2 additions & 1 deletion src/include/OpenImageIO/imagebuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,8 @@ class OIIO_API ImageBuf {
/// Return the number of MIP levels of the current subimage within the
/// file this ImageBuf refers to. This will always be 1 for an ImageBuf
/// that was not constructed as a direct reference to a file, or if this
/// subimage within the file was not MIP-mapped.
/// subimage within the file was not MIP-mapped. A return value of 0
/// indicates an error.
int nmiplevels() const;

/// Return the number of color channels in the image. This is equivalent
Expand Down
20 changes: 18 additions & 2 deletions src/libOpenImageIO/imagebuf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,8 @@ ImageBufImpl::ImageBufImpl(const ImageBufImpl& src)
m_nmiplevels = 0;
m_spec.erase_attribute("oiio:subimages");
m_nativespec.erase_attribute("oiio:subimages");
m_spec.erase_attribute("oiio:miplevels");
m_nativespec.erase_attribute("oiio:miplevels");
m_pixels_read = true;
}
if (src.m_configspec)
Expand Down Expand Up @@ -870,6 +872,7 @@ ImageBufImpl::clear()
m_name.clear();
m_fileformat.clear();
m_nsubimages = 0;
m_nmiplevels = 0;
m_current_subimage = -1;
m_current_miplevel = -1;
m_spec = ImageSpec();
Expand Down Expand Up @@ -2109,7 +2112,18 @@ ImageBuf::miplevel() const
int
ImageBuf::nmiplevels() const
{
m_impl->validate_spec();
if (!m_impl->validate_spec()) {
// Spec is invalid. Unnamed means no file to refer to (for example,
// default-constructed), so 1 as documented. Named means the file
// failed, so 0.
m_impl->m_nmiplevels = m_impl->m_name.empty() ? 1 : 0;
} else if (m_impl->m_name.empty() || m_impl->m_fileformat.empty()) {
// No direct reference to a file, so 1 as documented.
m_impl->m_nmiplevels = 1;
} else if (m_impl->m_nmiplevels == 0) {
m_impl->m_nmiplevels
= m_impl->m_spec.get_int_attribute("oiio:miplevels", 1);
}
return m_impl->m_nmiplevels;
}

Expand Down Expand Up @@ -2389,9 +2403,11 @@ ImageBuf::copy_pixels(const ImageBuf& src)
m_impl->m_nsubimages = 1;
m_impl->m_current_subimage = 0;
m_impl->m_current_miplevel = 0;
m_impl->m_nmiplevels = 0;
m_impl->m_nmiplevels = 1;
m_impl->m_spec.erase_attribute("oiio:subimages");
m_impl->m_nativespec.erase_attribute("oiio:subimages");
m_impl->m_spec.erase_attribute("oiio:miplevels");
m_impl->m_nativespec.erase_attribute("oiio:miplevels");

return ok;
}
Expand Down
10 changes: 4 additions & 6 deletions src/openexr.imageio/exrinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,11 @@ OpenEXRInput::PartInfo::parse_header(OpenEXRInput* in,

spec.deep = Strutil::istarts_with(header->type(), "deep");

if (levelmode != Imf::ONE_LEVEL)
if (levelmode != Imf::ONE_LEVEL) {
spec.attribute("openexr:roundingmode", roundingmode);
if (nmiplevels > 1)
spec.attribute("oiio:miplevels", nmiplevels);
}

const Imf::EnvmapAttribute* envmap;
envmap = header->findTypedAttribute<Imf::EnvmapAttribute>("envmap");
Expand Down Expand Up @@ -1194,11 +1197,6 @@ OpenEXRInput::seek_subimage(int subimage, int miplevel)
m_miplevel = miplevel;
m_spec = part.spec;

//! Add the number of miplevels as an attribute for the first miplevel.
//! TOFIX: adding the following attribute breaks unit tests
// if (m_miplevel == 0 && part.nmiplevels > 1)
// m_spec.attribute("oiio:miplevels", part.nmiplevels);

// The checks below reject this subimage. Invalidate rather than leave it
// as the current one, or a repeat of this same seek would take the early
// out above and hand back the spec we just refused.
Expand Down
10 changes: 4 additions & 6 deletions src/openexr.imageio/exrinput_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,11 @@ OpenEXRCoreInput::PartInfo::parse_header(OpenEXRCoreInput* in,
spec.deep = (storage == EXR_STORAGE_DEEP_TILED
|| storage == EXR_STORAGE_DEEP_SCANLINE);

if (levelmode != EXR_TILE_ONE_LEVEL)
if (levelmode != EXR_TILE_ONE_LEVEL) {
spec.attribute("openexr:roundingmode", (int)roundingmode);
if (nmiplevels > 1)
spec.attribute("oiio:miplevels", nmiplevels);
}

exr_envmap_t envmap;
rv = exr_attr_get_envmap(ctxt, subimage, "envmap", &envmap);
Expand Down Expand Up @@ -1218,11 +1221,6 @@ OpenEXRCoreInput::seek_subimage(int subimage, int miplevel)
m_miplevel = miplevel;
m_spec = part.spec;

//! Add the number of miplevels as an attribute for the first miplevel.
//! TOFIX: adding the following attribute breaks unit tests
// if (m_miplevel == 0 && part.nmiplevels > 1)
// m_spec.attribute("oiio:miplevels", part.nmiplevels);

// The checks below reject this subimage, so don't leave it as the
// current one with a spec that failed validation.
if (!check_open(m_spec, { 0, 1 << 30, 0, 1 << 30, 0, 1, 0, 1 << 12 })) {
Expand Down
16 changes: 12 additions & 4 deletions src/tiff.imageio/tiffinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,12 @@

// General TIFF information:
// TIFF 6.0 spec:
// http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
// Other Adobe TIFF docs:
// http://partners.adobe.com/public/developer/tiff/index.html
// https://download.osgeo.org/libtiff/doc/TIFF6.pdf
// Adobe extensions to allow 16 (and 24) bit float in TIFF (ugh, not on
// their developer page, only on Chris Cox's web site?):
// http://chriscox.org/TIFFTN3d1.pdf
// Libtiff:
// http://remotesensing.org/libtiff/
// http://www.simplesystems.org/libtiff/


// clang-format off
Expand Down Expand Up @@ -1483,6 +1481,16 @@ TIFFInput::readspec(bool read_meta)
m_spec.channelnames[c] = "z";
}

// Set miplevels attribute in MIP emulation case (m_emulate_mipmap = true).
if (m_emulate_mipmap) {
// libtiff's TIFFNumberOfDirectories() returns tdir_t (uint32_t after
// libtiff v4.5.0, uint16_t before it), but the int cast seems safe for
// any realistic directory count here.
int nmiplevels = (int)TIFFNumberOfDirectories(m_tif);
if (nmiplevels > 1)
m_spec.attribute("oiio:miplevels", nmiplevels);
}

/// read color profile
unsigned int icc_datasize = 0;
uint8_t* icc_buf = NULL;
Expand Down
5 changes: 5 additions & 0 deletions testsuite/dds/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Reading ../oiio-images/dds/dds_bc1_mips.dds
channel list: R, G, B, A
compression: "DXT1"
textureformat: "Plain Texture"
oiio:miplevels: 5
Reading ../oiio-images/dds/dds_bc2.dds
../oiio-images/dds/dds_bc2.dds : 16 x 8, 4 channel, uint8 dds
SHA-1: B458B3BAA7F457E06D04D0FBF93C003FFA729C97
Expand Down Expand Up @@ -74,6 +75,7 @@ Reading ../oiio-images/dds/dds_npot_bc3_mips.dds
channel list: R, G, B, A
compression: "DXT5"
textureformat: "Plain Texture"
oiio:miplevels: 4
Reading ../oiio-images/dds/dds_npot_rgba8.dds
../oiio-images/dds/dds_npot_rgba8.dds : 13 x 7, 4 channel, uint8 dds
SHA-1: 6CBA3E2782498E2E92F5E4B08376A2E948FE3BAF
Expand All @@ -87,6 +89,7 @@ Reading ../oiio-images/dds/dds_npot_rgba8_mips.dds
channel list: R, G, B, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 32
oiio:miplevels: 4
Reading ../oiio-images/dds/dds_r5g6b5.dds
../oiio-images/dds/dds_r5g6b5.dds : 16 x 8, 3 channel, uint8 dds
SHA-1: 37A3BFD2B8A52006B4F07065A90BE774F276B751
Expand Down Expand Up @@ -118,6 +121,7 @@ Reading ../oiio-images/dds/dds_rgba8_mips.dds
channel list: R, G, B, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 32
oiio:miplevels: 5
Reading ../oiio-images/dds/dds_a8.dds
../oiio-images/dds/dds_a8.dds : 24 x 20, 1 channel, uint8 dds
SHA-1: 497ACCA96FAAC89AE74BDE8CA7B69B37CA9C5F20
Expand Down Expand Up @@ -283,6 +287,7 @@ src/crash-3950.dds : 16 x 1, 4 channel, uint8 dds
channel list: R, G, B, A
compression: "DXT4"
textureformat: "Plain Texture"
oiio:miplevels: 6
oiiotool ERROR: read : "src/crash-bpp.dds": Invalid DDS bytes-per-pixel (322122548). Possible corrupt input?
Full command line was:
> oiiotool --info -v -a --hash src/crash-bpp.dds
Expand Down
2 changes: 2 additions & 0 deletions testsuite/iinfo/ref/out-fmt6.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
YResolution: 72
oiio:AverageColor: "0.608983,0.608434,0.608728,1"
oiio:BitsPerSample: 8
oiio:miplevels: 11
oiio:SHA-1: "233A1D3412A54A5F49814AB7BFFD04F56F46D3D7"
tiff:Compression: 8
tiff:PhotometricInterpretation: 2
Expand Down Expand Up @@ -441,6 +442,7 @@ src/mip.tif : 2 x 2, 3 channel, uint8 tiff
oiio:AverageColor: "0.25,0.5,0.75"
oiio:BitsPerSample: 8
oiio:ConstantColor: "0.25,0.5,0.75"
oiio:miplevels: 2
oiio:SHA-1: "1042D991FBDE596CF8FBC5660BC809AC057D8B9A"
tiff:Compression: 8
tiff:PhotometricInterpretation: 2
Expand Down
2 changes: 2 additions & 0 deletions testsuite/iinfo/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
YResolution: 72
oiio:AverageColor: "0.608983,0.608434,0.608728,1"
oiio:BitsPerSample: 8
oiio:miplevels: 11
oiio:SHA-1: "233A1D3412A54A5F49814AB7BFFD04F56F46D3D7"
tiff:Compression: 8
tiff:PhotometricInterpretation: 2
Expand Down Expand Up @@ -442,6 +443,7 @@ src/mip.tif : 2 x 2, 3 channel, uint8 tiff
oiio:AverageColor: "0.25,0.5,0.75"
oiio:BitsPerSample: 8
oiio:ConstantColor: "0.25,0.5,0.75"
oiio:miplevels: 2
oiio:SHA-1: "1042D991FBDE596CF8FBC5660BC809AC057D8B9A"
tiff:Compression: 8
tiff:PhotometricInterpretation: 2
Expand Down
Loading
Loading