Bug 869723 (Part 1) - Add imgIContainer::GetOrientation. r=joe sr=bz

This commit is contained in:
Seth Fowler 2013-08-24 17:31:14 -07:00
parent 0358c713dc
commit 58c9cfc5f3
11 changed files with 137 additions and 14 deletions

View File

@ -31,6 +31,12 @@ class TimeStamp;
class SVGImageContext;
}
namespace mozilla {
namespace image {
class Orientation;
}
}
%}
[ptr] native gfxImageSurface(gfxImageSurface);
@ -46,6 +52,7 @@ native nsSize(nsSize);
[ptr] native nsIFrame(nsIFrame);
[ptr] native ImageContainer(mozilla::layers::ImageContainer);
[ptr] native LayerManager(mozilla::layers::LayerManager);
native Orientation(mozilla::image::Orientation);
[ref] native TimeStamp(mozilla::TimeStamp);
[ptr] native SVGImageContext(mozilla::SVGImageContext);
@ -57,7 +64,7 @@ native nsSize(nsSize);
*
* Internally, imgIContainer also manages animation of images.
*/
[scriptable, builtinclass, uuid(f9029a03-758c-4047-a1f3-4b2e51e47363)]
[scriptable, builtinclass, uuid(73340b79-e3ae-4f02-97d0-822db78017e5)]
interface imgIContainer : nsISupports
{
/**
@ -302,6 +309,12 @@ interface imgIContainer : nsISupports
*/
[notxpcom] float getFrameIndex(in uint32_t aWhichFrame);
/*
* Returns the inherent orientation of the image, as described in the image's
* metadata (e.g. EXIF).
*/
[notxpcom] Orientation getOrientation();
/*
* Returns the delay, in ms, between the first and second frame. If this
* returns 0, there is no delay between first and second frame (i.e., this

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/SVGSVGElement.h"
#include "ClippedImage.h"
#include "Orientation.h"
using mozilla::layers::LayerManager;
using mozilla::layers::ImageContainer;
@ -411,5 +412,13 @@ ClippedImage::RequestDiscard()
return InnerImage()->RequestDiscard();
}
NS_IMETHODIMP_(Orientation)
ClippedImage::GetOrientation()
{
// XXX(seth): This should not actually be here; this is just to work around a
// what appears to be a bug in MSVC's linker.
return InnerImage()->GetOrientation();
}
} // namespace image
} // namespace mozilla

View File

@ -50,6 +50,7 @@ public:
uint32_t aWhichFrame,
uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD RequestDiscard() MOZ_OVERRIDE;
NS_IMETHOD_(Orientation) GetOrientation() MOZ_OVERRIDE;
protected:
ClippedImage(Image* aImage, nsIntRect aClip);

View File

@ -266,7 +266,12 @@ Decoder::FlushInvalidations()
void
Decoder::SetSizeOnImage()
{
mImage.SetSize(mImageMetadata.GetWidth(), mImageMetadata.GetHeight());
MOZ_ASSERT(mImageMetadata.HasSize(), "Should have size");
MOZ_ASSERT(mImageMetadata.HasOrientation(), "Should have orientation");
mImage.SetSize(mImageMetadata.GetWidth(),
mImageMetadata.GetHeight(),
mImageMetadata.GetOrientation());
}
/*
@ -282,14 +287,16 @@ void Decoder::FinishInternal() { }
*/
void
Decoder::PostSize(int32_t aWidth, int32_t aHeight)
Decoder::PostSize(int32_t aWidth,
int32_t aHeight,
Orientation aOrientation /* = Orientation()*/)
{
// Validate
NS_ABORT_IF_FALSE(aWidth >= 0, "Width can't be negative!");
NS_ABORT_IF_FALSE(aHeight >= 0, "Height can't be negative!");
// Tell the image
mImageMetadata.SetSize(aWidth, aHeight);
mImageMetadata.SetSize(aWidth, aHeight, aOrientation);
// Notify the observer
if (mObserver)

View File

@ -10,6 +10,7 @@
#include "imgDecoderObserver.h"
#include "mozilla/RefPtr.h"
#include "ImageMetadata.h"
#include "Orientation.h"
namespace mozilla {
namespace image {
@ -189,7 +190,9 @@ protected:
// Called by decoders when they determine the size of the image. Informs
// the image of its size and sends notifications.
void PostSize(int32_t aWidth, int32_t aHeight);
void PostSize(int32_t aWidth,
int32_t aHeight,
Orientation aOrientation = Orientation());
// Called by decoders when they begin a frame. Informs the image, sends
// notifications, and does internal book-keeping.

View File

@ -7,6 +7,7 @@
#include <stdint.h>
#include "mozilla/Util.h"
#include "nsSize.h"
#include "Orientation.h"
namespace mozilla {
namespace image {
@ -42,15 +43,18 @@ public:
mIsNonPremultiplied = nonPremult;
}
void SetSize(int32_t width, int32_t height)
void SetSize(int32_t width, int32_t height, Orientation orientation)
{
mSize.construct(nsIntSize(width, height));
mOrientation.construct(orientation);
}
bool HasSize() const { return !mSize.empty(); }
bool HasOrientation() const { return !mOrientation.empty(); }
int32_t GetWidth() const { return mSize.ref().width; }
int32_t GetHeight() const { return mSize.ref().height; }
Orientation GetOrientation() const { return mOrientation.ref(); }
private:
// The hotspot found on cursors, or -1 if none was found.
@ -61,6 +65,7 @@ private:
int32_t mLoopCount;
Maybe<nsIntSize> mSize;
Maybe<Orientation> mOrientation;
bool mIsNonPremultiplied;
};

View File

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageWrapper.h"
#include "Orientation.h"
#include "mozilla/MemoryReporting.h"
@ -167,6 +168,12 @@ ImageWrapper::GetIntrinsicRatio(nsSize* aSize)
return mInnerImage->GetIntrinsicRatio(aSize);
}
NS_IMETHODIMP_(Orientation)
ImageWrapper::GetOrientation()
{
return mInnerImage->GetOrientation();
}
NS_IMETHODIMP
ImageWrapper::GetType(uint16_t* aType)
{

62
image/src/Orientation.h Normal file
View File

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_IMAGELIB_ORIENTATION_H_
#define MOZILLA_IMAGELIB_ORIENTATION_H_
#include <stdint.h>
#include "mozilla/TypedEnum.h"
namespace mozilla {
namespace image {
MOZ_BEGIN_ENUM_CLASS(Angle, uint8_t)
D0,
D90,
D180,
D270
MOZ_END_ENUM_CLASS(Angle)
MOZ_BEGIN_ENUM_CLASS(Flip, uint8_t)
Unflipped,
Horizontal
MOZ_END_ENUM_CLASS(Flip)
/**
* A struct that describes an image's orientation as a rotation optionally
* followed by a reflection. This may be used to be indicate an image's inherent
* orientation or a desired orientation for the image.
*/
struct Orientation
{
Orientation(Angle aRotation = Angle::D0, Flip mFlip = Flip::Unflipped)
: rotation(aRotation)
, flip(mFlip)
{ }
bool IsIdentity() const {
return (rotation == Angle::D0) && (flip == Flip::Unflipped);
}
bool SwapsWidthAndHeight() const {
return (rotation == Angle::D90) || (rotation == Angle::D270);
}
bool operator==(const Orientation& aOther) const {
return (rotation == aOther.rotation) && (flip == aOther.flip);
}
bool operator!=(const Orientation& aOther) const {
return !(*this == aOther);
}
Angle rotation;
Flip flip;
};
}
}
#endif

View File

@ -619,6 +619,12 @@ RasterImage::GetIntrinsicRatio(nsSize* aRatio)
return NS_OK;
}
NS_IMETHODIMP_(Orientation)
RasterImage::GetOrientation()
{
return mOrientation;
}
//******************************************************************************
/* unsigned short GetType(); */
NS_IMETHODIMP
@ -1202,7 +1208,7 @@ RasterImage::ApplyDecodeFlags(uint32_t aNewFlags)
}
nsresult
RasterImage::SetSize(int32_t aWidth, int32_t aHeight)
RasterImage::SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation)
{
MOZ_ASSERT(NS_IsMainThread());
@ -1216,7 +1222,9 @@ RasterImage::SetSize(int32_t aWidth, int32_t aHeight)
// if we already have a size, check the new size against the old one
if (!mMultipart && mHasSize &&
((aWidth != mSize.width) || (aHeight != mSize.height))) {
((aWidth != mSize.width) ||
(aHeight != mSize.height) ||
(aOrientation != mOrientation))) {
NS_WARNING("Image changed size on redecode! This should not happen!");
// Make the decoder aware of the error so that it doesn't try to call
@ -1230,6 +1238,7 @@ RasterImage::SetSize(int32_t aWidth, int32_t aHeight)
// Set the size and flag that we have it
mSize.SizeTo(aWidth, aHeight);
mOrientation = aOrientation;
mHasSize = true;
mFrameBlender.SetSize(mSize);

View File

@ -28,6 +28,7 @@
#include "imgFrame.h"
#include "nsThreadUtils.h"
#include "DiscardTracker.h"
#include "Orientation.h"
#include "nsISupportsImpl.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TimeStamp.h"
@ -186,13 +187,11 @@ public:
/* Callbacks for decoders */
nsresult SetFrameAsNonPremult(uint32_t aFrameNum, bool aIsNonPremult);
/**
* Sets the size of the container. This should only be called by the
* decoder. This function may be called multiple times, but will throw an
* error if subsequent calls do not match the first.
/** Sets the size and inherent orientation of the container. This should only
* be called by the decoder. This function may be called multiple times, but
* will throw an error if subsequent calls do not match the first.
*/
nsresult SetSize(int32_t aWidth, int32_t aHeight);
nsresult SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation);
/**
* Ensures that a given frame number exists with the given parameters, and
@ -583,6 +582,7 @@ private:
private: // data
nsIntSize mSize;
Orientation mOrientation;
// Whether our frames were decoded using any special flags.
// Some flags (e.g. unpremultiplied data) may not be compatible

View File

@ -27,6 +27,7 @@
#include "nsStubDocumentObserver.h"
#include "nsSVGEffects.h" // for nsSVGRenderingObserver
#include "nsSVGUtils.h" // for nsSVGUtils::ConvertToSurfaceSize
#include "Orientation.h"
#include "SVGDocumentWrapper.h"
namespace mozilla {
@ -540,6 +541,12 @@ VectorImage::GetIntrinsicRatio(nsSize* aRatio)
return NS_OK;
}
NS_IMETHODIMP_(Orientation)
VectorImage::GetOrientation()
{
return Orientation();
}
//******************************************************************************
/* readonly attribute unsigned short type; */
NS_IMETHODIMP