image/decoders/icon/android/nsIconChannel.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     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 <stdlib.h>
     7 #include "mozilla/dom/ContentChild.h"
     8 #include "nsMimeTypes.h"
     9 #include "nsIURL.h"
    10 #include "nsXULAppAPI.h"
    11 #include "AndroidBridge.h"
    12 #include "nsIconChannel.h"
    13 #include "nsIStringStream.h"
    14 #include "nsNetUtil.h"
    16 NS_IMPL_ISUPPORTS(nsIconChannel,
    17                   nsIRequest,
    18                   nsIChannel)
    20 using namespace mozilla;
    21 using mozilla::dom::ContentChild;
    23 static nsresult
    24 GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf)
    25 {
    26     if (!AndroidBridge::Bridge())
    27         return NS_ERROR_FAILURE;
    29     AndroidBridge::Bridge()->GetIconForExtension(aFileExt, aIconSize, aBuf);
    31     return NS_OK;
    32 }
    34 static nsresult
    35 CallRemoteGetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf)
    36 {
    37   NS_ENSURE_TRUE(aBuf != nullptr, NS_ERROR_NULL_POINTER);
    39   // An array has to be used to get data from remote process
    40   InfallibleTArray<uint8_t> bits;
    41   uint32_t bufSize = aIconSize * aIconSize * 4;
    43   if (!ContentChild::GetSingleton()->SendGetIconForExtension(PromiseFlatCString(aFileExt), aIconSize, &bits))
    44     return NS_ERROR_FAILURE;
    46   NS_ASSERTION(bits.Length() == bufSize, "Pixels array is incomplete");
    47   if (bits.Length() != bufSize)
    48     return NS_ERROR_FAILURE;
    50   memcpy(aBuf, bits.Elements(), bufSize);
    52   return NS_OK;
    53 }
    55 static nsresult
    56 moz_icon_to_channel(nsIURI *aURI, const nsACString& aFileExt, uint32_t aIconSize, nsIChannel **aChannel)
    57 {
    58   NS_ENSURE_TRUE(aIconSize < 256 && aIconSize > 0, NS_ERROR_UNEXPECTED);
    60   int width = aIconSize;
    61   int height = aIconSize;
    63   // moz-icon data should have two bytes for the size,
    64   // then the ARGB pixel values with pre-multiplied Alpha
    65   const int channels = 4;
    66   long int buf_size = 2 + channels * height * width;
    67   uint8_t * const buf = (uint8_t*)NS_Alloc(buf_size);
    68   NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
    69   uint8_t * out = buf;
    71   *(out++) = width;
    72   *(out++) = height;
    74   nsresult rv;
    75   if (XRE_GetProcessType() == GeckoProcessType_Default)
    76     rv = GetIconForExtension(aFileExt, aIconSize, out);
    77   else
    78     rv = CallRemoteGetIconForExtension(aFileExt, aIconSize, out);
    79   NS_ENSURE_SUCCESS(rv, rv);
    81   // Encode the RGBA data
    82   const uint8_t * in = out;
    83   for (int y = 0; y < height; ++y) {
    84     for (int x = 0; x < width; ++x) {
    85       uint8_t r = *(in++);
    86       uint8_t g = *(in++);
    87       uint8_t b = *(in++);
    88       uint8_t a = *(in++);
    89 #define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
    90       *(out++) = DO_PREMULTIPLY(b);
    91       *(out++) = DO_PREMULTIPLY(g);
    92       *(out++) = DO_PREMULTIPLY(r);
    93       *(out++) = a;
    94 #undef DO_PREMULTIPLY
    95     }
    96   }
    98   nsCOMPtr<nsIStringInputStream> stream =
    99     do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
   100   NS_ENSURE_SUCCESS(rv, rv);
   102   rv = stream->AdoptData((char*)buf, buf_size);
   103   NS_ENSURE_SUCCESS(rv, rv);
   105   return NS_NewInputStreamChannel(aChannel, aURI, stream,
   106                                   NS_LITERAL_CSTRING(IMAGE_ICON_MS));
   107 }
   109 nsresult
   110 nsIconChannel::Init(nsIURI* aURI)
   111 {
   112   nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
   113   NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
   115   nsAutoCString stockIcon;
   116   iconURI->GetStockIcon(stockIcon);
   118   uint32_t desiredImageSize;
   119   iconURI->GetImageSize(&desiredImageSize);
   121   nsAutoCString iconFileExt;
   122   iconURI->GetFileExtension(iconFileExt);
   124   return moz_icon_to_channel(iconURI, iconFileExt, desiredImageSize, getter_AddRefs(mRealChannel));
   125 }

mercurial