/** \fn GalleryViewHelper::SetFileOrientation(int) * \brief Saves the orientation information of the selected node * \param fileOrientation The orientation value 1-8 * \return void */ void GalleryViewHelper::SetFileOrientation(int fileOrientation) { ImageMetadata *im = GetImageMetadataFromSelectedNode(); if (!im) return; int oldFileOrientation = im->GetOrientation(); // Update the orientation, the new value will // be calculated with this method. This new // value will then be saved in the exif header tag. im->SetOrientation(fileOrientation, false); // Update the exif tag, if that fails we can restore the original // orientation so that the database and image file are not out of sync if (m_fileHelper->SetImageOrientation(im)) { m_dbHelper->UpdateData(im); m_thumbGenThread->RecreateThumbnail(im); m_thumbGenThread->start(); } else { im->SetOrientation(oldFileOrientation, false); LOG(VB_GENERAL, LOG_ERR, QString("Could not write the angle %1 into the file %2. " "The database value has not been updated.") .arg(im->GetAngle()).arg(im->m_fileName)); } }
/** \fn GalleryViewHelper::SetFileOrientation(int) * \brief Saves the orientation information of the selected node * \param fileOrientation The orientation value 1-8 * \return void */ void GalleryViewHelper::SetFileOrientation(int fileOrientation) { ImageMetadata *im = GetImageMetadataFromSelectedNode(); if (!im) return; int oldFileOrientation = im->GetOrientation(); // Update the orientation, the new value will // be calculated with this method. This new // value will then be saved in the exif header tag. im->SetOrientation(fileOrientation, false); // Request orientation update if (m_fileHelper->SetImageOrientation(im)) { // force thumbnail to be regenerated m_fileHelper->AddToThumbnailList(im, true); } else { // Restore previous orientation im->SetOrientation(oldFileOrientation, true); LOG(VB_GENERAL, LOG_ERR, QString("Orientation update failed for %1") .arg(im->m_fileName)); } }
/** * \brief Set the meta data in an image */ void ImageDirectory::setMetadata(const std::string& filename, const ImageMetadata& metadata) { ImagePtr image = getImagePtr(filename); for (auto ptr = metadata.begin(); ptr != metadata.end(); ptr++) { image->setMetadata(ptr->second); } write(image, filename); }
/** \fn GalleryViewHelper::SetFileZoom(int) * \brief Saves the zoom information of the selected node * \param zoom The zoom value in percent * \return void */ void GalleryViewHelper::SetFileZoom(int zoom) { ImageMetadata *im = GetImageMetadataFromSelectedNode(); if (!im) return; if (zoom == kFileZoomIn) im->SetZoom(20); if (zoom == kFileZoomOut) im->SetZoom(-20); m_dbHelper->UpdateData(im); }
/** \fn ImageScanThread::SyncFile(QFileInfo &, int) * \brief Syncronizes a file with the database. Either inserts, * updates or deletes the information in the database. * \param fileInfo The information of the file * \param parentId The parent directory which will be saved with the file * \return void */ void ImageScanThread::SyncFile(QFileInfo &fileInfo, int parentId, const QString &baseDirectory) { LOG(VB_FILE, LOG_DEBUG, QString("Syncing file %1") .arg(fileInfo.absoluteFilePath())); if (!m_dbFileList->contains(fileInfo.absoluteFilePath())) { ImageMetadata *im = new ImageMetadata(); // Load all required information of the file ImageUtils *iu = ImageUtils::getInstance(); iu->LoadFileData(fileInfo, im, baseDirectory); // Only load the file if contains a valid file extension LOG(VB_FILE, LOG_DEBUG, QString("Type of file %1 is %2, extension %3").arg(im->m_fileName).arg(im->m_type).arg(im->m_extension)); if (im->m_type != kUnknown) { // Load any required exif information if the file is an image if (im->m_type == kImageFile) { bool ok; int exifOrientation = iu->GetExifOrientation(fileInfo.absoluteFilePath(), &ok); if (ok) im->SetOrientation(exifOrientation, true); int exifDate = iu->GetExifDate(fileInfo.absoluteFilePath(), &ok); if (ok) im->m_date = exifDate; } // Load the parent id. This is the id of the file's path im->m_parentId = parentId; // The file is not in the database list // add it to the database. im->m_id = iu->InsertFileIntoDB(im); } delete im; } else { // Remove the entry from the dbList // so we don't need to search again m_dbFileList->remove(fileInfo.absoluteFilePath()); } }
void FixDpiDialog::setDpiForm(ImageMetadata const& metadata) { Dpi const dpi(metadata.dpi()); if (dpi.isNull()) { resetDpiForm(); return; } m_xDpiInitialValue = QString::number(dpi.horizontal()); m_yDpiInitialValue = QString::number(dpi.vertical()); m_selectedItemPixelSize = metadata.size(); xDpi->setText(m_xDpiInitialValue); yDpi->setText(m_yDpiInitialValue); dpiValueChanged(); }
/** * This comparator puts objects that are not OK to the front. */ bool FixDpiDialog::DpiCounts::MetadataComparator::operator()( ImageMetadata const& lhs, ImageMetadata const& rhs) const { bool const lhs_ok = lhs.isDpiOK(); bool const rhs_ok = rhs.isDpiOK(); if (lhs_ok != rhs_ok) { return rhs_ok; } if (lhs.size().width() < rhs.size().width()) { return true; } else if (lhs.size().width() > rhs.size().width()) { return false; } else if (lhs.size().height() < rhs.size().height()) { return true; } else if (lhs.size().height() > rhs.size().height()) { return false; } else if (lhs.dpi().horizontal() < rhs.dpi().horizontal()) { return true; } else if (lhs.dpi().horizontal() > rhs.dpi().horizontal()) { return false; } else { return lhs.dpi().vertical() < rhs.dpi().vertical(); } }
bool RasterImage::SetMetadata(const ImageMetadata& aMetadata, bool aFromMetadataDecode) { MOZ_ASSERT(NS_IsMainThread()); if (mError) { return true; } if (aMetadata.HasSize()) { IntSize size = aMetadata.GetSize(); if (size.width < 0 || size.height < 0) { NS_WARNING("Image has negative intrinsic size"); DoError(); return true; } MOZ_ASSERT(aMetadata.HasOrientation()); Orientation orientation = aMetadata.GetOrientation(); // If we already have a size, check the new size against the old one. if (mHasSize && (size != mSize || orientation != mOrientation)) { NS_WARNING("Image changed size or orientation on redecode! " "This should not happen!"); DoError(); return true; } // Set the size and flag that we have it. mSize = size; mOrientation = orientation; mHasSize = true; } if (mHasSize && aMetadata.HasAnimation() && !mAnimationState) { // We're becoming animated, so initialize animation stuff. mAnimationState.emplace(mAnimationMode); mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize); // We don't support discarding animated images (See bug 414259). // Lock the image and throw away the key. LockImage(); if (!aFromMetadataDecode) { // The metadata decode reported that this image isn't animated, but we // discovered that it actually was during the full decode. This is a // rare failure that only occurs for corrupt images. To recover, we need // to discard all existing surfaces and redecode. return false; } } if (mAnimationState) { mAnimationState->SetLoopCount(aMetadata.GetLoopCount()); mAnimationState->SetFirstFrameTimeout(aMetadata.GetFirstFrameTimeout()); if (aMetadata.HasLoopLength()) { mAnimationState->SetLoopLength(aMetadata.GetLoopLength()); } if (aMetadata.HasFirstFrameRefreshArea()) { mAnimationState ->SetFirstFrameRefreshArea(aMetadata.GetFirstFrameRefreshArea()); } } if (aMetadata.HasHotspot()) { IntPoint hotspot = aMetadata.GetHotspot(); nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID); nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID); intwrapx->SetData(hotspot.x); intwrapy->SetData(hotspot.y); Set("hotspotX", intwrapx); Set("hotspotY", intwrapy); } return true; }
void RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata, const DecoderTelemetry& aTelemetry, Progress aProgress, const IntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount, DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) { MOZ_ASSERT(NS_IsMainThread()); // If the decoder detected an error, log it to the error console. if (aStatus.mShouldReportError && !aStatus.mWasAborted) { ReportDecoderError(); } // Record all the metadata the decoder gathered about this image. bool metadataOK = SetMetadata(aMetadata, aStatus.mWasMetadataDecode); if (!metadataOK) { // This indicates a serious error that requires us to discard all existing // surfaces and redecode to recover. We'll drop the results from this // decoder on the floor, since they aren't valid. RecoverFromInvalidFrames(mSize, FromSurfaceFlags(aSurfaceFlags)); return; } MOZ_ASSERT(mError || mHasSize || !aMetadata.HasSize(), "SetMetadata should've gotten a size"); if (!aStatus.mWasMetadataDecode && aStatus.mFinished && !aStatus.mWasAborted) { // Flag that we've been decoded before. mHasBeenDecoded = true; } // Send out any final notifications. NotifyProgress(aProgress, aInvalidRect, aFrameCount, aDecoderFlags, aSurfaceFlags); if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) && mHasBeenDecoded && mAnimationState) { // We've finished a full decode of all animation frames and our AnimationState // has been notified about them all, so let it know not to expect anymore. mAnimationState->SetDoneDecoding(true); } if (!aStatus.mWasMetadataDecode && aTelemetry.mChunkCount) { Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, aTelemetry.mChunkCount); } if (aStatus.mFinished) { // Do some telemetry if this isn't a metadata decode. if (!aStatus.mWasMetadataDecode) { Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME, int32_t(aTelemetry.mDecodeTime.ToMicroseconds())); if (aTelemetry.mSpeedHistogram) { Telemetry::Accumulate(*aTelemetry.mSpeedHistogram, aTelemetry.Speed()); } } // Detect errors. if (aStatus.mHadError && !aStatus.mWasAborted) { DoError(); } else if (aStatus.mWasMetadataDecode && !mHasSize) { DoError(); } // If we were waiting to fire the load event, go ahead and fire it now. if (mLoadProgress && aStatus.mWasMetadataDecode) { NotifyForLoadEvent(*mLoadProgress); mLoadProgress = Nothing(); NotifyProgress(FLAG_ONLOAD_UNBLOCKED); } } // If we were a metadata decode and a full decode was requested, do it. if (aStatus.mFinished && aStatus.mWasMetadataDecode && mWantFullDecode) { mWantFullDecode = false; RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT); } }