Backed out changeset 177eae915693 (bug 1206581) for bustage
[gecko.git] / image / ImageOps.cpp
blob76a7bb968be077698aae34edad95ea835ac76b87
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ImageOps.h"
9 #include "ClippedImage.h"
10 #include "DecodePool.h"
11 #include "Decoder.h"
12 #include "DecoderFactory.h"
13 #include "DynamicImage.h"
14 #include "FrozenImage.h"
15 #include "Image.h"
16 #include "imgIContainer.h"
17 #include "mozilla/gfx/2D.h"
18 #include "nsStreamUtils.h"
19 #include "OrientedImage.h"
20 #include "SourceBuffer.h"
22 using namespace mozilla::gfx;
24 namespace mozilla {
25 namespace image {
27 /* static */ already_AddRefed<Image>
28 ImageOps::Freeze(Image* aImage)
30 RefPtr<Image> frozenImage = new FrozenImage(aImage);
31 return frozenImage.forget();
34 /* static */ already_AddRefed<imgIContainer>
35 ImageOps::Freeze(imgIContainer* aImage)
37 nsCOMPtr<imgIContainer> frozenImage =
38 new FrozenImage(static_cast<Image*>(aImage));
39 return frozenImage.forget();
42 /* static */ already_AddRefed<Image>
43 ImageOps::Clip(Image* aImage, nsIntRect aClip)
45 RefPtr<Image> clippedImage = new ClippedImage(aImage, aClip);
46 return clippedImage.forget();
49 /* static */ already_AddRefed<imgIContainer>
50 ImageOps::Clip(imgIContainer* aImage, nsIntRect aClip)
52 nsCOMPtr<imgIContainer> clippedImage =
53 new ClippedImage(static_cast<Image*>(aImage), aClip);
54 return clippedImage.forget();
57 /* static */ already_AddRefed<Image>
58 ImageOps::Orient(Image* aImage, Orientation aOrientation)
60 RefPtr<Image> orientedImage = new OrientedImage(aImage, aOrientation);
61 return orientedImage.forget();
64 /* static */ already_AddRefed<imgIContainer>
65 ImageOps::Orient(imgIContainer* aImage, Orientation aOrientation)
67 nsCOMPtr<imgIContainer> orientedImage =
68 new OrientedImage(static_cast<Image*>(aImage), aOrientation);
69 return orientedImage.forget();
72 /* static */ already_AddRefed<imgIContainer>
73 ImageOps::CreateFromDrawable(gfxDrawable* aDrawable)
75 nsCOMPtr<imgIContainer> drawableImage = new DynamicImage(aDrawable);
76 return drawableImage.forget();
79 /* static */ already_AddRefed<gfx::SourceSurface>
80 ImageOps::DecodeToSurface(nsIInputStream* aInputStream,
81 const nsACString& aMimeType,
82 uint32_t aFlags)
84 MOZ_ASSERT(aInputStream);
86 nsresult rv;
88 // Prepare the input stream.
89 nsCOMPtr<nsIInputStream> inputStream = aInputStream;
90 if (!NS_InputStreamIsBuffered(aInputStream)) {
91 nsCOMPtr<nsIInputStream> bufStream;
92 rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
93 aInputStream, 1024);
94 if (NS_SUCCEEDED(rv)) {
95 inputStream = bufStream;
99 // Figure out how much data we've been passed.
100 uint64_t length;
101 rv = inputStream->Available(&length);
102 if (NS_FAILED(rv) || length > UINT32_MAX) {
103 return nullptr;
106 // Write the data into a SourceBuffer.
107 RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
108 sourceBuffer->ExpectLength(length);
109 rv = sourceBuffer->AppendFromInputStream(inputStream, length);
110 if (NS_FAILED(rv)) {
111 return nullptr;
113 sourceBuffer->Complete(NS_OK);
115 // Create a decoder.
116 DecoderType decoderType =
117 DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get());
118 RefPtr<Decoder> decoder =
119 DecoderFactory::CreateAnonymousDecoder(decoderType,
120 sourceBuffer,
121 ToSurfaceFlags(aFlags));
122 if (!decoder) {
123 return nullptr;
126 // Run the decoder synchronously.
127 decoder->Decode();
128 if (!decoder->GetDecodeDone() || decoder->HasError()) {
129 return nullptr;
132 // Pull out the surface.
133 RawAccessFrameRef frame = decoder->GetCurrentFrameRef();
134 if (!frame) {
135 return nullptr;
138 RefPtr<SourceSurface> surface = frame->GetSurface();
139 if (!surface) {
140 return nullptr;
143 return surface.forget();
146 } // namespace image
147 } // namespace mozilla