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:
authorCampbell Barton <ideasman42@gmail.com>2010-12-01 05:54:10 +0300
committerCampbell Barton <ideasman42@gmail.com>2010-12-01 05:54:10 +0300
commitf801b2bcba276a26a68accb9167798c4facb9275 (patch)
tree64ea3576e772dff74146d58933a2beacdb95968d /source/blender/imbuf/intern/divers.c
parentad0dd98f26bc681c92a0a1893c17a3bc484a0cb5 (diff)
bugfix [#23406] DPX Images load darker then saved, UI broken.
- a linear float buffer was being created and saved into a non-linear DPX/Cineon file. - removed the UI since the settings are not used at the moment. added a utility function IMB_float_profile_ensure(), which returns a float buffer in the requested profile, using the existing if needed or returning an allocated buffer if the profile is different to that of the ImBuf. - Useful this case where the save function has its own linear setting.
Diffstat (limited to 'source/blender/imbuf/intern/divers.c')
-rw-r--r--source/blender/imbuf/intern/divers.c116
1 files changed, 86 insertions, 30 deletions
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 245dcfb7fae..f2803737377 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -40,6 +40,8 @@
#include "BKE_utildefines.h"
#include "BKE_colortools.h"
+#include "MEM_guardedalloc.h"
+
void IMB_de_interlace(struct ImBuf *ibuf)
{
struct ImBuf * tbuf1, * tbuf2;
@@ -187,13 +189,47 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
}
}
+static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
+{
+ float *tof = fbuf;
+ int i;
+ unsigned char *to = (unsigned char *) ibuf->rect;
+
+ for (i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ tof[0] = ((float)to[0])*(1.0f/255.0f);
+ tof[1] = ((float)to[1])*(1.0f/255.0f);
+ tof[2] = ((float)to[2])*(1.0f/255.0f);
+ tof[3] = ((float)to[3])*(1.0f/255.0f);
+ to += 4;
+ tof += 4;
+ }
+}
+
+
+static void imb_float_from_rect_linear(struct ImBuf *ibuf, float *fbuf)
+{
+ float *tof = fbuf;
+ int i;
+ unsigned char *to = (unsigned char *) ibuf->rect;
+
+ for (i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
+ tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
+ tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
+ tof[3] = ((float)to[3])*(1.0f/255.0f);
+ to += 4;
+ tof += 4;
+ }
+}
+
void IMB_float_from_rect(struct ImBuf *ibuf)
{
/* quick method to convert byte to floatbuf */
float *tof = ibuf->rect_float;
- int i;
+
unsigned char *to = (unsigned char *) ibuf->rect;
-
if(to==NULL) return;
if(tof==NULL) {
if (imb_addrectfloatImBuf(ibuf) == 0) return;
@@ -205,41 +241,16 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
if (ibuf->profile != IB_PROFILE_NONE) {
/* if the image has been given a profile then we're working
* with color management in mind, so convert it to linear space */
-
- for (i = ibuf->x * ibuf->y; i > 0; i--)
- {
- tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
- tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
- tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
- tof[3] = ((float)to[3])*(1.0f/255.0f);
- to += 4;
- tof += 4;
- }
+ imb_float_from_rect_linear(ibuf, ibuf->rect_float);
} else {
- for (i = ibuf->x * ibuf->y; i > 0; i--)
- {
- tof[0] = ((float)to[0])*(1.0f/255.0f);
- tof[1] = ((float)to[1])*(1.0f/255.0f);
- tof[2] = ((float)to[2])*(1.0f/255.0f);
- tof[3] = ((float)to[3])*(1.0f/255.0f);
- to += 4;
- tof += 4;
- }
+ imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
}
}
/* no profile conversion */
void IMB_float_from_rect_simple(struct ImBuf *ibuf)
{
- int profile = IB_PROFILE_NONE;
-
- /* no color management:
- * don't disturb the existing profiles */
- SWAP(int, ibuf->profile, profile);
-
- IMB_float_from_rect(ibuf);
-
- SWAP(int, ibuf->profile, profile);
+ imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
}
void IMB_convert_profile(struct ImBuf *ibuf, int profile)
@@ -299,3 +310,48 @@ void IMB_convert_profile(struct ImBuf *ibuf, int profile)
ibuf->profile= profile;
}
+
+/* use when you need to get a buffer with a certain profile
+ * if the return */
+float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
+{
+ /* stupid but it works like this everywhere now */
+ const short is_lin_from= (ibuf->profile != IB_PROFILE_NONE);
+ const short is_lin_to= (profile != IB_PROFILE_NONE);
+
+
+ if(is_lin_from == is_lin_to) {
+ *alloc= 0;
+
+ /* simple case, just allocate the buffer and return */
+ if(ibuf->rect_float == NULL) {
+ IMB_float_from_rect(ibuf);
+ }
+
+ return ibuf->rect_float;
+ }
+ else {
+ /* conversion is needed, first check */
+ float *fbuf= MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure");
+ *alloc= 1;
+
+ if(ibuf->rect_float == NULL) {
+ if(is_lin_to) {
+ imb_float_from_rect_linear(ibuf, fbuf);
+ }
+ else {
+ imb_float_from_rect_nonlinear(ibuf, fbuf);
+ }
+ }
+ else {
+ if(is_lin_to) { /* lin -> nonlin */
+ linearrgb_to_srgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y);
+ }
+ else { /* nonlin -> lin */
+ srgb_to_linearrgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y);
+ }
+ }
+
+ return fbuf;
+ }
+}