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

Side by Side Diff: src/effects/SkColorMatrixFilter.cpp

Issue 1041203004: clamp matrix-translate before converting to pmcolor (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 8 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkColorMatrixFilter.h" 8 #include "SkColorMatrixFilter.h"
9 #include "SkColorMatrix.h" 9 #include "SkColorMatrix.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 #endif 265 #endif
266 266
267 return pm; 267 return pm;
268 } 268 }
269 269
270 static Sk4s unpremul(const SkPMFloat& pm) { 270 static Sk4s unpremul(const SkPMFloat& pm) {
271 float scale = 255 / pm.a(); // candidate for fast/approx invert? 271 float scale = 255 / pm.a(); // candidate for fast/approx invert?
272 return Sk4s(pm) * Sk4s(scale, scale, scale, 1); 272 return Sk4s(pm) * Sk4s(scale, scale, scale, 1);
273 } 273 }
274 274
275 static Sk4f clamp_0_255(const Sk4f& value) {
276 return Sk4f::Max(Sk4f::Min(value, Sk4f(255)), Sk4f(0));
277 }
278
275 void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const { 279 void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
276 Proc proc = fProc; 280 Proc proc = fProc;
277 if (NULL == proc) { 281 if (NULL == proc) {
278 if (src != dst) { 282 if (src != dst) {
279 memcpy(dst, src, count * sizeof(SkPMColor)); 283 memcpy(dst, src, count * sizeof(SkPMColor));
280 } 284 }
281 return; 285 return;
282 } 286 }
283 287
284 #ifdef SK_SUPPORT_LEGACY_INT_COLORMATRIX 288 #ifdef SK_SUPPORT_LEGACY_INT_COLORMATRIX
285 const bool use_floats = false; 289 const bool use_floats = false;
286 #else 290 #else
287 const bool use_floats = true; 291 const bool use_floats = true;
288 #endif 292 #endif
289 293
290 if (use_floats) { 294 if (use_floats) {
291 const Sk4s c0 = Sk4s::Load(fTranspose + 0); 295 const Sk4s c0 = Sk4s::Load(fTranspose + 0);
292 const Sk4s c1 = Sk4s::Load(fTranspose + 4); 296 const Sk4s c1 = Sk4s::Load(fTranspose + 4);
293 const Sk4s c2 = Sk4s::Load(fTranspose + 8); 297 const Sk4s c2 = Sk4s::Load(fTranspose + 8);
294 const Sk4s c3 = Sk4s::Load(fTranspose + 12); 298 const Sk4s c3 = Sk4s::Load(fTranspose + 12);
295 const Sk4s c4 = Sk4s::Load(fTranspose + 16); // translates 299 const Sk4s c4 = Sk4s::Load(fTranspose + 16); // translates
296 300
297 SkPMColor matrix_translate_pmcolor = SkPMFloat(premul(c4)).clamped(); 301 // todo: we could cache this in the constructor...
302 SkPMColor matrix_translate_pmcolor = SkPMFloat(premul(clamp_0_255(c4))). clamped();
298 303
299 for (int i = 0; i < count; i++) { 304 for (int i = 0; i < count; i++) {
300 const SkPMColor src_c = src[i]; 305 const SkPMColor src_c = src[i];
301 if (0 == src_c) { 306 if (0 == src_c) {
302 dst[i] = matrix_translate_pmcolor; 307 dst[i] = matrix_translate_pmcolor;
303 continue; 308 continue;
304 } 309 }
305 310
306 SkPMFloat srcf(src_c); 311 SkPMFloat srcf(src_c);
307 312
308 if (0xFF != SkGetPackedA32(src_c)) { 313 if (0xFF != SkGetPackedA32(src_c)) {
309 srcf = unpremul(srcf); 314 srcf = unpremul(srcf);
310 } 315 }
311 316
312 Sk4s r4 = Sk4s(srcf.r()); 317 Sk4s r4 = Sk4s(srcf.r());
313 Sk4s g4 = Sk4s(srcf.g()); 318 Sk4s g4 = Sk4s(srcf.g());
314 Sk4s b4 = Sk4s(srcf.b()); 319 Sk4s b4 = Sk4s(srcf.b());
315 Sk4s a4 = Sk4s(srcf.a()); 320 Sk4s a4 = Sk4s(srcf.a());
316 321
317 // apply matrix 322 // apply matrix
318 Sk4s dst4 = c0 * r4 + c1 * g4 + c2 * b4 + c3 * a4 + c4; 323 Sk4s dst4 = c0 * r4 + c1 * g4 + c2 * b4 + c3 * a4 + c4;
319 324
320 // pin before re-premul (convention for color-matrix???) 325 // clamp, re-premul, and write
321 dst4 = Sk4s::Max(Sk4s(0), Sk4s::Min(Sk4s(255), dst4)); 326 dst[i] = SkPMFloat(premul(clamp_0_255(dst4))).get();
322
323 // re-premul and write
324 dst[i] = SkPMFloat(premul(dst4)).get();
325 } 327 }
326 } else { 328 } else {
327 const State& state = fState; 329 const State& state = fState;
328 int32_t result[4]; 330 int32_t result[4];
329 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); 331 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
330 332
331 for (int i = 0; i < count; i++) { 333 for (int i = 0; i < count; i++) {
332 SkPMColor c = src[i]; 334 SkPMColor c = src[i];
333 335
334 unsigned r = SkGetPackedR32(c); 336 unsigned r = SkGetPackedR32(c);
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 str->append("matrix: ("); 577 str->append("matrix: (");
576 for (int i = 0; i < 20; ++i) { 578 for (int i = 0; i < 20; ++i) {
577 str->appendScalar(fMatrix.fMat[i]); 579 str->appendScalar(fMatrix.fMat[i]);
578 if (i < 19) { 580 if (i < 19) {
579 str->append(", "); 581 str->append(", ");
580 } 582 }
581 } 583 }
582 str->append(")"); 584 str->append(")");
583 } 585 }
584 #endif 586 #endif
OLDNEW
« 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