Ejemplo n.º 1
0
    static MythImage *LoadImage(MythPainter *painter,
                                 // Must be a copy for thread safety
                                ImageProperties imProps,
                                ImageCacheMode cacheMode,
                                 // Included only to check address, could be
                                 // replaced by generating a unique value for
                                 // each MythUIImage object?
                                const MythUIImage *parent,
                                bool &aborted,
                                MythImageReader *imageReader = NULL)
    {
        QString cacheKey = GenImageLabel(imProps);
        if (!PreLoad(cacheKey, parent))
        {
            aborted = true;
            return NULL;
        }

        QString filename = imProps.filename;
        MythImage *image = NULL;

        bool bResize = false;
        bool bFoundInCache = false;

        int w = -1;
        int h = -1;

        if (!imProps.forceSize.isNull())
        {
            if (imProps.forceSize.width() != -1)
                w = imProps.forceSize.width();

            if (imProps.forceSize.height() != -1)
                h = imProps.forceSize.height();

            bResize = true;
        }

        if (!imageReader)
        {
            image = GetMythUI()->LoadCacheImage(filename, cacheKey,
                                                painter, cacheMode);
        }

        if (image)
        {
            if (VERBOSE_LEVEL_CHECK(VB_GUI | VB_FILE, LOG_INFO))
            {
                image->IncrRef();
                int cnt = image->DecrRef();
                LOG(VB_GUI | VB_FILE, LOG_INFO,
                    QString("ImageLoader::LoadImage(%1) Found in cache, "
                            "RefCount = %2")
                    .arg(cacheKey).arg(cnt));
            }

            if (imProps.isReflected)
                image->setIsReflected(true);

            if (imProps.isOriented)
                image->setIsOriented(true);

            bFoundInCache = true;
        }
        else
        {
            LOG(VB_GUI | VB_FILE, LOG_INFO,
                QString("ImageLoader::LoadImage(%1) NOT Found in cache. "
                        "Loading Directly").arg(cacheKey));

            image = painter->GetFormatImage();
            bool ok = false;

            if (imageReader)
                ok = image->Load(imageReader);
            else
                ok = image->Load(filename);

            if (!ok)
            {
                image->DecrRef();
                image = NULL;
            }
        }

        if (image && image->isNull())
        {
            LOG(VB_GUI | VB_FILE, LOG_INFO,
                QString("ImageLoader::LoadImage(%1) Image is NULL")
                                                    .arg(filename));

            image->DecrRef();
            image = NULL;
        }

        if (image && !bFoundInCache)
        {
            if (imProps.isReflected)
                image->Reflect(imProps.reflectAxis, imProps.reflectShear,
                               imProps.reflectScale, imProps.reflectLength,
                               imProps.reflectSpacing);

            if (imProps.isGreyscale)
                image->ToGreyscale();

            if (imProps.isOriented)
                image->Orientation(imProps.orientation);

            // Even if an explicit size wasn't defined this image may still need
            // to be scaled because of a difference between the theme resolution
            // and the screen resolution. We want to avoid scaling twice.
            if (!bResize && imProps.isThemeImage)
            {
                float wmult; // Width multipler
                float hmult; // Height multipler
                GetMythUI()->GetScreenSettings(wmult, hmult);
                if (wmult != 1.0f || hmult != 1.0f)
                {
                    w = image->size().width() * wmult;
                    h = image->size().height() * hmult;
                    bResize = true;
                }
            }

            if (bResize)
                image->Resize(QSize(w, h), imProps.preserveAspect);

            if (imProps.isMasked)
            {
                QRect imageArea = image->rect();
                QRect maskArea = imProps.GetMaskImageRect();

                // Crop the mask to the image
                int x = 0;
                int y = 0;

                if (maskArea.width() > imageArea.width())
                    x = (maskArea.width() - imageArea.width()) / 2;

                if (maskArea.height() > imageArea.height())
                    y = (maskArea.height() - imageArea.height()) / 2;

                if (x > 0 || y > 0)
                    imageArea.translate(x, y);

                QImage mask = imProps.GetMaskImageSubset(imageArea);
                image->setAlphaChannel(mask.alphaChannel());
            }

            if (!imageReader)
                GetMythUI()->CacheImage(cacheKey, image);
        }

        if (image)
            image->SetChanged();

        PostLoad(cacheKey);

        return image;
    }
Ejemplo n.º 2
0
/**
*  \brief Load an image
*/
MythImage *MythUIImage::LoadImage(
    MythImageReader &imageReader, const QString &imFile,
    QSize bForceSize, int cacheMode)
{
    QString filename = imFile;

    m_loadingImagesLock.lock();

    // Check to see if the image is being loaded by us in another thread
    if ((m_loadingImages.contains(filename)) &&
        (m_loadingImages[filename] == this))
    {
        VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString(
                    "MythUIImage::LoadImage(%1), this "
                    "file is already being loaded by this same MythUIImage in "
                    "another thread.").arg(filename));
        m_loadingImagesLock.unlock();
        return NULL;
    }

    // Check to see if the exact same image is being loaded anywhere else
    while (m_loadingImages.contains(filename))
        m_loadingImagesCond.wait(&m_loadingImagesLock);

    m_loadingImages[filename] = this;
    m_loadingImagesLock.unlock();

    VERBOSE(VB_GUI|VB_FILE, LOC + QString("LoadImage(%2) Object %3")
            .arg(filename).arg(objectName()));

    MythImage *image = NULL;

    bool bForceResize = false;
    bool bFoundInCache = false;

    QString imagelabel;

    int w = -1;
    int h = -1;

    if (!bForceSize.isNull())
    {
        if (bForceSize.width() != -1)
            w = bForceSize.width();

        if (bForceSize.height() != -1)
            h = bForceSize.height();

        bForceResize = true;
    }

    imagelabel = GenImageLabel(filename, w, h);

    if (!imageReader.supportsAnimation())
    {
        image = GetMythUI()->LoadCacheImage(
            filename, imagelabel, GetPainter(), (ImageCacheMode) cacheMode);
    }

    if (image)
    {
        image->UpRef();

        VERBOSE(VB_GUI|VB_FILE, LOC +
                QString("LoadImage found in cache :%1: RefCount = %2")
                .arg(imagelabel).arg(image->RefCount()));

        if (m_isReflected)
            image->setIsReflected(true);

        bFoundInCache = true;
    }
    else
    {
        VERBOSE(VB_GUI|VB_FILE, LOC +
                QString("LoadImage Not Found in cache. "
                        "Loading Directly :%1:").arg(filename));

        image = GetPainter()->GetFormatImage();
        image->UpRef();
        bool ok = false;
        if (imageReader.supportsAnimation())
            ok = image->Load(imageReader);
        else
            ok = image->Load(filename);

        if (!ok)
        {
            image->DownRef();

            m_loadingImagesLock.lock();
            m_loadingImages.remove(filename);
            m_loadingImagesCond.wakeAll();
            m_loadingImagesLock.unlock();

            return NULL;
        }
    }

    if (!bFoundInCache)
    {
        if (bForceResize)
            image->Resize(QSize(w, h), m_preserveAspect);

        if (m_isMasked)
        {
            QRect imageArea = image->rect();
            QRect maskArea = m_maskImage->rect();

            // Crop the mask to the image
            int x = 0;
            int y = 0;
            if (maskArea.width() > imageArea.width())
                x = (maskArea.width() - imageArea.width()) / 2;
            if (maskArea.height() > imageArea.height())
                y = (maskArea.height() - imageArea.height()) / 2;

            if (x > 0 || y > 0)
                imageArea.translate(x,y);
            d->m_UpdateLock.lockForWrite();
            QImage mask = m_maskImage->copy(imageArea);
            d->m_UpdateLock.unlock();
            image->setAlphaChannel(mask.alphaChannel());
        }

        if (m_isReflected)
            image->Reflect(m_reflectAxis, m_reflectShear, m_reflectScale,
                        m_reflectLength, m_reflectSpacing);

        if (m_isGreyscale)
            image->ToGreyscale();

        if (!imageReader.supportsAnimation())
            GetMythUI()->CacheImage(imagelabel, image);
    }

    if (image->isNull())
    {
        VERBOSE(VB_GUI|VB_FILE, LOC + QString("LoadImage Image is NULL :%1:")
                .arg(filename));

        image->DownRef();
        Reset();

        m_loadingImagesLock.lock();
        m_loadingImages.remove(filename);
        m_loadingImagesCond.wakeAll();
        m_loadingImagesLock.unlock();

        return NULL;
    }

    image->SetChanged();

    m_loadingImagesLock.lock();
    m_loadingImages.remove(filename);
    m_loadingImagesCond.wakeAll();
    m_loadingImagesLock.unlock();

    return image;
}