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

Side by Side Diff: src/core/SkColorSpaceXform.cpp

Issue 2341143002: YUV and color xforms
Patch Set: Created 4 years, 3 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 | « src/core/SkColorSpaceXform.h ('k') | 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 2016 Google Inc. 2 * Copyright 2016 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 "SkColorPriv.h" 8 #include "SkColorPriv.h"
9 #include "SkColorSpace_Base.h" 9 #include "SkColorSpace_Base.h"
10 #include "SkColorSpacePriv.h" 10 #include "SkColorSpacePriv.h"
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 default: 1322 default:
1323 SkASSERT(false); 1323 SkASSERT(false);
1324 return; 1324 return;
1325 } 1325 }
1326 default: 1326 default:
1327 SkASSERT(false); 1327 SkASSERT(false);
1328 return; 1328 return;
1329 } 1329 }
1330 } 1330 }
1331 1331
1332 static inline Sk4f srgb_to_linear(const Sk4f& x) {
1333 // Approximation of the sRGB gamma curve (within 1 when scaled to 8-bit pixe ls).
1334 // For 0.00000f <= x < 0.00349f, 12.92 * x
1335 // For 0.00349f <= x <= 1.00000f, 0.679*(x.^0.5) + 0.423*x.^(0.25) - 0.10 1
1336 // Note that 0.00349 was selected because it is a point where both functions produce the
1337 // same pixel value when rounded.
1338 auto y = (x + 0.055f) * (1.0f / 1.055f);
1339 auto twodotfive = y * y * y.rsqrt().invert();
1340 auto lo = ((1.0f / 12.92f)) * x;
1341 auto hi = twodotfive;
1342 auto out = (x < 0.04045f).thenElse(lo, hi);
1343 return out;
1344 }
1345
1346 template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
1347 void SkColorSpaceXform_Base<kSrc, kDst, kCSM>
1348 ::applyYUV(void* dst, const uint8_t* srcY, const uint8_t* srcU, const uint8_t* s rcV, int len)
1349 const
1350 {
1351 Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT;
1352 load_matrix(fSrcToDst, rXgXbX, rYgYbY, rZgZbZ, rTgTbT);
1353
1354 if (len >= 4) {
1355 // Naively this would be a loop of load-transform-store, but we found it faster to
1356 // move the N+1th load ahead of the Nth store. We don't bother doing th is for N<4.
1357 Sk4f r, g, b, a;
1358
1359 Sk4f y = (1.0f / 255.0f) * SkNx_cast<float, uint8_t>(Sk4b::Load(srcY));
1360 Sk4f u = (1.0f / 255.0f) * (SkNx_cast<float, uint8_t>(Sk4b::Load(srcU)) - 128.0f);
1361 Sk4f v = (1.0f / 255.0f) * (SkNx_cast<float, uint8_t>(Sk4b::Load(srcV)) - 128.0f);
1362
1363 r = (y + 1.402f * v);
1364 g = (y - 0.34414f * u - 0.71414f * v);
1365 b = (y + 1.772f * u);
1366
1367 r = srgb_to_linear(r);
1368 g = srgb_to_linear(g);
1369 b = srgb_to_linear(b);
1370
1371 srcY += 4;
1372 srcU += 4;
1373 srcV += 4;
1374 len -= 4;
1375
1376 Sk4f dr, dg, db, da;
1377 while (len >= 4) {
1378 transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da);
1379 translate_gamut(rTgTbT, dr, dg, db);
1380
1381 y = (1.0f / 255.0f) * SkNx_cast<float, uint8_t>(Sk4b::Load(srcY));
1382 u = (1.0f / 255.0f) * (SkNx_cast<float, uint8_t>(Sk4b::Load(srcU)) - 128.0f);
1383 v = (1.0f / 255.0f) * (SkNx_cast<float, uint8_t>(Sk4b::Load(srcV)) - 128.0f);
1384
1385 r = (y + 1.402f * v);
1386 g = (y - 0.34414f * u - 0.71414f * v);
1387 b = (y + 1.772f * u);
1388
1389 r = srgb_to_linear(r);
1390 g = srgb_to_linear(g);
1391 b = srgb_to_linear(b);
1392
1393 srcY += 4;
1394 srcU += 4;
1395 srcV += 4;
1396 len -= 4;
1397
1398 dr = sk_linear_to_srgb_needs_trunc(dr);
1399 dg = sk_linear_to_srgb_needs_trunc(dg);
1400 db = sk_linear_to_srgb_needs_trunc(db);
1401
1402 dr = sk_clamp_0_255(dr);
1403 dg = sk_clamp_0_255(dg);
1404 db = sk_clamp_0_255(db);
1405
1406 Sk4i rgba = (SkNx_cast<int>(dr) << 16)
1407 | (SkNx_cast<int>(dg) << 8)
1408 | (SkNx_cast<int>(db) << 0)
1409 | (0xFF << 24 );
1410 rgba.store(dst);
1411 dst = SkTAddOffset<void>(dst, 4 * 4);
1412 }
1413
1414 transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da);
1415 translate_gamut(rTgTbT, dr, dg, db);
1416
1417 dr = sk_linear_to_srgb_needs_trunc(dr);
1418 dg = sk_linear_to_srgb_needs_trunc(dg);
1419 db = sk_linear_to_srgb_needs_trunc(db);
1420
1421 dr = sk_clamp_0_255(dr);
1422 dg = sk_clamp_0_255(dg);
1423 db = sk_clamp_0_255(db);
1424
1425 Sk4i rgba = (SkNx_cast<int>(dr) << 16)
1426 | (SkNx_cast<int>(dg) << 8)
1427 | (SkNx_cast<int>(db) << 0)
1428 | (0xFF << 24 );
1429 rgba.store(dst);
1430 dst = SkTAddOffset<void>(dst, 4 * 4);
1431 }
1432 }
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1332 //////////////////////////////////////////////////////////////////////////////// /////////////////// 1499 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1333 1500
1334 std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(const sk_sp<SkColorSpace>& space) { 1501 std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(const sk_sp<SkColorSpace>& space) {
1335 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 1502 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
1336 <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 1503 <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
1337 (space, SkMatrix::I(), space)); 1504 (space, SkMatrix::I(), space));
1338 } 1505 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698