Skip to content

Commit 09a0629

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fix-bug-with-window-loosing-focus-on-mac-on-startup
2 parents 7d9200a + 01392e6 commit 09a0629

File tree

6 files changed

+58
-22
lines changed

6 files changed

+58
-22
lines changed

src/doc/builtinplugins.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3066,6 +3066,11 @@ attributes are supported:
30663066
- ptr
30673067
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
30683068
example by reading from memory rather than the file system.
3069+
* - ``oiio:UnassociatedAlpha``
3070+
- int
3071+
- If nonzero, will leave alpha unassociated (versus the default of
3072+
premultiplying color channels by alpha if the alpha channel is
3073+
unassociated).
30693074

30703075
**Configuration settings for WebP output**
30713076

@@ -3088,6 +3093,12 @@ control aspects of the writing itself:
30883093
- ptr
30893094
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
30903095
example by writing to a memory buffer.
3096+
* - ``oiio:UnassociatedAlpha``
3097+
- int
3098+
- If nonzero, indicates that the data being passed is already in
3099+
unassociated form (non-premultiplied colors) and should stay that way
3100+
for output rather than being assumed to be associated and get automatic
3101+
un-association to store in the file.
30913102

30923103
**Custom I/O Overrides**
30933104

src/include/OpenImageIO/typedesc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ struct formatter<OIIO::TypeDesc> {
616616
{
617617
// Get the presentation type, if any. Required to be 's'.
618618
auto it = ctx.begin(), end = ctx.end();
619+
// Skip any width specifier. Remember that this is only for old
620+
// versions of fmt, so just don't sweat it.
621+
while (it != end && isdigit(*it)) ++it;
619622
if (it != end && (*it == 's')) ++it;
620623
// Check if reached the end of the range:
621624
if (it != end && *it != '}')

src/libOpenImageIO/imageinput.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class ImageInput::Impl {
3535
public:
3636
Impl()
3737
: m_id(++input_next_id)
38+
, m_threads(pvt::oiio_threads)
3839
{
3940
}
4041

src/libOpenImageIO/imageoutput.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class ImageOutput::Impl {
3838
public:
3939
Impl()
4040
: m_id(++output_next_id)
41+
, m_threads(pvt::oiio_threads)
4142
{
4243
}
4344

src/webp.imageio/webpinput.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ class WebpInput final : public ImageInput {
4444
int m_frame_count = 1;
4545
WebPDemuxer* m_demux = nullptr;
4646
WebPIterator m_iter;
47-
int m_subimage = -1; // Subimage we're pointed to
48-
int m_subimage_read = -1; // Subimage stored in decoded_image
47+
int m_subimage = -1; // Subimage we're pointed to
48+
int m_subimage_read = -1; // Subimage stored in decoded_image
49+
bool m_keep_unassociated_alpha = false; // Do not convert unassociated alpha
4950

5051
void init(void)
5152
{
@@ -204,6 +205,9 @@ WebpInput::open(const std::string& name, ImageSpec& spec,
204205
// Make space for the decoded image
205206
m_decoded_image.reset(new uint8_t[m_spec.image_bytes()]);
206207

208+
if (config.get_int_attribute("oiio:UnassociatedAlpha", 0) == 1)
209+
m_keep_unassociated_alpha = true;
210+
207211
seek_subimage(0, 0);
208212
spec = m_spec;
209213
return true;
@@ -306,12 +310,15 @@ WebpInput::read_current_subimage()
306310
m_decoded_image.get() + offset,
307311
m_spec.image_bytes() - offset,
308312
m_spec.scanline_bytes());
309-
// WebP requires unassociated alpha, and it's sRGB.
310-
// Handle this all by wrapping an IB around it.
311-
ImageBuf fullbuf(m_spec,
312-
span<std::byte>((std::byte*)m_decoded_image.get(),
313-
m_spec.image_bytes()));
314-
ImageBufAlgo::premult(fullbuf, fullbuf);
313+
314+
// WebP is unassociated alpha and sRGB.
315+
// Convert to the OIIO-native associated form if required.
316+
if (!m_keep_unassociated_alpha) {
317+
ImageBuf fullbuf(
318+
m_spec, span<std::byte>((std::byte*)m_decoded_image.get(),
319+
m_spec.image_bytes()));
320+
ImageBufAlgo::premult(fullbuf, fullbuf);
321+
}
315322
}
316323
} else {
317324
// This subimage writes *atop* the prior image, we must composite
@@ -328,10 +335,14 @@ WebpInput::read_current_subimage()
328335
(uint8_t*)fragbuf.localpixels(),
329336
fragspec.image_bytes(),
330337
fragspec.scanline_bytes());
331-
// WebP requires unassociated alpha, and it's sRGB.
332-
// Handle this all by wrapping an IB around it.
333-
ImageBufAlgo::premult(fragbuf, fragbuf);
334-
ImageBufAlgo::over(fullbuf, fragbuf, fullbuf);
338+
339+
340+
// WebP is unassociated alpha and sRGB.
341+
// Convert to the OIIO-native associated form if required.
342+
if (!m_keep_unassociated_alpha) {
343+
ImageBufAlgo::premult(fragbuf, fragbuf);
344+
ImageBufAlgo::over(fullbuf, fragbuf, fullbuf);
345+
}
335346
}
336347

337348
if (!okptr) {
@@ -371,7 +382,8 @@ WebpInput::close()
371382
}
372383
m_decoded_image.reset();
373384
m_encoded_image.reset();
374-
m_subimage = -1;
385+
m_subimage = -1;
386+
m_keep_unassociated_alpha = false;
375387
init();
376388
return true;
377389
}

src/webp.imageio/webpoutput.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class WebpOutput final : public ImageOutput {
3636
std::string m_filename;
3737
imagesize_t m_scanline_size;
3838
unsigned int m_dither;
39+
bool m_convert_alpha; // Do we deassociate alpha?
3940
std::vector<uint8_t> m_uncompressed_image;
4041

4142
void init()
@@ -113,7 +114,9 @@ WebpOutput::open(const std::string& name, const ImageSpec& spec, OpenMode mode)
113114

114115
// forcing UINT8 format
115116
m_spec.set_format(TypeDesc::UINT8);
116-
m_dither = m_spec.get_int_attribute("oiio:dither", 0);
117+
m_dither = m_spec.get_int_attribute("oiio:dither", 0);
118+
m_convert_alpha = m_spec.alpha_channel != -1
119+
&& !m_spec.get_int_attribute("oiio:UnassociatedAlpha", 0);
117120

118121
m_scanline_size = m_spec.scanline_bytes();
119122
m_uncompressed_image.resize(m_spec.image_bytes(), 0);
@@ -136,20 +139,25 @@ WebpOutput::write_scanline(int y, int z, TypeDesc format, const void* data,
136139

137140
if (y == m_spec.height - 1) {
138141
if (m_spec.nchannels == 4) {
139-
// WebP requires unassociated alpha, and it's sRGB.
140-
// Handle this all by wrapping an IB around it.
141-
ImageSpec specwrap(m_spec.width, m_spec.height, 4, TypeUInt8);
142-
ImageBuf bufwrap(specwrap, cspan<uint8_t>(m_uncompressed_image));
143-
ROI rgbroi(0, m_spec.width, 0, m_spec.height, 0, 1, 0, 3);
144-
ImageBufAlgo::pow(bufwrap, bufwrap, 2.2f, rgbroi);
145-
ImageBufAlgo::unpremult(bufwrap, bufwrap);
146-
ImageBufAlgo::pow(bufwrap, bufwrap, 1.0f / 2.2f, rgbroi);
142+
if (m_convert_alpha) {
143+
// WebP requires unassociated alpha, and it's sRGB.
144+
// Handle this all by wrapping an IB around it.
145+
ImageSpec specwrap(m_spec.width, m_spec.height, 4, TypeUInt8);
146+
ImageBuf bufwrap(specwrap,
147+
cspan<uint8_t>(m_uncompressed_image));
148+
ROI rgbroi(0, m_spec.width, 0, m_spec.height, 0, 1, 0, 3);
149+
ImageBufAlgo::pow(bufwrap, bufwrap, 2.2f, rgbroi);
150+
ImageBufAlgo::unpremult(bufwrap, bufwrap);
151+
ImageBufAlgo::pow(bufwrap, bufwrap, 1.0f / 2.2f, rgbroi);
152+
}
153+
147154
WebPPictureImportRGBA(&m_webp_picture, m_uncompressed_image.data(),
148155
m_scanline_size);
149156
} else {
150157
WebPPictureImportRGB(&m_webp_picture, m_uncompressed_image.data(),
151158
m_scanline_size);
152159
}
160+
153161
if (!WebPEncode(&m_webp_config, &m_webp_picture)) {
154162
errorfmt("Failed to encode {} as WebP image", m_filename);
155163
close();

0 commit comments

Comments
 (0)