Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/scene/image_oiio.cpp')
-rw-r--r--intern/cycles/scene/image_oiio.cpp45
1 files changed, 32 insertions, 13 deletions
diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp
index 3f825afbe90..09676455308 100644
--- a/intern/cycles/scene/image_oiio.cpp
+++ b/intern/cycles/scene/image_oiio.cpp
@@ -94,10 +94,11 @@ bool OIIOImageLoader::load_metadata(const ImageDeviceFeatures & /*features*/,
template<TypeDesc::BASETYPE FileFormat, typename StorageType>
static void oiio_load_pixels(const ImageMetaData &metadata,
const unique_ptr<ImageInput> &in,
+ const bool associate_alpha,
StorageType *pixels)
{
- const int width = metadata.width;
- const int height = metadata.height;
+ const size_t width = metadata.width;
+ const size_t height = metadata.height;
const int depth = metadata.depth;
const int components = metadata.channels;
@@ -105,12 +106,12 @@ static void oiio_load_pixels(const ImageMetaData &metadata,
StorageType *readpixels = pixels;
vector<StorageType> tmppixels;
if (components > 4) {
- tmppixels.resize(((size_t)width) * height * components);
+ tmppixels.resize(width * height * components);
readpixels = &tmppixels[0];
}
if (depth <= 1) {
- size_t scanlinesize = ((size_t)width) * components * sizeof(StorageType);
+ size_t scanlinesize = width * components * sizeof(StorageType);
in->read_image(FileFormat,
(uchar *)readpixels + (height - 1) * scanlinesize,
AutoStride,
@@ -122,7 +123,7 @@ static void oiio_load_pixels(const ImageMetaData &metadata,
}
if (components > 4) {
- size_t dimensions = ((size_t)width) * height;
+ size_t dimensions = width * height;
for (size_t i = dimensions - 1, pixel = 0; pixel < dimensions; pixel++, i--) {
pixels[i * 4 + 3] = tmppixels[i * components + 3];
pixels[i * 4 + 2] = tmppixels[i * components + 2];
@@ -137,7 +138,7 @@ static void oiio_load_pixels(const ImageMetaData &metadata,
if (cmyk) {
const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
- const size_t num_pixels = ((size_t)width) * height * depth;
+ const size_t num_pixels = width * height * depth;
for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
float c = util_image_cast_to_float(pixels[i * 4 + 0]);
float m = util_image_cast_to_float(pixels[i * 4 + 1]);
@@ -149,6 +150,16 @@ static void oiio_load_pixels(const ImageMetaData &metadata,
pixels[i * 4 + 3] = one;
}
}
+
+ if (components == 4 && associate_alpha) {
+ size_t dimensions = width * height;
+ for (size_t i = dimensions - 1, pixel = 0; pixel < dimensions; pixel++, i--) {
+ const StorageType alpha = pixels[i * 4 + 3];
+ pixels[i * 4 + 0] = util_image_multiply_native(pixels[i * 4 + 0], alpha);
+ pixels[i * 4 + 1] = util_image_multiply_native(pixels[i * 4 + 1], alpha);
+ pixels[i * 4 + 2] = util_image_multiply_native(pixels[i * 4 + 2], alpha);
+ }
+ }
}
bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata,
@@ -172,33 +183,41 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata,
ImageSpec spec = ImageSpec();
ImageSpec config = ImageSpec();
- if (!associate_alpha) {
- config.attribute("oiio:UnassociatedAlpha", 1);
- }
+ /* Load without automatic OIIO alpha conversion, we do it ourselves. OIIO
+ * will associate alpha in the the 8bit buffer for PNGs, which leads to too
+ * much precision loss when we load it as half float to do a colorspace
+ * transform. */
+ config.attribute("oiio:UnassociatedAlpha", 1);
if (!in->open(filepath.string(), spec, config)) {
return false;
}
+ const bool do_associate_alpha = associate_alpha &&
+ spec.get_int_attribute("oiio:UnassociatedAlpha", 0);
+
switch (metadata.type) {
case IMAGE_DATA_TYPE_BYTE:
case IMAGE_DATA_TYPE_BYTE4:
- oiio_load_pixels<TypeDesc::UINT8, uchar>(metadata, in, (uchar *)pixels);
+ oiio_load_pixels<TypeDesc::UINT8, uchar>(metadata, in, do_associate_alpha, (uchar *)pixels);
break;
case IMAGE_DATA_TYPE_USHORT:
case IMAGE_DATA_TYPE_USHORT4:
- oiio_load_pixels<TypeDesc::USHORT, uint16_t>(metadata, in, (uint16_t *)pixels);
+ oiio_load_pixels<TypeDesc::USHORT, uint16_t>(
+ metadata, in, do_associate_alpha, (uint16_t *)pixels);
break;
case IMAGE_DATA_TYPE_HALF:
case IMAGE_DATA_TYPE_HALF4:
- oiio_load_pixels<TypeDesc::HALF, half>(metadata, in, (half *)pixels);
+ oiio_load_pixels<TypeDesc::HALF, half>(metadata, in, do_associate_alpha, (half *)pixels);
break;
case IMAGE_DATA_TYPE_FLOAT:
case IMAGE_DATA_TYPE_FLOAT4:
- oiio_load_pixels<TypeDesc::FLOAT, float>(metadata, in, (float *)pixels);
+ oiio_load_pixels<TypeDesc::FLOAT, float>(metadata, in, do_associate_alpha, (float *)pixels);
break;
case IMAGE_DATA_TYPE_NANOVDB_FLOAT:
case IMAGE_DATA_TYPE_NANOVDB_FLOAT3:
+ case IMAGE_DATA_TYPE_NANOVDB_FPN:
+ case IMAGE_DATA_TYPE_NANOVDB_FP16:
case IMAGE_DATA_NUM_TYPES:
break;
}