forked from bartvdbraak/blender
Fix Cycles incorrect resize and CMYK conversion of uint16/half images.
This commit is contained in:
parent
83a4e1aaf9
commit
edbb2d2279
@ -33,15 +33,15 @@ CCL_NAMESPACE_BEGIN
|
|||||||
/* Some helpers to silence warning in templated function. */
|
/* Some helpers to silence warning in templated function. */
|
||||||
static bool isfinite(uchar /*value*/)
|
static bool isfinite(uchar /*value*/)
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
static bool isfinite(half /*value*/)
|
static bool isfinite(half /*value*/)
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
static bool isfinite(uint16_t /*value*/)
|
static bool isfinite(uint16_t /*value*/)
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageManager::ImageManager(const DeviceInfo& info)
|
ImageManager::ImageManager(const DeviceInfo& info)
|
||||||
@ -508,7 +508,6 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
int texture_limit,
|
int texture_limit,
|
||||||
device_vector<DeviceType>& tex_img)
|
device_vector<DeviceType>& tex_img)
|
||||||
{
|
{
|
||||||
const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
|
|
||||||
ImageInput *in = NULL;
|
ImageInput *in = NULL;
|
||||||
if(!file_load_image_generic(img, &in)) {
|
if(!file_load_image_generic(img, &in)) {
|
||||||
return false;
|
return false;
|
||||||
@ -601,13 +600,19 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
type == IMAGE_DATA_TYPE_BYTE4 ||
|
type == IMAGE_DATA_TYPE_BYTE4 ||
|
||||||
type == IMAGE_DATA_TYPE_USHORT4);
|
type == IMAGE_DATA_TYPE_USHORT4);
|
||||||
if(is_rgba) {
|
if(is_rgba) {
|
||||||
|
const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
|
||||||
|
|
||||||
if(cmyk) {
|
if(cmyk) {
|
||||||
/* CMYK */
|
/* CMYK */
|
||||||
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
||||||
pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
|
float c = util_image_cast_to_float(pixels[i*4+0]);
|
||||||
pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
|
float m = util_image_cast_to_float(pixels[i*4+1]);
|
||||||
pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
|
float y = util_image_cast_to_float(pixels[i*4+2]);
|
||||||
pixels[i*4+3] = alpha_one;
|
float k = util_image_cast_to_float(pixels[i*4+3]);
|
||||||
|
pixels[i*4+0] = util_image_cast_from_float<StorageType>((1.0f - c) * (1.0f - k));
|
||||||
|
pixels[i*4+1] = util_image_cast_from_float<StorageType>((1.0f - m) * (1.0f - k));
|
||||||
|
pixels[i*4+2] = util_image_cast_from_float<StorageType>((1.0f - y) * (1.0f - k));
|
||||||
|
pixels[i*4+3] = one;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(components == 2) {
|
else if(components == 2) {
|
||||||
@ -622,7 +627,7 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
else if(components == 3) {
|
else if(components == 3) {
|
||||||
/* RGB */
|
/* RGB */
|
||||||
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
||||||
pixels[i*4+3] = alpha_one;
|
pixels[i*4+3] = one;
|
||||||
pixels[i*4+2] = pixels[i*3+2];
|
pixels[i*4+2] = pixels[i*3+2];
|
||||||
pixels[i*4+1] = pixels[i*3+1];
|
pixels[i*4+1] = pixels[i*3+1];
|
||||||
pixels[i*4+0] = pixels[i*3+0];
|
pixels[i*4+0] = pixels[i*3+0];
|
||||||
@ -631,7 +636,7 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
else if(components == 1) {
|
else if(components == 1) {
|
||||||
/* grayscale */
|
/* grayscale */
|
||||||
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
||||||
pixels[i*4+3] = alpha_one;
|
pixels[i*4+3] = one;
|
||||||
pixels[i*4+2] = pixels[i];
|
pixels[i*4+2] = pixels[i];
|
||||||
pixels[i*4+1] = pixels[i];
|
pixels[i*4+1] = pixels[i];
|
||||||
pixels[i*4+0] = pixels[i];
|
pixels[i*4+0] = pixels[i];
|
||||||
@ -639,7 +644,7 @@ bool ImageManager::file_load_image(Image *img,
|
|||||||
}
|
}
|
||||||
if(img->use_alpha == false) {
|
if(img->use_alpha == false) {
|
||||||
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
||||||
pixels[i*4+3] = alpha_one;
|
pixels[i*4+3] = one;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -871,7 +876,7 @@ void ImageManager::device_load_image(Device *device,
|
|||||||
thread_scoped_lock device_lock(device_mutex);
|
thread_scoped_lock device_lock(device_mutex);
|
||||||
uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
|
uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
|
||||||
|
|
||||||
pixels[0] = TEX_IMAGE_MISSING_R;
|
pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
|
||||||
}
|
}
|
||||||
|
|
||||||
img->mem = tex_img;
|
img->mem = tex_img;
|
||||||
@ -893,10 +898,10 @@ void ImageManager::device_load_image(Device *device,
|
|||||||
thread_scoped_lock device_lock(device_mutex);
|
thread_scoped_lock device_lock(device_mutex);
|
||||||
uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
|
uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
|
||||||
|
|
||||||
pixels[0] = TEX_IMAGE_MISSING_R;
|
pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
|
||||||
pixels[1] = TEX_IMAGE_MISSING_G;
|
pixels[1] = (TEX_IMAGE_MISSING_G * 65535);
|
||||||
pixels[2] = TEX_IMAGE_MISSING_B;
|
pixels[2] = (TEX_IMAGE_MISSING_B * 65535);
|
||||||
pixels[3] = TEX_IMAGE_MISSING_A;
|
pixels[3] = (TEX_IMAGE_MISSING_A * 65535);
|
||||||
}
|
}
|
||||||
|
|
||||||
img->mem = tex_img;
|
img->mem = tex_img;
|
||||||
|
@ -38,6 +38,68 @@ void util_image_resize_pixels(const vector<T>& input_pixels,
|
|||||||
size_t *output_height,
|
size_t *output_height,
|
||||||
size_t *output_depth);
|
size_t *output_depth);
|
||||||
|
|
||||||
|
/* Cast input pixel from unknown storage to float. */
|
||||||
|
template<typename T>
|
||||||
|
inline float util_image_cast_to_float(T value);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline float util_image_cast_to_float(float value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
inline float util_image_cast_to_float(uchar value)
|
||||||
|
{
|
||||||
|
return (float)value / 255.0f;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
inline float util_image_cast_to_float(uint16_t value)
|
||||||
|
{
|
||||||
|
return (float)value / 65535.0f;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
inline float util_image_cast_to_float(half value)
|
||||||
|
{
|
||||||
|
return half_to_float(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cast float value to output pixel type. */
|
||||||
|
template<typename T>
|
||||||
|
inline T util_image_cast_from_float(float value);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline float util_image_cast_from_float(float value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
inline uchar util_image_cast_from_float(float value)
|
||||||
|
{
|
||||||
|
if(value < 0.0f) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(value > (1.0f - 0.5f / 255.0f)) {
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
return (uchar)((255.0f * value) + 0.5f);
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
inline uint16_t util_image_cast_from_float(float value)
|
||||||
|
{
|
||||||
|
if(value < 0.0f) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(value > (1.0f - 0.5f / 65535.0f)) {
|
||||||
|
return 65535;
|
||||||
|
}
|
||||||
|
return (uint16_t)((65535.0f * value) + 0.5f);
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
inline half util_image_cast_from_float(float value)
|
||||||
|
{
|
||||||
|
return float_to_half(value);
|
||||||
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* __UTIL_IMAGE_H__ */
|
#endif /* __UTIL_IMAGE_H__ */
|
||||||
|
@ -38,68 +38,6 @@ const T *util_image_read(const vector<T>& pixels,
|
|||||||
return &pixels[index];
|
return &pixels[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cast input pixel from unknown storage to float. */
|
|
||||||
template<typename T>
|
|
||||||
inline float cast_to_float(T value);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline float cast_to_float(float value)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline float cast_to_float(uchar value)
|
|
||||||
{
|
|
||||||
return (float)value / 255.0f;
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline float cast_to_float(uint16_t value)
|
|
||||||
{
|
|
||||||
return (float)value / 65535.0f;
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline float cast_to_float(half value)
|
|
||||||
{
|
|
||||||
return half_to_float(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cast float value to output pixel type. */
|
|
||||||
template<typename T>
|
|
||||||
inline T cast_from_float(float value);
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline float cast_from_float(float value)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline uchar cast_from_float(float value)
|
|
||||||
{
|
|
||||||
if(value < 0.0f) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if(value > (1.0f - 0.5f / 255.0f)) {
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
return (uchar)((255.0f * value) + 0.5f);
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline uint16_t cast_from_float(float value)
|
|
||||||
{
|
|
||||||
if(value < 0.0f) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if(value >(1.0f - 0.5f / 65535.0f)) {
|
|
||||||
return 65535;
|
|
||||||
}
|
|
||||||
return (uchar)((65535.0f * value) + 0.5f);
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline half cast_from_float(float value)
|
|
||||||
{
|
|
||||||
return float_to_half(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void util_image_downscale_sample(const vector<T>& pixels,
|
void util_image_downscale_sample(const vector<T>& pixels,
|
||||||
const size_t width,
|
const size_t width,
|
||||||
@ -133,7 +71,7 @@ void util_image_downscale_sample(const vector<T>& pixels,
|
|||||||
components,
|
components,
|
||||||
nx, ny, nz);
|
nx, ny, nz);
|
||||||
for(size_t k = 0; k < components; ++k) {
|
for(size_t k = 0; k < components; ++k) {
|
||||||
accum[k] += cast_to_float(pixel[k]);
|
accum[k] += util_image_cast_to_float(pixel[k]);
|
||||||
}
|
}
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@ -142,7 +80,7 @@ void util_image_downscale_sample(const vector<T>& pixels,
|
|||||||
if(count != 0) {
|
if(count != 0) {
|
||||||
const float inv_count = 1.0f / (float)count;
|
const float inv_count = 1.0f / (float)count;
|
||||||
for(size_t k = 0; k < components; ++k) {
|
for(size_t k = 0; k < components; ++k) {
|
||||||
result[k] = cast_from_float<T>(accum[k] * inv_count);
|
result[k] = util_image_cast_from_float<T>(accum[k] * inv_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
Reference in New Issue
Block a user