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:
authorAntony Riakiotakis <kalast@gmail.com>2011-06-07 02:10:05 +0400
committerAntony Riakiotakis <kalast@gmail.com>2011-06-07 02:10:05 +0400
commitb481524fde453884f8854a95bba1c1fdeb46959f (patch)
treeb9a065e7d239f84a95fa79e2181b6b45fd264686 /source/blender/imbuf/intern/divers.c
parent9088b69f7a1707b6826cc6cb50e59fa3b6fbcdda (diff)
fix for float projection painting, now updating correctly.
This fix also allows for partial update of the image, speeding up painting. The different code path implemented will be used to upload high resolution images to OpenGL when onion branch is merged. Due to conversion of float textures to/from sRGB, corrections made to brush color sampling to take account of the image profile. This is not 100% correct yet as texture images used for projection painting strokes are not converted to/from sRGB yet(This has been decided due to loss of precision for 8-bit formats). It will have to do for now, though. last-minute update, exr image loading is broken, will fix asap
Diffstat (limited to 'source/blender/imbuf/intern/divers.c')
-rw-r--r--source/blender/imbuf/intern/divers.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 6b35d7df397..90ee2692cf0 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -197,6 +197,135 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
ibuf->userflags &= ~IB_RECT_INVALID;
}
+
+
+/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
+void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h)
+{
+ /* indices to source and destination image pixels */
+ float *srcFloatPxl;
+ unsigned char *dstBytePxl;
+ /* buffer index will fill buffer */
+ float *bufferIndex;
+
+ /* convenience pointers to start of image buffers */
+ float *init_srcFloatPxl = (float *)ibuf->rect_float;
+ unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
+
+ /* Dithering factor */
+ float dither= ibuf->dither / 255.0f;
+ /* respective attributes of image */
+ short profile= ibuf->profile;
+ int channels= ibuf->channels;
+
+ int i, j;
+
+ /*
+ if called -only- from GPU_paint_update_image this test will never fail
+ but leaving it here for better or worse
+ */
+ if(init_srcFloatPxl==NULL || (buffer == NULL)){
+ return;
+ }
+ if(init_dstBytePxl==NULL) {
+ imb_addrectImBuf(ibuf);
+ init_dstBytePxl = (unsigned char *) ibuf->rect;
+ }
+ if(channels==1) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x);
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) {
+ dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]);
+ bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0];
+ }
+ }
+ }
+ else if (profile == IB_PROFILE_LINEAR_RGB) {
+ if(channels == 3) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) {
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ F3TOCHAR4(bufferIndex, dstBytePxl);
+ bufferIndex[3]= 1.0;
+ }
+ }
+ }
+ else if (channels == 4) {
+ if (dither != 0.f) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ const float d = (BLI_frand()-0.5f)*dither;
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ bufferIndex[3] = srcFloatPxl[3];
+ add_v4_fl(bufferIndex, d);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ } else {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ bufferIndex[3]= srcFloatPxl[3];
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ }
+ }
+ }
+ else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
+ if(channels==3) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) {
+ copy_v3_v3(bufferIndex, srcFloatPxl);
+ F3TOCHAR4(bufferIndex, dstBytePxl);
+ bufferIndex[3] = 1.0;
+ }
+ }
+ }
+ else {
+ if (dither != 0.f) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ const float d = (BLI_frand()-0.5f)*dither;
+ copy_v4_v4(bufferIndex, srcFloatPxl);
+ add_v4_fl(bufferIndex,d);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ } else {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ copy_v4_v4(bufferIndex, srcFloatPxl);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ }
+ }
+ }
+ /* ensure user flag is reset */
+ ibuf->userflags &= ~IB_RECT_INVALID;
+}
+
static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
{
float *tof = fbuf;