Exemple #1
0
GammaCurvePtr GammaCurve::GetMatching(const GammaCurvePtr& newInstance)
{
    GammaCurvePtr oldInstance;
    bool cached = false;

    // See if we have a matching gamma curve in our chache already

#if POV_MULTITHREADED
    // make sure the cache doesn't get tampered with while we're working on it
    boost::mutex::scoped_lock lock(cacheMutex);
#endif

    // Check if we already have created a matching gamma curve object; if so, return that object instead.
    // Also, make sure we get the new object stored (as we're using weak pointers, we may have stale entries;
    // it also won't hurt if we store the new instance, even if we decide to discard it)
    for(list<weak_ptr<GammaCurve> >::iterator i(cache.begin()); i != cache.end(); i++)
    {
        oldInstance = (*i).lock();
        if (!oldInstance)
        {
            // Found a stale entry in the cache where we could store the new instance, in case we don't find any match.
            // As the cache uses weak pointers, we can just as well store the new instance now right away,
            // and leave it up to the weak pointer mechanism to clean up in case we find an existing instance.
            if (!cached)
                (*i) = newInstance;
            cached = true;
        }
        else if (oldInstance->Matches(newInstance))
        {
            // Found a matching curve in the cache, so use that instead, and (as far as we're concerned)
            // just forget that the new instance ever existed (allowing the shared_ptr mechanism to garbage-collect it)
            return oldInstance;
        }
    }

    // No matching gamma curve in the cache yet

    // Store the new entry in the cache if we haven't done so already.
    if (!cached)
        cache.push_back(newInstance);

    return newInstance;
}
Exemple #2
0
GammaCurvePtr TranscodingGammaCurve::Get(const GammaCurvePtr& working, const GammaCurvePtr& encoding)
{
    // if the working gamma space is linear, we only need the encoding gamma
    if (GammaCurve::IsNeutral(working))
        return GammaCurvePtr(encoding);
    // if both gamma spaces are the same, we can replace them with a neutral gamma curve
    if (working->Matches(encoding))
        return NeutralGammaCurve::Get();
    // check if we can replace the combination of gamma curves with a single power-law gamma curve
    PowerLawGammaCurve* powerLawWork = dynamic_cast<PowerLawGammaCurve*>(working.get());
    if (powerLawWork)
    {
        // if the encoding gamma space is linear, we only need the inverse of the working gamma
        if (GammaCurve::IsNeutral(encoding))
            return PowerLawGammaCurve::GetByEncodingGamma(powerLawWork->ApproximateDecodingGamma());
        // if both gamma spaces are based on a simple power-law, we only need to combine them into a single one
        PowerLawGammaCurve* powerLawEnc  = dynamic_cast<PowerLawGammaCurve*>(encoding.get());
        if (powerLawEnc)
            return PowerLawGammaCurve::GetByEncodingGamma(powerLawWork->ApproximateDecodingGamma() / powerLawEnc->ApproximateDecodingGamma());
    }
    // we really need a combo of two gamma curves
    return GetMatching(GammaCurvePtr(new TranscodingGammaCurve(working, encoding ? encoding : GammaCurvePtr(NeutralGammaCurve::Get()))));
}
Exemple #3
0
bool TranscodingGammaCurve::Matches(const GammaCurvePtr& p) const
{
    TranscodingGammaCurve* other = dynamic_cast<TranscodingGammaCurve*>(p.get());
    if (!other) return false;
    return (this->encGamma->Matches(other->encGamma) && this->workGamma->Matches(other->workGamma));
}
Exemple #4
0
bool ScaledGammaCurve::Matches(const GammaCurvePtr& p) const
{
    ScaledGammaCurve* other = dynamic_cast<ScaledGammaCurve*>(p.get());
    if (!other) return false;
    return (this->baseGamma == other->baseGamma) && IsNeutral(this->encFactor / other->encFactor);
}
Exemple #5
0
bool PowerLawGammaCurve::Matches(const GammaCurvePtr& p) const
{
    PowerLawGammaCurve* other = dynamic_cast<PowerLawGammaCurve*>(p.get());
    if (!other) return false;
    return IsNeutral(this->encGamma / other->encGamma);
}