示例#1
0
/** \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));
    }
}
示例#2
0
/** \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);
}
示例#4
0
/** \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);
}
示例#5
0
/** \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());
    }
}
示例#6
0
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();
}
示例#7
0
/**
 * 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();
	}
}
示例#8
0
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;
}
示例#9
0
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);
  }
}