diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-11-14 16:03:17 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-11-14 16:03:17 +0300 |
commit | b047d79871ce7ad366b166de2a872f93508bbc9f (patch) | |
tree | f3889d3835a898f8e6fc9653f8d4f85959deff7e | |
parent | 7a4a2ed5f4086b488e9bc03ab32a79f6f8322c02 (diff) |
Cycles: De-duplicate image loading functions
The code was templated already, so don't see big reason to have
3 versions of templated functions. It was giving some extra code
to maintain and in fact already had divergency for support of huge
image resolution (missing size_t cast in byte image loading).
There should be no changes visible by artists.
-rw-r--r-- | intern/cycles/render/image.cpp | 270 | ||||
-rw-r--r-- | intern/cycles/render/image.h | 14 |
2 files changed, 51 insertions, 233 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 073a0aa2ac9..7465fbd43a7 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -471,133 +471,43 @@ bool ImageManager::file_load_image_generic(Image *img, ImageInput **in, int &wid return true; } -template<typename T> -bool ImageManager::file_load_byte_image(Image *img, ImageDataType type, device_vector<T>& tex_img) +template<TypeDesc::BASETYPE FileFormat, + typename StorageType, + typename DeviceType> +bool ImageManager::file_load_image(Image *img, + ImageDataType type, + device_vector<DeviceType>& tex_img) { + const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1; ImageInput *in = NULL; int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read RGBA pixels */ - uchar *pixels = (uchar*)tex_img.resize(width, height, depth); - if(pixels == NULL) { + if(!file_load_image_generic(img, &in, width, height, depth, components)) { return false; } - bool cmyk = 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); - } - - cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4; - - in->close(); - delete in; - } - else { - builtin_image_pixels_cb(img->filename, img->builtin_data, pixels); - } - - /* 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 == 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]; - } - } - - 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; -} - -template<typename T> -bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_vector<T>& tex_img) -{ - ImageInput *in = NULL; - int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read RGBA pixels */ - float *pixels = (float*)tex_img.resize(width, height, depth); + /* Read RGBA pixels. */ + StorageType *pixels = (StorageType*)tex_img.resize(width, height, depth); if(pixels == NULL) { return false; } bool cmyk = false; - if(in) { - float *readpixels = pixels; - vector<float> tmppixels; - + StorageType *readpixels = pixels; + vector<StorageType> tmppixels; if(components > 4) { tmppixels.resize(((size_t)width)*height*components); readpixels = &tmppixels[0]; } - if(depth <= 1) { - size_t scanlinesize = ((size_t)width)*components*sizeof(float); - in->read_image(TypeDesc::FLOAT, + size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType); + in->read_image(FileFormat, (uchar*)readpixels + (height-1)*scanlinesize, AutoStride, -scanlinesize, AutoStride); } else { - in->read_image(TypeDesc::FLOAT, (uchar*)readpixels); + in->read_image(FileFormat, (uchar*)readpixels); } - if(components > 4) { size_t dimensions = ((size_t)width)*height; for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) { @@ -606,30 +516,42 @@ bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_ pixels[i*4+1] = tmppixels[i*components+1]; pixels[i*4+0] = tmppixels[i*components+0]; } - tmppixels.clear(); } - cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4; - in->close(); delete in; } else { - builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); + if(FileFormat == TypeDesc::FLOAT) { + builtin_image_float_pixels_cb(img->filename, + img->builtin_data, + (float*)pixels); + } + else if(FileFormat == TypeDesc::UINT8) { + builtin_image_pixels_cb(img->filename, + img->builtin_data, + (uchar*)pixels); + } + else { + /* TODO(dingto): Support half for ImBuf. */ + } } - - /* 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) { + /* 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 || + type == IMAGE_DATA_TYPE_HALF4 || + 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+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; + pixels[i*4+3] = alpha_one; } } else if(components == 2) { @@ -644,7 +566,7 @@ bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_ 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+3] = alpha_one; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; pixels[i*4+0] = pixels[i*3+0]; @@ -653,120 +575,18 @@ bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_ 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+3] = alpha_one; 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; + pixels[i*4+3] = alpha_one; } } } - - return true; -} - -template<typename T> -bool ImageManager::file_load_half_image(Image *img, ImageDataType type, device_vector<T>& tex_img) -{ - ImageInput *in = NULL; - int width, height, depth, components; - - if(!file_load_image_generic(img, &in, width, height, depth, components)) - return false; - - /* read RGBA pixels */ - half *pixels = (half*)tex_img.resize(width, height, depth); - if(pixels == NULL) { - return false; - } - - if(in) { - half *readpixels = pixels; - vector<half> tmppixels; - - if(components > 4) { - tmppixels.resize(((size_t)width)*height*components); - readpixels = &tmppixels[0]; - } - - if(depth <= 1) { - size_t scanlinesize = ((size_t)width)*components*sizeof(half); - in->read_image(TypeDesc::HALF, - (uchar*)readpixels + (height-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); - } - else { - in->read_image(TypeDesc::HALF, (uchar*)readpixels); - } - - if(components > 4) { - size_t dimensions = ((size_t)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]; - pixels[i*4+1] = tmppixels[i*components+1]; - pixels[i*4+0] = tmppixels[i*components+0]; - } - - tmppixels.clear(); - } - - in->close(); - delete in; - } -#if 0 - /* TODO(dingto): Support half for ImBuf. */ - else { - builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); - } -#endif - - /* Check if we actually have a half4 slot, in case components == 1, but device - * doesn't support single channel textures. */ - if(type == IMAGE_DATA_TYPE_HALF4) { - size_t num_pixels = ((size_t)width) * height * depth; - 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 == 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; } @@ -802,7 +622,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_float_image(img, type, tex_img)) { + if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); @@ -828,7 +648,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_float_image(img, type, tex_img)) { + if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); @@ -851,7 +671,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_byte_image(img, type, tex_img)) { + if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); @@ -877,7 +697,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_byte_image(img, type, tex_img)) { + if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); @@ -900,7 +720,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_half_image(img, type, tex_img)) { + if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ half *pixels = (half*)tex_img.resize(1, 1); @@ -926,7 +746,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD device->tex_free(tex_img); } - if(!file_load_half_image(img, type, tex_img)) { + if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ half *pixels = (half*)tex_img.resize(1, 1); diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index cca71a6bb93..1dc4bf180f8 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -109,14 +109,12 @@ private: bool file_load_image_generic(Image *img, ImageInput **in, int &width, int &height, int &depth, int &components); - template<typename T> - bool file_load_byte_image(Image *img, ImageDataType type, device_vector<T>& tex_img); - - template<typename T> - bool file_load_float_image(Image *img, ImageDataType type, device_vector<T>& tex_img); - - template<typename T> - bool file_load_half_image(Image *img, ImageDataType type, device_vector<T>& tex_img); + template<TypeDesc::BASETYPE FileFormat, + typename StorageType, + typename DeviceType> + bool file_load_image(Image *img, + ImageDataType type, + device_vector<DeviceType>& tex_img); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); |