LCOV - code coverage report
Current view: top level - widget/gtk - nsImageToPixbuf.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 53 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* vim:set sw=4 sts=4 et cin: */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include <gdk-pixbuf/gdk-pixbuf.h>
       7             : 
       8             : #include "nsImageToPixbuf.h"
       9             : 
      10             : #include "imgIContainer.h"
      11             : #include "mozilla/gfx/2D.h"
      12             : #include "mozilla/RefPtr.h"
      13             : 
      14             : using mozilla::gfx::DataSourceSurface;
      15             : using mozilla::gfx::SurfaceFormat;
      16             : 
      17           0 : NS_IMPL_ISUPPORTS(nsImageToPixbuf, nsIImageToPixbuf)
      18             : 
      19             : inline unsigned char
      20           0 : unpremultiply (unsigned char color,
      21             :                unsigned char alpha)
      22             : {
      23           0 :     if (alpha == 0)
      24           0 :         return 0;
      25             :     // plus alpha/2 to round instead of truncate
      26           0 :     return (color * 255 + alpha / 2) / alpha;
      27             : }
      28             : 
      29             : NS_IMETHODIMP_(GdkPixbuf*)
      30           0 : nsImageToPixbuf::ConvertImageToPixbuf(imgIContainer* aImage)
      31             : {
      32           0 :     return ImageToPixbuf(aImage);
      33             : }
      34             : 
      35             : GdkPixbuf*
      36           0 : nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
      37             : {
      38             :     RefPtr<SourceSurface> surface =
      39           0 :       aImage->GetFrame(imgIContainer::FRAME_CURRENT,
      40           0 :                        imgIContainer::FLAG_SYNC_DECODE);
      41             : 
      42             :     // If the last call failed, it was probably because our call stack originates
      43             :     // in an imgINotificationObserver event, meaning that we're not allowed request
      44             :     // a sync decode. Presumably the originating event is something sensible like
      45             :     // OnStopFrame(), so we can just retry the call without a sync decode.
      46           0 :     if (!surface)
      47           0 :       surface = aImage->GetFrame(imgIContainer::FRAME_CURRENT,
      48           0 :                                  imgIContainer::FLAG_NONE);
      49             : 
      50           0 :     NS_ENSURE_TRUE(surface, nullptr);
      51             : 
      52           0 :     return SourceSurfaceToPixbuf(surface,
      53           0 :                                  surface->GetSize().width,
      54           0 :                                  surface->GetSize().height);
      55             : }
      56             : 
      57             : GdkPixbuf*
      58           0 : nsImageToPixbuf::SourceSurfaceToPixbuf(SourceSurface* aSurface,
      59             :                                        int32_t aWidth,
      60             :                                        int32_t aHeight)
      61             : {
      62           0 :     MOZ_ASSERT(aWidth <= aSurface->GetSize().width &&
      63             :                aHeight <= aSurface->GetSize().height,
      64             :                "Requested rect is bigger than the supplied surface");
      65             : 
      66             :     GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
      67           0 :                                        aWidth, aHeight);
      68           0 :     if (!pixbuf)
      69           0 :         return nullptr;
      70             : 
      71           0 :     uint32_t destStride = gdk_pixbuf_get_rowstride (pixbuf);
      72           0 :     guchar* destPixels = gdk_pixbuf_get_pixels (pixbuf);
      73             : 
      74           0 :     RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
      75             :     DataSourceSurface::MappedSurface map;
      76           0 :     if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map))
      77           0 :         return nullptr;
      78             : 
      79           0 :     uint8_t* srcData = map.mData;
      80           0 :     int32_t srcStride = map.mStride;
      81             : 
      82           0 :     SurfaceFormat format = dataSurface->GetFormat();
      83             : 
      84           0 :     for (int32_t row = 0; row < aHeight; ++row) {
      85           0 :         for (int32_t col = 0; col < aWidth; ++col) {
      86           0 :             guchar* destPixel = destPixels + row * destStride + 4 * col;
      87             : 
      88             :             uint32_t* srcPixel =
      89           0 :                 reinterpret_cast<uint32_t*>((srcData + row * srcStride + 4 * col));
      90             : 
      91           0 :             if (format == SurfaceFormat::B8G8R8A8) {
      92           0 :                 const uint8_t a = (*srcPixel >> 24) & 0xFF;
      93           0 :                 const uint8_t r = unpremultiply((*srcPixel >> 16) & 0xFF, a);
      94           0 :                 const uint8_t g = unpremultiply((*srcPixel >>  8) & 0xFF, a);
      95           0 :                 const uint8_t b = unpremultiply((*srcPixel >>  0) & 0xFF, a);
      96             : 
      97           0 :                 *destPixel++ = r;
      98           0 :                 *destPixel++ = g;
      99           0 :                 *destPixel++ = b;
     100           0 :                 *destPixel++ = a;
     101             :             } else {
     102           0 :                 MOZ_ASSERT(format == SurfaceFormat::B8G8R8X8);
     103             : 
     104           0 :                 const uint8_t r = (*srcPixel >> 16) & 0xFF;
     105           0 :                 const uint8_t g = (*srcPixel >>  8) & 0xFF;
     106           0 :                 const uint8_t b = (*srcPixel >>  0) & 0xFF;
     107             : 
     108           0 :                 *destPixel++ = r;
     109           0 :                 *destPixel++ = g;
     110           0 :                 *destPixel++ = b;
     111           0 :                 *destPixel++ = 0xFF; // A
     112             :             }
     113             :         }
     114             :     }
     115             : 
     116           0 :     dataSurface->Unmap();
     117             : 
     118           0 :     return pixbuf;
     119             : }
     120             : 

Generated by: LCOV version 1.13