summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2ea3680)
raw | patch | inline | side by side (parent: 2ea3680)
author | Jasper van de Gronde <jasper.vandegronde@gmail.com> | |
Tue, 18 May 2010 07:53:46 +0000 (09:53 +0200) | ||
committer | Jasper van de Gronde <jasper.vandegronde@gmail.com> | |
Tue, 18 May 2010 07:53:46 +0000 (09:53 +0200) |
src/libnr/nr-compose-transform.cpp | patch | blob | history | |
src/libnr/nr-pixops.h | patch | blob | history |
index e7c2865698f31ecef2c49387972e43238b573f2e..05852bf07859bee67a33942b89ad715fc7cc1a92 100644 (file)
int x, y;
if (alpha == 0) return;
+ if (alpha>255) {
+ g_warning("In transform PPN alpha=%u>255",alpha);
+ }
- // Both alpha and color components are stored temporarily with a range of [0,255^2], so more supersampling and we get an overflow
- if (xd+yd>16) {
- xd = 8;
- yd = 8;
+ // The color component is stored temporarily with a range of [0,255^3], so more supersampling and we get an overflow (fortunately Inkscape's preferences also doesn't allow a higher setting)
+ if (xd+yd>8) {
+ xd = 4;
+ yd = 4;
}
xsize = (1 << xd);
@@ -122,38 +125,42 @@ nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h,
if ((sy >= 0) && (sy < sh)) {
const unsigned char *s;
s = spx + sy * srs + sx * 4;
- r += NR_PREMUL_112 (s[0], s[3]);
+ r += NR_PREMUL_112 (s[0], s[3]); // s in [0,255]
g += NR_PREMUL_112 (s[1], s[3]);
b += NR_PREMUL_112 (s[2], s[3]);
a += s[3];
+ // a=sum(s3)
+ // r,g,b in [0,sum(s3)*255]
}
}
}
a = (a*alpha + rounding_fix) >> dbits;
+ // a=sum(s3)*alpha/size=avg(s3)*alpha
// Compare to nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P
if (a != 0) {
- r = (r + rounding_fix) >> dbits;
- g = (g + rounding_fix) >> dbits;
- b = (b + rounding_fix) >> dbits;
+ r = (r*alpha + rounding_fix) >> dbits;
+ g = (g*alpha + rounding_fix) >> dbits;
+ b = (b*alpha + rounding_fix) >> dbits;
+ // r,g,b in [0,avg(s3)*alpha*255]=[0,a*255]
if (a == 255*255) {
/* Full coverage, demul src */
- d[0] = NR_NORMALIZE_21(r);
- d[1] = NR_NORMALIZE_21(g);
- d[2] = NR_NORMALIZE_21(b);
+ d[0] = NR_NORMALIZE_31(r);
+ d[1] = NR_NORMALIZE_31(g);
+ d[2] = NR_NORMALIZE_31(b);
d[3] = NR_NORMALIZE_21(a);
} else if (d[3] == 0) {
/* Only foreground, demul src */
- d[0] = NR_DEMUL_221(r,a);
- d[1] = NR_DEMUL_221(g,a);
- d[2] = NR_DEMUL_221(b,a);
+ d[0] = NR_DEMUL_321(r,a);
+ d[1] = NR_DEMUL_321(g,a);
+ d[2] = NR_DEMUL_321(b,a);
d[3] = NR_NORMALIZE_21(a);
} else {
unsigned int ca;
/* Full composition */
ca = NR_COMPOSEA_213(a, d[3]);
- d[0] = NR_COMPOSEPNN_221131 (r, a, d[0], d[3], ca);
- d[1] = NR_COMPOSEPNN_221131 (g, a, d[1], d[3], ca);
- d[2] = NR_COMPOSEPNN_221131 (b, a, d[2], d[3], ca);
+ d[0] = NR_COMPOSEPNN_321131 (r, a, d[0], d[3], ca);
+ d[1] = NR_COMPOSEPNN_321131 (g, a, d[1], d[3], ca);
+ d[2] = NR_COMPOSEPNN_321131 (b, a, d[2], d[3], ca);
d[3] = NR_NORMALIZE_31(ca);
}
}
@@ -272,19 +279,19 @@ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h
}
a = (a*alpha + rounding_fix) >> dbits;
if (a != 0) {
- r = (r + rounding_fix) >> dbits;
- g = (g + rounding_fix) >> dbits;
- b = (b + rounding_fix) >> dbits;
+ r = (r*alpha + rounding_fix) >> dbits;
+ g = (g*alpha + rounding_fix) >> dbits;
+ b = (b*alpha + rounding_fix) >> dbits;
if ((a == 255*255) || (d[3] == 0)) {
/* Transparent BG, premul src */
- d[0] = NR_NORMALIZE_21(r);
- d[1] = NR_NORMALIZE_21(g);
- d[2] = NR_NORMALIZE_21(b);
+ d[0] = NR_NORMALIZE_31(r);
+ d[1] = NR_NORMALIZE_31(g);
+ d[2] = NR_NORMALIZE_31(b);
d[3] = NR_NORMALIZE_21(a);
} else {
- d[0] = NR_COMPOSEPPP_2211 (r, a, d[0]);
- d[1] = NR_COMPOSEPPP_2211 (g, a, d[1]);
- d[2] = NR_COMPOSEPPP_2211 (b, a, d[2]);
+ d[0] = NR_COMPOSEPPP_3211 (r, a, d[0]);
+ d[1] = NR_COMPOSEPPP_3211 (g, a, d[1]);
+ d[2] = NR_COMPOSEPPP_3211 (b, a, d[2]);
d[3] = NR_COMPOSEA_211(a, d[3]);
}
}
@@ -309,11 +316,14 @@ void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, in
int i;
if (alpha == 0) return;
+ if (alpha>255) {
+ g_warning("In transform PPN alpha=%u>255",alpha);
+ }
- // Both alpha and color components are stored temporarily with a range of [0,255^2], so more supersampling and we get an overflow
- if (xd+yd>16) {
- xd = 8;
- yd = 8;
+ // The color component is stored temporarily with a range of [0,255^3], so more supersampling and we get an overflow (fortunately Inkscape's preferences also doesn't allow a higher setting)
+ if (xd+yd>8) {
+ xd = 4;
+ yd = 4;
}
dbits = xd + yd;
diff --git a/src/libnr/nr-pixops.h b/src/libnr/nr-pixops.h
index 417e5e2c9e18df498a32700ccec7a5422723a205..7eafd1a9d368add0ece8dc9511982d5d99aaf4a1 100644 (file)
--- a/src/libnr/nr-pixops.h
+++ b/src/libnr/nr-pixops.h
static inline unsigned int NR_COMPOSENNP_11111(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba) { return NR_NORMALIZE_31(NR_COMPOSENNP_11113(fc, fa, bc, ba)); }
// Operation: (1 - fa) * bc * ba + fc
+static inline unsigned int NR_COMPOSEPNP_32114(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba) { return (255*255 - fa) * ba * bc + 255 * fc; }
static inline unsigned int NR_COMPOSEPNP_22114(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba) { return (255*255 - fa) * ba * bc + 255*255 * fc; }
static inline unsigned int NR_COMPOSEPNP_11113(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba) { return (255 - fa) * ba * bc + 255*255 * fc; }
static inline unsigned int NR_COMPOSEPNP_22111(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba) { return NR_NORMALIZE_41(NR_COMPOSEPNP_22114(fc, fa, bc, ba)); }
// Operation: ((1 - fa) * bc * ba + fc)/a
// Reuses non-normalized versions of NR_COMPOSEPNP
+static inline unsigned int NR_COMPOSEPNN_321131(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba, unsigned int a) { return DIV_ROUND(NR_COMPOSEPNP_32114(fc, fa, bc, ba), a); }
static inline unsigned int NR_COMPOSEPNN_221131(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba, unsigned int a) { return DIV_ROUND(NR_COMPOSEPNP_22114(fc, fa, bc, ba), a); }
static inline unsigned int NR_COMPOSEPNN_111121(unsigned int fc, unsigned int fa, unsigned int bc, unsigned int ba, unsigned int a) { return DIV_ROUND(NR_COMPOSEPNP_11113(fc, fa, bc, ba), a); }
// Operation: (1 - fa) * bc + fc
// (1-fa)*bc+fc = bc-fa*bc+fc = (bc+fc)-fa*bc
// This rewritten form results in faster code (found out through testing)
-static inline unsigned int NR_COMPOSEPPP_2224(unsigned int fc, unsigned int fa, unsigned int bc) { return 255*255*(bc+fc) - fa*bc; }
+static inline unsigned int NR_COMPOSEPPP_2224(unsigned int fc, unsigned int fa, unsigned int bc) { return 255*255*(bc+fc) - fa*bc; } // Note that this can temporarily overflow (but it probably doesn't cause problems)
// NR_COMPOSEPPP_2224 assumes that fa and fc have a common component (fa=a*x and fc=c*x), because then the maximum value is:
// (255*255-255*x)*255*255 + 255*x*255*255 = 255*255*( (255*255-255*x) + 255*x ) = 255*255*255*( (255-x)+x ) = 255*255*255*255
+static inline unsigned int NR_COMPOSEPPP_3213(unsigned int fc, unsigned int fa, unsigned int bc) { return 255*255*bc + fc - fa*bc; }
static inline unsigned int NR_COMPOSEPPP_2213(unsigned int fc, unsigned int fa, unsigned int bc) { return 255*(255*bc+fc) - fa*bc; }
static inline unsigned int NR_COMPOSEPPP_1213(unsigned int fc, unsigned int fa, unsigned int bc) { return 255*255*(bc+fc) - fa*bc; }
static inline unsigned int NR_COMPOSEPPP_1112(unsigned int fc, unsigned int fa, unsigned int bc) { return 255*(bc+fc) - fa*bc; }
static inline unsigned int NR_COMPOSEPPP_2221(unsigned int fc, unsigned int fa, unsigned int bc) { return NR_NORMALIZE_41(NR_COMPOSEPPP_2224(fc, fa, bc)); }
+static inline unsigned int NR_COMPOSEPPP_3211(unsigned int fc, unsigned int fa, unsigned int bc) { return NR_NORMALIZE_31(NR_COMPOSEPPP_3213(fc, fa, bc)); }
static inline unsigned int NR_COMPOSEPPP_2211(unsigned int fc, unsigned int fa, unsigned int bc) { return NR_NORMALIZE_31(NR_COMPOSEPPP_2213(fc, fa, bc)); }
static inline unsigned int NR_COMPOSEPPP_1211(unsigned int fc, unsigned int fa, unsigned int bc) { return NR_NORMALIZE_21(NR_COMPOSEPPP_1213(fc, fa, bc)); }
static inline unsigned int NR_COMPOSEPPP_1111(unsigned int fc, unsigned int fa, unsigned int bc) { return NR_NORMALIZE_21(NR_COMPOSEPPP_1112(fc, fa, bc)); }