LCOV - code coverage report
Current view: top level - image - ImageOps.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 3 99 3.0 %
Date: 2017-07-14 16:53:18 Functions: 1 16 6.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       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/. */
       6             : 
       7             : #include "ImageOps.h"
       8             : 
       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 "IDecodingTask.h"
      16             : #include "Image.h"
      17             : #include "ImageMetadata.h"
      18             : #include "imgIContainer.h"
      19             : #include "mozilla/gfx/2D.h"
      20             : #include "nsStreamUtils.h"
      21             : #include "OrientedImage.h"
      22             : #include "SourceBuffer.h"
      23             : 
      24             : using namespace mozilla::gfx;
      25             : 
      26             : namespace mozilla {
      27             : namespace image {
      28             : 
      29             : /* static */ already_AddRefed<Image>
      30           0 : ImageOps::Freeze(Image* aImage)
      31             : {
      32           0 :   RefPtr<Image> frozenImage = new FrozenImage(aImage);
      33           0 :   return frozenImage.forget();
      34             : }
      35             : 
      36             : /* static */ already_AddRefed<imgIContainer>
      37           0 : ImageOps::Freeze(imgIContainer* aImage)
      38             : {
      39             :   nsCOMPtr<imgIContainer> frozenImage =
      40           0 :     new FrozenImage(static_cast<Image*>(aImage));
      41           0 :   return frozenImage.forget();
      42             : }
      43             : 
      44             : /* static */ already_AddRefed<Image>
      45           0 : ImageOps::Clip(Image* aImage, nsIntRect aClip,
      46             :                const Maybe<nsSize>& aSVGViewportSize)
      47             : {
      48           0 :   RefPtr<Image> clippedImage = new ClippedImage(aImage, aClip, aSVGViewportSize);
      49           0 :   return clippedImage.forget();
      50             : }
      51             : 
      52             : /* static */ already_AddRefed<imgIContainer>
      53          56 : ImageOps::Clip(imgIContainer* aImage, nsIntRect aClip,
      54             :                const Maybe<nsSize>& aSVGViewportSize)
      55             : {
      56             :   nsCOMPtr<imgIContainer> clippedImage =
      57         168 :     new ClippedImage(static_cast<Image*>(aImage), aClip, aSVGViewportSize);
      58         112 :   return clippedImage.forget();
      59             : }
      60             : 
      61             : /* static */ already_AddRefed<Image>
      62           0 : ImageOps::Orient(Image* aImage, Orientation aOrientation)
      63             : {
      64           0 :   RefPtr<Image> orientedImage = new OrientedImage(aImage, aOrientation);
      65           0 :   return orientedImage.forget();
      66             : }
      67             : 
      68             : /* static */ already_AddRefed<imgIContainer>
      69           0 : ImageOps::Orient(imgIContainer* aImage, Orientation aOrientation)
      70             : {
      71             :   nsCOMPtr<imgIContainer> orientedImage =
      72           0 :     new OrientedImage(static_cast<Image*>(aImage), aOrientation);
      73           0 :   return orientedImage.forget();
      74             : }
      75             : 
      76             : /* static */ already_AddRefed<imgIContainer>
      77           0 : ImageOps::CreateFromDrawable(gfxDrawable* aDrawable)
      78             : {
      79           0 :   nsCOMPtr<imgIContainer> drawableImage = new DynamicImage(aDrawable);
      80           0 :   return drawableImage.forget();
      81             : }
      82             : 
      83             : class ImageOps::ImageBufferImpl final : public ImageOps::ImageBuffer {
      84             : public:
      85           0 :   explicit ImageBufferImpl(already_AddRefed<SourceBuffer> aSourceBuffer)
      86           0 :     : mSourceBuffer(aSourceBuffer)
      87           0 :   { }
      88             : 
      89             : protected:
      90           0 :   ~ImageBufferImpl() override { }
      91             : 
      92           0 :   already_AddRefed<SourceBuffer> GetSourceBuffer() const override
      93             :   {
      94           0 :     RefPtr<SourceBuffer> sourceBuffer = mSourceBuffer;
      95           0 :     return sourceBuffer.forget();
      96             :   }
      97             : 
      98             : private:
      99             :   RefPtr<SourceBuffer> mSourceBuffer;
     100             : };
     101             : 
     102             : /* static */ already_AddRefed<ImageOps::ImageBuffer>
     103           0 : ImageOps::CreateImageBuffer(nsIInputStream* aInputStream)
     104             : {
     105           0 :   MOZ_ASSERT(aInputStream);
     106             : 
     107             :   nsresult rv;
     108             : 
     109             :   // Prepare the input stream.
     110           0 :   nsCOMPtr<nsIInputStream> inputStream = aInputStream;
     111           0 :   if (!NS_InputStreamIsBuffered(aInputStream)) {
     112           0 :     nsCOMPtr<nsIInputStream> bufStream;
     113           0 :     rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
     114           0 :                                    aInputStream, 1024);
     115           0 :     if (NS_SUCCEEDED(rv)) {
     116           0 :       inputStream = bufStream;
     117             :     }
     118             :   }
     119             : 
     120             :   // Figure out how much data we've been passed.
     121             :   uint64_t length;
     122           0 :   rv = inputStream->Available(&length);
     123           0 :   if (NS_FAILED(rv) || length > UINT32_MAX) {
     124           0 :     return nullptr;
     125             :   }
     126             : 
     127             :   // Write the data into a SourceBuffer.
     128           0 :   RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
     129           0 :   sourceBuffer->ExpectLength(length);
     130           0 :   rv = sourceBuffer->AppendFromInputStream(inputStream, length);
     131           0 :   if (NS_FAILED(rv)) {
     132           0 :     return nullptr;
     133             :   }
     134             :   // Make sure our sourceBuffer is marked as complete.
     135           0 :   if (sourceBuffer->IsComplete()) {
     136             :     NS_WARNING("The SourceBuffer was unexpectedly marked as complete. This may "
     137             :                "indicate either an OOM condition, or that imagelib was not "
     138           0 :                "initialized properly.");
     139           0 :     return nullptr;
     140             :   }
     141           0 :   sourceBuffer->Complete(NS_OK);
     142             : 
     143           0 :   RefPtr<ImageBuffer> imageBuffer = new ImageBufferImpl(sourceBuffer.forget());
     144           0 :   return imageBuffer.forget();
     145             : }
     146             : 
     147             : /* static */ nsresult
     148           0 : ImageOps::DecodeMetadata(nsIInputStream* aInputStream,
     149             :                          const nsACString& aMimeType,
     150             :                          ImageMetadata& aMetadata)
     151             : {
     152           0 :   RefPtr<ImageBuffer> buffer = CreateImageBuffer(aInputStream);
     153           0 :   return DecodeMetadata(buffer, aMimeType, aMetadata);
     154             : }
     155             : 
     156             : /* static */ nsresult
     157           0 : ImageOps::DecodeMetadata(ImageBuffer* aBuffer,
     158             :                          const nsACString& aMimeType,
     159             :                          ImageMetadata& aMetadata)
     160             : {
     161           0 :   if (!aBuffer) {
     162           0 :     return NS_ERROR_FAILURE;
     163             :   }
     164             : 
     165           0 :   RefPtr<SourceBuffer> sourceBuffer = aBuffer->GetSourceBuffer();
     166           0 :   if (NS_WARN_IF(!sourceBuffer)) {
     167           0 :     return NS_ERROR_FAILURE;
     168             :   }
     169             : 
     170             :   // Create a decoder.
     171             :   DecoderType decoderType =
     172           0 :     DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get());
     173             :   RefPtr<Decoder> decoder =
     174           0 :     DecoderFactory::CreateAnonymousMetadataDecoder(decoderType,
     175           0 :                                                    WrapNotNull(sourceBuffer));
     176           0 :   if (!decoder) {
     177           0 :     return NS_ERROR_FAILURE;
     178             :   }
     179             : 
     180             :   // Run the decoder synchronously.
     181           0 :   RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder));
     182           0 :   task->Run();
     183           0 :   if (!decoder->GetDecodeDone() || decoder->HasError()) {
     184           0 :     return NS_ERROR_FAILURE;
     185             :   }
     186             : 
     187           0 :   aMetadata = decoder->GetImageMetadata();
     188           0 :   if (aMetadata.GetNativeSizes().IsEmpty() && aMetadata.HasSize()) {
     189           0 :     aMetadata.AddNativeSize(aMetadata.GetSize());
     190             :   }
     191             : 
     192           0 :   return NS_OK;
     193             : }
     194             : 
     195             : /* static */ already_AddRefed<gfx::SourceSurface>
     196           0 : ImageOps::DecodeToSurface(nsIInputStream* aInputStream,
     197             :                           const nsACString& aMimeType,
     198             :                           uint32_t aFlags,
     199             :                           const Maybe<IntSize>& aSize /* = Nothing() */)
     200             : {
     201           0 :   RefPtr<ImageBuffer> buffer = CreateImageBuffer(aInputStream);
     202           0 :   return DecodeToSurface(buffer, aMimeType, aFlags, aSize);
     203             : }
     204             : 
     205             : /* static */ already_AddRefed<gfx::SourceSurface>
     206           0 : ImageOps::DecodeToSurface(ImageBuffer* aBuffer,
     207             :                           const nsACString& aMimeType,
     208             :                           uint32_t aFlags,
     209             :                           const Maybe<IntSize>& aSize /* = Nothing() */)
     210             : {
     211           0 :   if (!aBuffer) {
     212           0 :     return nullptr;
     213             :   }
     214             : 
     215           0 :   RefPtr<SourceBuffer> sourceBuffer = aBuffer->GetSourceBuffer();
     216           0 :   if (NS_WARN_IF(!sourceBuffer)) {
     217           0 :     return nullptr;
     218             :   }
     219             : 
     220             :   // Create a decoder.
     221             :   DecoderType decoderType =
     222           0 :     DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get());
     223             :   RefPtr<Decoder> decoder =
     224           0 :     DecoderFactory::CreateAnonymousDecoder(decoderType,
     225           0 :                                            WrapNotNull(sourceBuffer),
     226           0 :                                            aSize, ToSurfaceFlags(aFlags));
     227           0 :   if (!decoder) {
     228           0 :     return nullptr;
     229             :   }
     230             : 
     231             :   // Run the decoder synchronously.
     232           0 :   RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder));
     233           0 :   task->Run();
     234           0 :   if (!decoder->GetDecodeDone() || decoder->HasError()) {
     235           0 :     return nullptr;
     236             :   }
     237             : 
     238             :   // Pull out the surface.
     239           0 :   RawAccessFrameRef frame = decoder->GetCurrentFrameRef();
     240           0 :   if (!frame) {
     241           0 :     return nullptr;
     242             :   }
     243             : 
     244           0 :   RefPtr<SourceSurface> surface = frame->GetSourceSurface();
     245           0 :   if (!surface) {
     246           0 :     return nullptr;
     247             :   }
     248             : 
     249           0 :   return surface.forget();
     250             : }
     251             : 
     252             : } // namespace image
     253             : } // namespace mozilla

Generated by: LCOV version 1.13