From a2669b0cbff0dc02729a7246ac29642aca84929e Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 22 May 2016 23:24:26 +0200 Subject: [PATCH] Cleanup: Deduplicate image loading functions using templates. --- intern/cycles/render/image.cpp | 248 ++++++++++++--------------------- intern/cycles/render/image.h | 10 +- 2 files changed, 96 insertions(+), 162 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 150c742fd24..6650c98aa38 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -280,7 +280,7 @@ int ImageManager::add_image(const string& filename, if(type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4) is_float = true; - /* No single channel textures on Fermi GPUs, use available slots */ + /* No single channel textures on CUDA (Fermi) and OpenCL, use available slots */ if(type == IMAGE_DATA_TYPE_FLOAT && tex_num_images[type] == 0) type = IMAGE_DATA_TYPE_FLOAT4; if(type == IMAGE_DATA_TYPE_BYTE && tex_num_images[type] == 0) @@ -460,7 +460,8 @@ bool ImageManager::file_load_image_generic(Image *img, ImageInput **in, int &wid return true; } -bool ImageManager::file_load_byte4_image(Image *img, device_vector& tex_img) +template +bool ImageManager::file_load_byte_image(Image *img, ImageDataType type, device_vector& tex_img) { ImageInput *in = NULL; int width, height, depth, components; @@ -498,92 +499,59 @@ bool ImageManager::file_load_byte4_image(Image *img, device_vector& tex_ builtin_image_pixels_cb(img->filename, img->builtin_data, pixels); } - size_t num_pixels = ((size_t)width) * height * depth; - if(cmyk) { - /* CMYK */ - 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; - pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; - pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; - pixels[i*4+3] = 255; + /* Check if we actually have a byte4 slot, in case components == 1, but device + * doesn't support single channel textures. */ + if(type == IMAGE_DATA_TYPE_BYTE4) { + size_t num_pixels = ((size_t)width) * height * depth; + if(cmyk) { + /* CMYK */ + 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; + pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; + pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; + pixels[i*4+3] = 255; + } } - } - else if(components == 2) { - /* grayscale + alpha */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = pixels[i*2+1]; - pixels[i*4+2] = pixels[i*2+0]; - pixels[i*4+1] = pixels[i*2+0]; - pixels[i*4+0] = pixels[i*2+0]; + else if(components == 2) { + /* grayscale + alpha */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = pixels[i*2+1]; + pixels[i*4+2] = pixels[i*2+0]; + pixels[i*4+1] = pixels[i*2+0]; + pixels[i*4+0] = pixels[i*2+0]; + } } - } - else if(components == 3) { - /* RGB */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; - pixels[i*4+2] = pixels[i*3+2]; - pixels[i*4+1] = pixels[i*3+1]; - pixels[i*4+0] = pixels[i*3+0]; + else if(components == 3) { + /* RGB */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + pixels[i*4+2] = pixels[i*3+2]; + pixels[i*4+1] = pixels[i*3+1]; + pixels[i*4+0] = pixels[i*3+0]; + } } - } - else if(components == 1) { - /* grayscale */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; - pixels[i*4+2] = pixels[i]; - pixels[i*4+1] = pixels[i]; - pixels[i*4+0] = pixels[i]; + else if(components == 1) { + /* grayscale */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + pixels[i*4+2] = pixels[i]; + pixels[i*4+1] = pixels[i]; + pixels[i*4+0] = pixels[i]; + } } - } - if(img->use_alpha == false) { - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; + if(img->use_alpha == false) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + } } } return true; } -bool ImageManager::file_load_byte_image(Image *img, device_vector& tex_img) -{ - ImageInput *in = NULL; - int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read BW pixels */ - uchar *pixels = (uchar*)tex_img.resize(width, height, depth); - if(pixels == NULL) { - return false; - } - - if(in) { - if(depth <= 1) { - int scanlinesize = width*components*sizeof(uchar); - - in->read_image(TypeDesc::UINT8, - (uchar*)pixels + (((size_t)height)-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); - } - else { - in->read_image(TypeDesc::UINT8, (uchar*)pixels); - } - - in->close(); - delete in; - } - else { - builtin_image_pixels_cb(img->filename, img->builtin_data, pixels); - } - - return true; -} - -bool ImageManager::file_load_float4_image(Image *img, device_vector& tex_img) +template +bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_vector& tex_img) { ImageInput *in = NULL; int width, height, depth, components; @@ -641,88 +609,52 @@ bool ImageManager::file_load_float4_image(Image *img, device_vector& tex builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); } - size_t num_pixels = ((size_t)width) * height * depth; - if(cmyk) { - /* CMYK */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 255; - pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; - pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; - pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; + /* Check if we actually have a float4 slot, in case components == 1, but device + * doesn't support single channel textures. */ + if(type == IMAGE_DATA_TYPE_FLOAT4) { + size_t num_pixels = ((size_t)width) * height * depth; + if(cmyk) { + /* CMYK */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 255; + pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; + pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; + pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; + } } - } - else if(components == 2) { - /* grayscale + alpha */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = pixels[i*2+1]; - pixels[i*4+2] = pixels[i*2+0]; - pixels[i*4+1] = pixels[i*2+0]; - pixels[i*4+0] = pixels[i*2+0]; + else if(components == 2) { + /* grayscale + alpha */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = pixels[i*2+1]; + pixels[i*4+2] = pixels[i*2+0]; + pixels[i*4+1] = pixels[i*2+0]; + pixels[i*4+0] = pixels[i*2+0]; + } } - } - else if(components == 3) { - /* RGB */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 1.0f; - pixels[i*4+2] = pixels[i*3+2]; - pixels[i*4+1] = pixels[i*3+1]; - pixels[i*4+0] = pixels[i*3+0]; + else if(components == 3) { + /* RGB */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 1.0f; + pixels[i*4+2] = pixels[i*3+2]; + pixels[i*4+1] = pixels[i*3+1]; + pixels[i*4+0] = pixels[i*3+0]; + } } - } - else if(components == 1) { - /* grayscale */ - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 1.0f; - pixels[i*4+2] = pixels[i]; - pixels[i*4+1] = pixels[i]; - pixels[i*4+0] = pixels[i]; - } - } - - if(img->use_alpha == false) { - for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = 1.0f; - } - } - - return true; -} - -bool ImageManager::file_load_float_image(Image *img, device_vector& tex_img) -{ - ImageInput *in = NULL; - int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read BW pixels */ - float *pixels = (float*)tex_img.resize(width, height, depth); - if(pixels == NULL) { - return false; - } - - if(in) { - float *readpixels = pixels; - - if(depth <= 1) { - int scanlinesize = width*components*sizeof(float); - - in->read_image(TypeDesc::FLOAT, - (uchar*)readpixels + (height-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); - } - else { - in->read_image(TypeDesc::FLOAT, (uchar*)readpixels); + else if(components == 1) { + /* grayscale */ + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 1.0f; + pixels[i*4+2] = pixels[i]; + pixels[i*4+1] = pixels[i]; + pixels[i*4+0] = pixels[i]; + } } - in->close(); - delete in; - } - else { - builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); + if(img->use_alpha == false) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { + pixels[i*4+3] = 1.0f; + } + } } return true; @@ -760,7 +692,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_float4_image(img, tex_img)) { + if(!file_load_float_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); @@ -786,7 +718,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_float_image(img, tex_img)) { + if(!file_load_float_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); @@ -809,7 +741,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_byte4_image(img, tex_img)) { + if(!file_load_byte_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); @@ -835,7 +767,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_byte_image(img, tex_img)) { + if(!file_load_byte_image(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 53f739cd356..2ab16dd8967 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -107,10 +107,12 @@ private: bool pack_images; bool file_load_image_generic(Image *img, ImageInput **in, int &width, int &height, int &depth, int &components); - bool file_load_byte4_image(Image *img, device_vector& tex_img); - bool file_load_byte_image(Image *img, device_vector& tex_img); - bool file_load_float4_image(Image *img, device_vector& tex_img); - bool file_load_float_image(Image *img, device_vector& tex_img); + + template + bool file_load_byte_image(Image *img, ImageDataType type, device_vector& tex_img); + + template + bool file_load_float_image(Image *img, ImageDataType type, device_vector& tex_img); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type);