image/decoders/icon/qt/nsIconChannel.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* vim:set ts=2 sw=2 sts=2 cin et: */
     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/. */
     6 #include <QIcon>
     8 #include <stdlib.h>
     9 #include <unistd.h>
    11 #include "mozilla/Endian.h"
    13 #include "nsMimeTypes.h"
    14 #include "nsIMIMEService.h"
    16 #include "nsIStringBundle.h"
    18 #include "nsNetUtil.h"
    19 #include "nsIURL.h"
    21 #include "nsIconChannel.h"
    22 #include "nsGtkQtIconsConverter.h"
    24 NS_IMPL_ISUPPORTS(nsIconChannel,
    25                   nsIRequest,
    26                   nsIChannel)
    28 static nsresult
    29 moz_qicon_to_channel(QImage *image, nsIURI *aURI,
    30                      nsIChannel **aChannel)
    31 {
    32   NS_ENSURE_ARG_POINTER(image);
    34   int width = image->width();
    35   int height = image->height();
    37   NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0,
    38                  NS_ERROR_UNEXPECTED);
    40   const int n_channels = 4;
    41   long int buf_size = 2 + n_channels * height * width;
    42   uint8_t * const buf = (uint8_t*)NS_Alloc(buf_size);
    43   NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
    44   uint8_t *out = buf;
    46   *(out++) = width;
    47   *(out++) = height;
    49   const uchar * const pixels = image->bits();
    50   int rowextra = image->bytesPerLine() - width * n_channels;
    52   // encode the RGB data and the A data
    53   const uchar * in = pixels;
    54   for (int y = 0; y < height; ++y, in += rowextra) {
    55     for (int x = 0; x < width; ++x) {
    56       uint8_t r = *(in++);
    57       uint8_t g = *(in++);
    58       uint8_t b = *(in++);
    59       uint8_t a = *(in++);
    60 #define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
    61 #if MOZ_LITTLE_ENDIAN
    62       *(out++) = DO_PREMULTIPLY(b);
    63       *(out++) = DO_PREMULTIPLY(g);
    64       *(out++) = DO_PREMULTIPLY(r);
    65       *(out++) = a;
    66 #else
    67       *(out++) = a;
    68       *(out++) = DO_PREMULTIPLY(r);
    69       *(out++) = DO_PREMULTIPLY(g);
    70       *(out++) = DO_PREMULTIPLY(b);
    71 #endif
    72 #undef DO_PREMULTIPLY
    73     }
    74   }
    76   NS_ASSERTION(out == buf + buf_size, "size miscalculation");
    78   nsresult rv;
    79   nsCOMPtr<nsIStringInputStream> stream =
    80     do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
    81   NS_ENSURE_SUCCESS(rv, rv);
    83   rv = stream->AdoptData((char*)buf, buf_size);
    84   NS_ENSURE_SUCCESS(rv, rv);
    86   return NS_NewInputStreamChannel(aChannel, aURI, stream,
    87                                   NS_LITERAL_CSTRING(IMAGE_ICON_MS));
    88 }
    90 nsresult
    91 nsIconChannel::Init(nsIURI* aURI)
    92 {
    94   nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
    95   NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
    97   nsAutoCString stockIcon;
    98   iconURI->GetStockIcon(stockIcon);
   100   nsAutoCString iconSizeString;
   101   iconURI->GetIconSize(iconSizeString);
   103   uint32_t desiredImageSize;
   104   iconURI->GetImageSize(&desiredImageSize);
   106   nsAutoCString iconStateString;
   107   iconURI->GetIconState(iconStateString);
   108   bool disabled = iconStateString.EqualsLiteral("disabled");
   110   // This is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=662299
   111   // Try to find corresponding freedesktop icon and fallback to empty QIcon if failed.
   112   QIcon icon = QIcon::fromTheme(QString(stockIcon.get()).replace("gtk-", "edit-"));
   113   QPixmap pixmap = icon.pixmap(desiredImageSize, desiredImageSize, disabled ? QIcon::Disabled : QIcon::Normal);
   115   QImage image = pixmap.toImage();
   117   return moz_qicon_to_channel(&image, iconURI,
   118                               getter_AddRefs(mRealChannel));
   119 }

mercurial