/** * \copydoc MythUIType::customEvent() */ void MythUIImage::customEvent(QEvent *event) { if (event->type() == ImageLoadEvent::kEventType) { ImageLoadEvent *le = dynamic_cast<ImageLoadEvent*>(event); if (le->GetParent() != this) return; MythImage *image = le->GetImage(); if (!image) return; d->m_UpdateLock.lockForRead(); if (le->GetBasefile() != m_Filename) { d->m_UpdateLock.unlock(); #if 0 VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString("customEvent(): Expecting '%2', got '%3'") .arg(m_Filename).arg(le->GetBasefile())); #endif image->DownRef(); return; } d->m_UpdateLock.unlock(); QString filename = le->GetFilename(); int number = le->GetNumber(); d->m_UpdateLock.lockForWrite(); if (m_ForceSize.isNull()) SetSize(image->size()); d->m_UpdateLock.unlock(); m_ImagesLock.lock(); if (m_Images[number]) { // If we got to this point, it means this same MythUIImage // was told to reload the same image, so we use the newest // copy of the image. m_Images[number]->DownRef(); // delete the original } m_Images[number] = image; m_ImagesLock.unlock(); SetRedraw(); d->m_UpdateLock.lockForWrite(); m_LastDisplay = QTime::currentTime(); d->m_UpdateLock.unlock(); } }
void MythPainter::ExpireImages(int max) { if (m_StringExpireList.size() < 1) return; while (m_SoftwareCacheSize > max) { QString oldmsg = m_StringExpireList.front(); m_StringExpireList.pop_front(); MythImage *oldim = NULL; if (m_StringToImageMap.contains(oldmsg)) oldim = m_StringToImageMap[oldmsg]; m_StringToImageMap.remove(oldmsg); if (oldim) { m_SoftwareCacheSize -= oldim->bytesPerLine() * oldim->height(); oldim->DownRef(); } } }
/** * \copydoc MythUIType::DrawSelf() */ void MythUIImage::DrawSelf(MythPainter *p, int xoffset, int yoffset, int alphaMod, QRect clipRect) { m_ImagesLock.lock(); if (m_Images.size() > 0) { d->m_UpdateLock.lockForWrite(); if (m_CurPos >= (uint)m_Images.size()) m_CurPos = 0; if (!m_Images[m_CurPos]) { unsigned int origPos = m_CurPos; m_CurPos++; while (!m_Images[m_CurPos] && m_CurPos != origPos) { m_CurPos++; if (m_CurPos >= (uint)m_Images.size()) m_CurPos = 0; } } QRect area = GetArea().toQRect(); area.translate(xoffset, yoffset); int alpha = CalcAlpha(alphaMod); MythImage *currentImage = m_Images[m_CurPos]; if (currentImage) currentImage->UpRef(); m_ImagesLock.unlock(); d->m_UpdateLock.unlock(); if (!currentImage) return; d->m_UpdateLock.lockForRead(); QRect currentImageArea = currentImage->rect(); if (!m_ForceSize.isNull()) area.setSize(area.size().expandedTo(currentImage->size())); // Centre image in available space int x = 0; int y = 0; if (area.width() > currentImageArea.width()) x = (area.width() - currentImageArea.width()) / 2; if (area.height() > currentImageArea.height()) y = (area.height() - currentImageArea.height()) / 2; if (x > 0 || y > 0) area.translate(x,y); QRect srcRect; m_cropRect.CalculateArea(GetArea()); if (!m_cropRect.isEmpty()) srcRect = m_cropRect.toQRect(); else srcRect = currentImageArea; p->DrawImage(area, currentImage, srcRect, alpha); currentImage->DownRef(); d->m_UpdateLock.unlock(); } else m_ImagesLock.unlock(); }
/** * \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; }