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

Side by Side Diff: third_party/lcms2-2.6/src/cmsopt.c

Issue 2538703002: lcms: avoid fixed number LUT optimization on inf values (Closed)
Patch Set: rebase Created 4 years 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 | « third_party/lcms2-2.6/README.pdfium ('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 // 2 //
3 // Little Color Management System 3 // Little Color Management System
4 // Copyright (c) 1998-2011 Marti Maria Saguer 4 // Copyright (c) 1998-2011 Marti Maria Saguer
5 // 5 //
6 // Permission is hereby granted, free of charge, to any person obtaining 6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the "Software"), 7 // a copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation 8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the Softwar e 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar e
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 1436
1437 // And across second shaper, 1437 // And across second shaper,
1438 Out[0] = p->Shaper2R[ri]; 1438 Out[0] = p->Shaper2R[ri];
1439 Out[1] = p->Shaper2G[gi]; 1439 Out[1] = p->Shaper2G[gi];
1440 Out[2] = p->Shaper2B[bi]; 1440 Out[2] = p->Shaper2B[bi];
1441 1441
1442 } 1442 }
1443 1443
1444 // This table converts from 8 bits to 1.14 after applying the curve 1444 // This table converts from 8 bits to 1.14 after applying the curve
1445 static 1445 static
1446 void FillFirstShaper(cmsS1Fixed14Number* Table, cmsToneCurve* Curve) 1446 cmsBool FillFirstShaper(cmsS1Fixed14Number* Table, cmsToneCurve* Curve)
1447 { 1447 {
1448 int i; 1448 int i;
1449 cmsFloat32Number R, y; 1449 cmsFloat32Number R, y;
1450 1450
1451 for (i=0; i < 256; i++) { 1451 for (i=0; i < 256; i++) {
1452 1452
1453 R = (cmsFloat32Number) (i / 255.0); 1453 R = (cmsFloat32Number) (i / 255.0);
1454 y = cmsEvalToneCurveFloat(Curve, R); 1454 y = cmsEvalToneCurveFloat(Curve, R);
1455 if (isinf(y))
1456 return FALSE;
1455 1457
1456 Table[i] = DOUBLE_TO_1FIXED14(y); 1458 Table[i] = DOUBLE_TO_1FIXED14(y);
1457 } 1459 }
1460 return TRUE;
1458 } 1461 }
1459 1462
1460 // This table converts form 1.14 (being 0x4000 the last entry) to 8 bits after a pplying the curve 1463 // This table converts form 1.14 (being 0x4000 the last entry) to 8 bits after a pplying the curve
1461 static 1464 static
1462 void FillSecondShaper(cmsUInt16Number* Table, cmsToneCurve* Curve, cmsBool Is8Bi tsOutput) 1465 cmsBool FillSecondShaper(cmsUInt16Number* Table, cmsToneCurve* Curve, cmsBool Is 8BitsOutput)
1463 { 1466 {
1464 int i; 1467 int i;
1465 cmsFloat32Number R, Val; 1468 cmsFloat32Number R, Val;
1466 1469
1467 for (i=0; i < 16385; i++) { 1470 for (i=0; i < 16385; i++) {
1468 1471
1469 R = (cmsFloat32Number) (i / 16384.0); 1472 R = (cmsFloat32Number) (i / 16384.0);
1470 Val = cmsEvalToneCurveFloat(Curve, R); // Val comes 0..1.0 1473 Val = cmsEvalToneCurveFloat(Curve, R); // Val comes 0..1.0
1474 if (isinf(Val))
1475 return FALSE;
1471 1476
1472 if (Is8BitsOutput) { 1477 if (Is8BitsOutput) {
1473 1478
1474 // If 8 bits output, we can optimize further by computing the / 257 part. 1479 // If 8 bits output, we can optimize further by computing the / 257 part.
1475 // first we compute the resulting byte and then we store the byte ti mes 1480 // first we compute the resulting byte and then we store the byte ti mes
1476 // 257. This quantization allows to round very quick by doing a >> 8 , but 1481 // 257. This quantization allows to round very quick by doing a >> 8 , but
1477 // since the low byte is always equal to msb, we can do a & 0xff and this works! 1482 // since the low byte is always equal to msb, we can do a & 0xff and this works!
1478 cmsUInt16Number w = _cmsQuickSaturateWord(Val * 65535.0); 1483 cmsUInt16Number w = _cmsQuickSaturateWord(Val * 65535.0);
1479 cmsUInt8Number b = FROM_16_TO_8(w); 1484 cmsUInt8Number b = FROM_16_TO_8(w);
1480 1485
1481 Table[i] = FROM_8_TO_16(b); 1486 Table[i] = FROM_8_TO_16(b);
1482 } 1487 }
1483 else Table[i] = _cmsQuickSaturateWord(Val * 65535.0); 1488 else Table[i] = _cmsQuickSaturateWord(Val * 65535.0);
1484 } 1489 }
1490 return TRUE;
1485 } 1491 }
1486 1492
1487 // Compute the matrix-shaper structure 1493 // Compute the matrix-shaper structure
1488 static 1494 static
1489 cmsBool SetMatShaper(cmsPipeline* Dest, cmsToneCurve* Curve1[3], cmsMAT3* Mat, c msVEC3* Off, cmsToneCurve* Curve2[3], cmsUInt32Number* OutputFormat) 1495 cmsBool SetMatShaper(cmsPipeline* Dest, cmsToneCurve* Curve1[3], cmsMAT3* Mat, c msVEC3* Off, cmsToneCurve* Curve2[3], cmsUInt32Number* OutputFormat)
1490 { 1496 {
1491 MatShaper8Data* p; 1497 MatShaper8Data* p;
1492 int i, j; 1498 int i, j;
1493 cmsBool Is8Bits = _cmsFormatterIs8bit(*OutputFormat); 1499 cmsBool Is8Bits = _cmsFormatterIs8bit(*OutputFormat);
1494 1500
1495 // Allocate a big chuck of memory to store precomputed tables 1501 // Allocate a big chuck of memory to store precomputed tables
1496 p = (MatShaper8Data*) _cmsMalloc(Dest ->ContextID, sizeof(MatShaper8Data)); 1502 p = (MatShaper8Data*) _cmsMalloc(Dest ->ContextID, sizeof(MatShaper8Data));
1497 if (p == NULL) return FALSE; 1503 if (p == NULL) return FALSE;
1498 1504
1499 p -> ContextID = Dest -> ContextID; 1505 p -> ContextID = Dest -> ContextID;
1500 1506
1501 // Precompute tables 1507 // Precompute tables
1502 FillFirstShaper(p ->Shaper1R, Curve1[0]); 1508 if (!FillFirstShaper(p ->Shaper1R, Curve1[0]))
1503 FillFirstShaper(p ->Shaper1G, Curve1[1]); 1509 goto Error;
1504 FillFirstShaper(p ->Shaper1B, Curve1[2]); 1510 if (!FillFirstShaper(p ->Shaper1G, Curve1[1]))
1511 goto Error;
1512 if (!FillFirstShaper(p ->Shaper1B, Curve1[2]))
1513 goto Error;
1505 1514
1506 FillSecondShaper(p ->Shaper2R, Curve2[0], Is8Bits); 1515 if (!FillSecondShaper(p ->Shaper2R, Curve2[0], Is8Bits))
1507 FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits); 1516 goto Error;
1508 FillSecondShaper(p ->Shaper2B, Curve2[2], Is8Bits); 1517 if (!FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits))
1518 goto Error;
1519 if (!FillSecondShaper(p ->Shaper2B, Curve2[2], Is8Bits))
1520 goto Error;
1509 1521
1510 // Convert matrix to nFixed14. Note that those values may take more than 16 bits as 1522 // Convert matrix to nFixed14. Note that those values may take more than 16 bits as
1511 for (i=0; i < 3; i++) { 1523 for (i=0; i < 3; i++) {
1512 for (j=0; j < 3; j++) { 1524 for (j=0; j < 3; j++) {
1513 p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]); 1525 p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]);
1514 } 1526 }
1515 } 1527 }
1516 1528
1517 for (i=0; i < 3; i++) { 1529 for (i=0; i < 3; i++) {
1518 1530
1519 if (Off == NULL) { 1531 if (Off == NULL) {
1520 p ->Off[i] = 0; 1532 p ->Off[i] = 0;
1521 } 1533 }
1522 else { 1534 else {
1523 p ->Off[i] = DOUBLE_TO_1FIXED14(Off->n[i]); 1535 p ->Off[i] = DOUBLE_TO_1FIXED14(Off->n[i]);
1524 } 1536 }
1525 } 1537 }
1526 1538
1527 // Mark as optimized for faster formatter 1539 // Mark as optimized for faster formatter
1528 if (Is8Bits) 1540 if (Is8Bits)
1529 *OutputFormat |= OPTIMIZED_SH(1); 1541 *OutputFormat |= OPTIMIZED_SH(1);
1530 1542
1531 // Fill function pointers 1543 // Fill function pointers
1532 _cmsPipelineSetOptimizationParameters(Dest, MatShaperEval16, (void*) p, Free MatShaper, DupMatShaper); 1544 _cmsPipelineSetOptimizationParameters(Dest, MatShaperEval16, (void*) p, Free MatShaper, DupMatShaper);
1533 return TRUE; 1545 return TRUE;
1546 Error:
1547 _cmsFree(Dest->ContextID, p);
1548 return FALSE;
1534 } 1549 }
1535 1550
1536 // 8 bits on input allows matrix-shaper boot up to 25 Mpixels per second on RGB . That's fast! 1551 // 8 bits on input allows matrix-shaper boot up to 25 Mpixels per second on RGB . That's fast!
1537 // TODO: Allow a third matrix for abs. colorimetric 1552 // TODO: Allow a third matrix for abs. colorimetric
1538 static 1553 static
1539 cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 2Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) 1554 cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3 2Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
1540 { 1555 {
1541 cmsStage* Curve1, *Curve2; 1556 cmsStage* Curve1, *Curve2;
1542 cmsStage* Matrix1, *Matrix2; 1557 cmsStage* Matrix1, *Matrix2;
1543 _cmsStageMatrixData* Data1; 1558 _cmsStageMatrixData* Data1;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 } 1614 }
1600 else { 1615 else {
1601 _cmsStageToneCurvesData* mpeC1 = (_cmsStageToneCurvesData*) cmsStageData (Curve1); 1616 _cmsStageToneCurvesData* mpeC1 = (_cmsStageToneCurvesData*) cmsStageData (Curve1);
1602 _cmsStageToneCurvesData* mpeC2 = (_cmsStageToneCurvesData*) cmsStageData (Curve2); 1617 _cmsStageToneCurvesData* mpeC2 = (_cmsStageToneCurvesData*) cmsStageData (Curve2);
1603 1618
1604 // In this particular optimization, cach?does not help as it takes more time to deal with 1619 // In this particular optimization, cach?does not help as it takes more time to deal with
1605 // the cach?that with the pixel handling 1620 // the cach?that with the pixel handling
1606 *dwFlags |= cmsFLAGS_NOCACHE; 1621 *dwFlags |= cmsFLAGS_NOCACHE;
1607 1622
1608 // Setup the optimizarion routines 1623 // Setup the optimizarion routines
1609 SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Data2 ->Offset, m peC2->TheCurves, OutputFormat); 1624 if (!SetMatShaper(Dest, mpeC1 ->TheCurves, &res, (cmsVEC3*) Data2 ->Offs et, mpeC2->TheCurves, OutputFormat))
1625 goto Error;
1610 } 1626 }
1611 1627
1612 cmsPipelineFree(Src); 1628 cmsPipelineFree(Src);
1613 *Lut = Dest; 1629 *Lut = Dest;
1614 return TRUE; 1630 return TRUE;
1615 Error: 1631 Error:
1616 // Leave Src unchanged 1632 // Leave Src unchanged
1617 cmsPipelineFree(Dest); 1633 cmsPipelineFree(Dest);
1618 return FALSE; 1634 return FALSE;
1619 } 1635 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 1802
1787 if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dw Flags)) { 1803 if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dw Flags)) {
1788 1804
1789 return TRUE; 1805 return TRUE;
1790 } 1806 }
1791 } 1807 }
1792 1808
1793 // Only simple optimizations succeeded 1809 // Only simple optimizations succeeded
1794 return AnySuccess; 1810 return AnySuccess;
1795 } 1811 }
OLDNEW
« no previous file with comments | « third_party/lcms2-2.6/README.pdfium ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698