Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Unified Diff: src/core/SkXfermode.cpp

Issue 12662006: This changes fixes issues with the non-separable blend modes. They were not producing the correct r… (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkXfermode.cpp
===================================================================
--- src/core/SkXfermode.cpp (revision 8084)
+++ src/core/SkXfermode.cpp (working copy)
@@ -290,57 +290,41 @@
static inline int colordodge_byte(int sc, int dc, int sa, int da) {
int diff = sa - sc;
int rc;
- if (0 == diff) {
+ if (0 == dc) {
+ return SkAlphaMulAlpha(sc, 255 - da);
+ } else if (0 == diff) {
rc = sa * da + sc * (255 - da) + dc * (255 - sa);
- rc = SkDiv255Round(rc);
} else {
- int tmp = (dc * sa << 15) / (da * diff);
- rc = SkDiv255Round(sa * da) * tmp >> 15;
- // don't clamp here, since we'll do it in our modeproc
+ diff = dc * sa / diff;
+ rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa);
}
- return rc;
+ return clamp_div255round(rc);
}
static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) {
- // added to avoid div-by-zero in colordodge_byte
- if (0 == dst) {
- return src;
- }
-
int sa = SkGetPackedA32(src);
int da = SkGetPackedA32(dst);
int a = srcover_byte(sa, da);
int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
- r = clamp_max(r, a);
- g = clamp_max(g, a);
- b = clamp_max(b, a);
return SkPackARGB32(a, r, g, b);
}
// kColorBurn_Mode
static inline int colorburn_byte(int sc, int dc, int sa, int da) {
int rc;
- if (dc == da && 0 == sc) {
- rc = sa * da + dc * (255 - sa);
+ if (dc == da) {
+ rc = sa * da + sc * (255 - da) + dc * (255 - sa);
} else if (0 == sc) {
return SkAlphaMulAlpha(dc, 255 - sa);
} else {
- int tmp = (sa * (da - dc) * 256) / (sc * da);
- if (tmp > 256) {
- tmp = 256;
- }
- int tmp2 = sa * da;
- rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa);
+ int tmp = (da - dc) * sa / sc;
+ rc = sa * (da - ((da < tmp) ? da : tmp))
+ + sc * (255 - da) + dc * (255 - sa);
}
- return SkDiv255Round(rc);
+ return clamp_div255round(rc);
}
static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) {
- // added to avoid div-by-zero in colorburn_byte
- if (0 == dst) {
- return src;
- }
-
int sa = SkGetPackedA32(src);
int da = SkGetPackedA32(dst);
int a = srcover_byte(sa, da);
@@ -438,7 +422,7 @@
// See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm
static inline int Lum(int r, int g, int b)
{
- return (r * 77 + g * 151 + b * 28) >> 8;
+ return SkDiv255Round(r * 77 + g * 150 + b * 28);
}
static inline int min2(int a, int b) { return a < b ? a : b; }
@@ -452,7 +436,7 @@
static inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) {
if(*Cmax > *Cmin) {
- *Cmid = (((*Cmid - *Cmin) * s ) / (*Cmax - *Cmin));
+ *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin);
*Cmax = s;
} else {
*Cmax = 0;
@@ -480,35 +464,35 @@
}
}
-static inline void clipColor(int* r, int* g, int* b) {
+static inline void clipColor(int* r, int* g, int* b, int a) {
int L = Lum(*r, *g, *b);
int n = minimum(*r, *g, *b);
int x = maximum(*r, *g, *b);
if(n < 0) {
- *r = L + (((*r - L) * L) / (L - n));
- *g = L + (((*g - L) * L) / (L - n));
- *b = L + (((*b - L) * L) / (L - n));
+ *r = L + SkMulDiv(*r - L, L, L - n);
+ *g = L + SkMulDiv(*g - L, L, L - n);
+ *b = L + SkMulDiv(*b - L, L, L - n);
}
- if(x > 255) {
- *r = L + (((*r - L) * (255 - L)) / (x - L));
- *g = L + (((*g - L) * (255 - L)) / (x - L));
- *b = L + (((*b - L) * (255 - L)) / (x - L));
+ if (x > a) {
+ *r = L + SkMulDiv(*r - L, a - L, x - L);
+ *g = L + SkMulDiv(*g - L, a - L, x - L);
+ *b = L + SkMulDiv(*b - L, a - L, x - L);
}
}
-static inline void SetLum(int* r, int* g, int* b, int l) {
+static inline void SetLum(int* r, int* g, int* b, int a, int l) {
int d = l - Lum(*r, *g, *b);
*r += d;
*g += d;
*b += d;
- clipColor(r, g, b);
+ clipColor(r, g, b, a);
}
// non-separable blend modes are done in non-premultiplied alpha
#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \
- clamp_div255round(sc * (255 - da) + dc * (255 - sa) + clamp_div255round(sa * da) * blendval)
+ clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval)
// kHue_Mode
// B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
@@ -526,14 +510,11 @@
int Sr, Sg, Sb;
if(sa && da) {
- Sr = SkMulDiv255Round(sr, sa);
- Sg = SkMulDiv255Round(sg, sa);
- Sb = SkMulDiv255Round(sb, sa);
- int Dr = SkMulDiv255Round(dr, da);
- int Dg = SkMulDiv255Round(dg, da);
- int Db = SkMulDiv255Round(db, da);
- SetSat(&Sr, &Sg, &Sb, Sat(Dr, Dg, Db));
- SetLum(&Sr, &Sg, &Sb, Lum(Dr, Dg, Db));
+ Sr = sr * sa;
+ Sg = sg * sa;
+ Sb = sb * sa;
+ SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa);
+ SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa);
} else {
Sr = 0;
Sg = 0;
@@ -563,15 +544,11 @@
int Dr, Dg, Db;
if(sa && da) {
- int Sr = SkMulDiv255Round(sr, sa);
- int Sg = SkMulDiv255Round(sg, sa);
- int Sb = SkMulDiv255Round(sb, sa);
- Dr = SkMulDiv255Round(dr, da);
- Dg = SkMulDiv255Round(dg, da);
- Db = SkMulDiv255Round(db, da);
- int LumD = Lum(Dr, Dg, Db);
- SetSat(&Dr, &Dg, &Db, Sat(Sr, Sg, Sb));
- SetLum(&Dr, &Dg, &Db, LumD);
+ Dr = dr * sa;
+ Dg = dg * sa;
+ Db = db * sa;
+ SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da);
+ SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa);
} else {
Dr = 0;
Dg = 0;
@@ -601,13 +578,10 @@
int Sr, Sg, Sb;
if(sa && da) {
- Sr = SkMulDiv255Round(sr, sa);
- Sg = SkMulDiv255Round(sg, sa);
- Sb = SkMulDiv255Round(sb, sa);
- int Dr = SkMulDiv255Round(dr, da);
- int Dg = SkMulDiv255Round(dg, da);
- int Db = SkMulDiv255Round(db, da);
- SetLum(&Sr, &Sg, &Sb, Lum(Dr, Dg, Db));
+ Sr = sr * da;
+ Sg = sg * da;
+ Sb = sb * da;
+ SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa);
} else {
Sr = 0;
Sg = 0;
@@ -637,13 +611,10 @@
int Dr, Dg, Db;
if(sa && da) {
- int Sr = SkMulDiv255Round(sr, sa);
- int Sg = SkMulDiv255Round(sg, sa);
- int Sb = SkMulDiv255Round(sb, sa);
- Dr = SkMulDiv255Round(dr, da);
- Dg = SkMulDiv255Round(dg, da);
- Db = SkMulDiv255Round(db, da);
- SetLum(&Dr, &Dg, &Db, Lum(Sr, Sg, Sb));
+ Dr = dr * sa;
+ Dg = dg * sa;
+ Db = db * sa;
+ SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da);
} else {
Dr = 0;
Dg = 0;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698