| Index: src/core/SkColorSpaceXform.cpp
|
| diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
|
| index 0faff88286d592a3a660b4abaf4d2d3c7e7fe5bf..e14201130579f7753ad120ec5cc0741c77d076a8 100644
|
| --- a/src/core/SkColorSpaceXform.cpp
|
| +++ b/src/core/SkColorSpaceXform.cpp
|
| @@ -152,22 +152,27 @@ void SkDefaultXform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_
|
| // be simpler and faster than our current approach.
|
| float srcFloats[3];
|
| for (int i = 0; i < 3; i++) {
|
| - const SkGammaCurve& gamma = (*fSrcGammas)[i];
|
| uint8_t byte = (*src >> (8 * i)) & 0xFF;
|
| - if (gamma.isValue()) {
|
| - srcFloats[i] = pow(byte_to_float(byte), gamma.fValue);
|
| - } else if (gamma.isTable()) {
|
| - srcFloats[i] = interp_lut(byte, gamma.fTable.get(), gamma.fTableSize);
|
| - } else {
|
| - SkASSERT(gamma.isParametric());
|
| - float component = byte_to_float(byte);
|
| - if (component < gamma.fD) {
|
| - // Y = E * X + F
|
| - srcFloats[i] = gamma.fE * component + gamma.fF;
|
| + if (fSrcGammas) {
|
| + const SkGammaCurve& gamma = (*fSrcGammas)[i];
|
| + if (gamma.isValue()) {
|
| + srcFloats[i] = powf(byte_to_float(byte), gamma.fValue);
|
| + } else if (gamma.isTable()) {
|
| + srcFloats[i] = interp_lut(byte, gamma.fTable.get(), gamma.fTableSize);
|
| } else {
|
| - // Y = (A * X + B)^G + C
|
| - srcFloats[i] = pow(gamma.fA * component + gamma.fB, gamma.fG) + gamma.fC;
|
| + SkASSERT(gamma.isParametric());
|
| + float component = byte_to_float(byte);
|
| + if (component < gamma.fD) {
|
| + // Y = E * X + F
|
| + srcFloats[i] = gamma.fE * component + gamma.fF;
|
| + } else {
|
| + // Y = (A * X + B)^G + C
|
| + srcFloats[i] = powf(gamma.fA * component + gamma.fB, gamma.fG) + gamma.fC;
|
| + }
|
| }
|
| + } else {
|
| + // FIXME: Handle named gammas.
|
| + srcFloats[i] = powf(byte_to_float(byte), 2.2f);
|
| }
|
| }
|
|
|
| @@ -189,48 +194,54 @@ void SkDefaultXform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_
|
| // QCMS builds a large float lookup table from the gamma info. Is this faster or
|
| // better than our approach?
|
| for (int i = 0; i < 3; i++) {
|
| - const SkGammaCurve& gamma = (*fDstGammas)[i];
|
| - if (gamma.isValue()) {
|
| - dstFloats[i] = pow(dstFloats[i], 1.0f / gamma.fValue);
|
| - } else if (gamma.isTable()) {
|
| - // FIXME (msarett):
|
| - // An inverse table lookup is particularly strange and non-optimal.
|
| - dstFloats[i] = interp_lut_inv(dstFloats[i], gamma.fTable.get(), gamma.fTableSize);
|
| - } else {
|
| - SkASSERT(gamma.isParametric());
|
| - // FIXME (msarett):
|
| - // This is a placeholder implementation for inverting parametric gammas.
|
| - // First, I need to verify if there are actually destination profiles that
|
| - // require this functionality. Next, I need to explore other possibilities
|
| - // for this implementation. The LUT based approach in QCMS would be a good
|
| - // place to start.
|
| -
|
| - // We need to take the inverse of a piecewise function. Assume that
|
| - // the gamma function is continuous, or this won't make much sense
|
| - // anyway.
|
| - // Plug in |fD| to the first equation to calculate the new piecewise
|
| - // interval. Then simply use the inverse of the original functions.
|
| - float interval = gamma.fE * gamma.fD + gamma.fF;
|
| - if (dstFloats[i] < interval) {
|
| - // X = (Y - F) / E
|
| - if (0.0f == gamma.fE) {
|
| - // The gamma curve for this segment is constant, so the inverse
|
| - // is undefined.
|
| - dstFloats[i] = 0.0f;
|
| - } else {
|
| - dstFloats[i] = (dstFloats[i] - gamma.fF) / gamma.fE;
|
| - }
|
| + if (fDstGammas) {
|
| + const SkGammaCurve& gamma = (*fDstGammas)[i];
|
| + if (gamma.isValue()) {
|
| + dstFloats[i] = powf(dstFloats[i], 1.0f / gamma.fValue);
|
| + } else if (gamma.isTable()) {
|
| + // FIXME (msarett):
|
| + // An inverse table lookup is particularly strange and non-optimal.
|
| + dstFloats[i] = interp_lut_inv(dstFloats[i], gamma.fTable.get(),
|
| + gamma.fTableSize);
|
| } else {
|
| - // X = ((Y - C)^(1 / G) - B) / A
|
| - if (0.0f == gamma.fA || 0.0f == gamma.fG) {
|
| - // The gamma curve for this segment is constant, so the inverse
|
| - // is undefined.
|
| - dstFloats[i] = 0.0f;
|
| + SkASSERT(gamma.isParametric());
|
| + // FIXME (msarett):
|
| + // This is a placeholder implementation for inverting parametric gammas.
|
| + // First, I need to verify if there are actually destination profiles that
|
| + // require this functionality. Next, I need to explore other possibilities
|
| + // for this implementation. The LUT based approach in QCMS would be a good
|
| + // place to start.
|
| +
|
| + // We need to take the inverse of a piecewise function. Assume that
|
| + // the gamma function is continuous, or this won't make much sense
|
| + // anyway.
|
| + // Plug in |fD| to the first equation to calculate the new piecewise
|
| + // interval. Then simply use the inverse of the original functions.
|
| + float interval = gamma.fE * gamma.fD + gamma.fF;
|
| + if (dstFloats[i] < interval) {
|
| + // X = (Y - F) / E
|
| + if (0.0f == gamma.fE) {
|
| + // The gamma curve for this segment is constant, so the inverse
|
| + // is undefined.
|
| + dstFloats[i] = 0.0f;
|
| + } else {
|
| + dstFloats[i] = (dstFloats[i] - gamma.fF) / gamma.fE;
|
| + }
|
| } else {
|
| - dstFloats[i] = (pow(dstFloats[i] - gamma.fC, 1.0f / gamma.fG) - gamma.fB)
|
| - / gamma.fA;
|
| + // X = ((Y - C)^(1 / G) - B) / A
|
| + if (0.0f == gamma.fA || 0.0f == gamma.fG) {
|
| + // The gamma curve for this segment is constant, so the inverse
|
| + // is undefined.
|
| + dstFloats[i] = 0.0f;
|
| + } else {
|
| + dstFloats[i] = (powf(dstFloats[i] - gamma.fC, 1.0f / gamma.fG) -
|
| + gamma.fB) / gamma.fA;
|
| + }
|
| }
|
| }
|
| + } else {
|
| + // FIXME: Handle named gammas.
|
| + dstFloats[i] = powf(dstFloats[i], 1.0f / 2.2f);
|
| }
|
| }
|
|
|
|
|