1414#include " FrozenImage.h"
1515#include " IDecodingTask.h"
1616#include " Image.h"
17+ #include " ImageMetadata.h"
1718#include " imgIContainer.h"
1819#include " mozilla/gfx/2D.h"
1920#include " nsStreamUtils.h"
@@ -79,10 +80,27 @@ ImageOps::CreateFromDrawable(gfxDrawable* aDrawable)
7980 return drawableImage.forget ();
8081}
8182
82- /* static */ already_AddRefed<gfx::SourceSurface>
83- ImageOps::DecodeToSurface (nsIInputStream* aInputStream,
84- const nsACString& aMimeType,
85- uint32_t aFlags)
83+ class ImageOps ::ImageBufferImpl final : public ImageOps::ImageBuffer {
84+ public:
85+ ImageBufferImpl (already_AddRefed<SourceBuffer> aSourceBuffer)
86+ : mSourceBuffer (aSourceBuffer)
87+ { }
88+
89+ protected:
90+ ~ImageBufferImpl () override { }
91+
92+ virtual already_AddRefed<SourceBuffer> GetSourceBuffer ()
93+ {
94+ RefPtr<SourceBuffer> sourceBuffer = mSourceBuffer ;
95+ return sourceBuffer.forget ();
96+ }
97+
98+ private:
99+ RefPtr<SourceBuffer> mSourceBuffer ;
100+ };
101+
102+ /* static */ already_AddRefed<ImageOps::ImageBuffer>
103+ ImageOps::CreateImageBuffer (nsIInputStream* aInputStream)
86104{
87105 MOZ_ASSERT (aInputStream);
88106
@@ -107,7 +125,7 @@ ImageOps::DecodeToSurface(nsIInputStream* aInputStream,
107125 }
108126
109127 // Write the data into a SourceBuffer.
110- NotNull< RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull ( new SourceBuffer () );
128+ RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer ();
111129 sourceBuffer->ExpectLength (length);
112130 rv = sourceBuffer->AppendFromInputStream (inputStream, length);
113131 if (NS_FAILED (rv)) {
@@ -122,12 +140,90 @@ ImageOps::DecodeToSurface(nsIInputStream* aInputStream,
122140 }
123141 sourceBuffer->Complete (NS_OK );
124142
143+ RefPtr<ImageBuffer> imageBuffer = new ImageBufferImpl (sourceBuffer.forget ());
144+ return imageBuffer.forget ();
145+ }
146+
147+ /* static */ nsresult
148+ ImageOps::DecodeMetadata (nsIInputStream* aInputStream,
149+ const nsACString& aMimeType,
150+ ImageMetadata& aMetadata)
151+ {
152+ RefPtr<ImageBuffer> buffer = CreateImageBuffer (aInputStream);
153+ return DecodeMetadata (buffer, aMimeType, aMetadata);
154+ }
155+
156+ /* static */ nsresult
157+ ImageOps::DecodeMetadata (ImageBuffer* aBuffer,
158+ const nsACString& aMimeType,
159+ ImageMetadata& aMetadata)
160+ {
161+ if (!aBuffer) {
162+ return NS_ERROR_FAILURE ;
163+ }
164+
165+ RefPtr<SourceBuffer> sourceBuffer = aBuffer->GetSourceBuffer ();
166+ if (NS_WARN_IF (!sourceBuffer)) {
167+ return NS_ERROR_FAILURE ;
168+ }
169+
170+ // Create a decoder.
171+ DecoderType decoderType =
172+ DecoderFactory::GetDecoderType (PromiseFlatCString (aMimeType).get ());
173+ RefPtr<Decoder> decoder =
174+ DecoderFactory::CreateAnonymousMetadataDecoder (decoderType,
175+ WrapNotNull (sourceBuffer));
176+ if (!decoder) {
177+ return NS_ERROR_FAILURE ;
178+ }
179+
180+ // Run the decoder synchronously.
181+ RefPtr<IDecodingTask> task = new AnonymousDecodingTask (WrapNotNull (decoder));
182+ task->Run ();
183+ if (!decoder->GetDecodeDone () || decoder->HasError ()) {
184+ return NS_ERROR_FAILURE ;
185+ }
186+
187+ aMetadata = decoder->GetImageMetadata ();
188+ if (aMetadata.GetNativeSizes ().IsEmpty () && aMetadata.HasSize ()) {
189+ aMetadata.AddNativeSize (aMetadata.GetSize ());
190+ }
191+
192+ return NS_OK ;
193+ }
194+
195+ /* static */ already_AddRefed<gfx::SourceSurface>
196+ ImageOps::DecodeToSurface (nsIInputStream* aInputStream,
197+ const nsACString& aMimeType,
198+ uint32_t aFlags,
199+ Maybe<IntSize> aSize /* = Nothing() */ )
200+ {
201+ RefPtr<ImageBuffer> buffer = CreateImageBuffer (aInputStream);
202+ return DecodeToSurface (buffer, aMimeType, aFlags, aSize);
203+ }
204+
205+ /* static */ already_AddRefed<gfx::SourceSurface>
206+ ImageOps::DecodeToSurface (ImageBuffer* aBuffer,
207+ const nsACString& aMimeType,
208+ uint32_t aFlags,
209+ Maybe<IntSize> aSize /* = Nothing() */ )
210+ {
211+ if (!aBuffer) {
212+ return nullptr ;
213+ }
214+
215+ RefPtr<SourceBuffer> sourceBuffer = aBuffer->GetSourceBuffer ();
216+ if (NS_WARN_IF (!sourceBuffer)) {
217+ return nullptr ;
218+ }
219+
125220 // Create a decoder.
126221 DecoderType decoderType =
127222 DecoderFactory::GetDecoderType (PromiseFlatCString (aMimeType).get ());
128223 RefPtr<Decoder> decoder =
129- DecoderFactory::CreateAnonymousDecoder (decoderType, sourceBuffer,
130- Nothing (), ToSurfaceFlags (aFlags));
224+ DecoderFactory::CreateAnonymousDecoder (decoderType,
225+ WrapNotNull (sourceBuffer),
226+ aSize, ToSurfaceFlags (aFlags));
131227 if (!decoder) {
132228 return nullptr ;
133229 }
0 commit comments