зеркало из https://github.com/mozilla/gecko-dev.git
Finish relanding Bug 389273 - large favicons (>32 KB) won't show up in url bar autocomplete, history / bookmarks menu, bm organizer.
This commit is contained in:
Родитель
b5557fcea9
Коммит
2d80c7fc26
|
@ -59,14 +59,12 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "mozStorageHelper.h"
|
||||
|
||||
// This is the maximum favicon size that we will bother storing. Most icons
|
||||
// are about 4K. Some people add 32x32 versions at different bit depths,
|
||||
// making them much bigger. It would be nice if could extract just the 16x16
|
||||
// version that we need. Instead, we'll just store everything below this
|
||||
// sanity threshold.
|
||||
#define MAX_FAVICON_SIZE 32768
|
||||
// For favicon optimization
|
||||
#include "imgITools.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#define FAVICON_BUFFER_INCREMENT 8192
|
||||
|
||||
|
@ -553,6 +551,24 @@ nsFaviconService::SetFaviconData(nsIURI* aFavicon, const PRUint8* aData,
|
|||
PRTime aExpiration)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 dataLen = aDataLen;
|
||||
const PRUint8* data = aData;
|
||||
const nsACString* mimeType = &aMimeType;
|
||||
nsCString newData, newMimeType;
|
||||
|
||||
// If the page provided a large image for the favicon (eg, a highres image
|
||||
// or a multiresolution .ico file), we don't want to store more data than
|
||||
// needed. An uncompressed 16x16 RGBA image is 1024 bytes, and almost all
|
||||
// sensible 16x16 icons are under 1024 bytes.
|
||||
if (aDataLen > 1024) {
|
||||
rv = OptimizeFaviconImage(aData, aDataLen, aMimeType, newData, newMimeType);
|
||||
if (NS_SUCCEEDED(rv) && newData.Length() < aDataLen) {
|
||||
data = reinterpret_cast<PRUint8*>(const_cast<char*>(newData.get())),
|
||||
dataLen = newData.Length();
|
||||
mimeType = &newMimeType;
|
||||
}
|
||||
}
|
||||
|
||||
mozIStorageStatement* statement;
|
||||
{
|
||||
// this block forces the scoper to reset our statement: necessary for the
|
||||
|
@ -583,9 +599,9 @@ nsFaviconService::SetFaviconData(nsIURI* aFavicon, const PRUint8* aData,
|
|||
mozStorageStatementScoper scoper(statement);
|
||||
|
||||
// the insert and update statements share all but the 0th parameter
|
||||
rv = statement->BindBlobParameter(1, aData, aDataLen);
|
||||
rv = statement->BindBlobParameter(1, data, dataLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindUTF8StringParameter(2, aMimeType);
|
||||
rv = statement->BindUTF8StringParameter(2, *mimeType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->BindInt64Parameter(3, aExpiration);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -800,6 +816,48 @@ nsFaviconService::GetFaviconSpecForIconString(const nsCString& aSpec, nsACString
|
|||
}
|
||||
|
||||
|
||||
// nsFaviconService::OptimizeFaviconImage
|
||||
//
|
||||
// Given a blob of data (a image file already read into a buffer), optimize
|
||||
// its size by recompressing it as a 16x16 PNG.
|
||||
nsresult
|
||||
nsFaviconService::OptimizeFaviconImage(const PRUint8* aData, PRUint32 aDataLen,
|
||||
const nsACString& aMimeType,
|
||||
nsACString& aNewData,
|
||||
nsACString& aNewMimeType)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
||||
nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1");
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
reinterpret_cast<const char*>(aData), aDataLen,
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// decode image
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
rv = imgtool->DecodeImageData(stream, aMimeType, getter_AddRefs(container));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aNewMimeType.AssignLiteral("image/png");
|
||||
|
||||
// scale and recompress
|
||||
nsCOMPtr<nsIInputStream> iconStream;
|
||||
rv = imgtool->EncodeScaledImage(container, aNewMimeType, 16, 16,
|
||||
getter_AddRefs(iconStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Read the stream into a new buffer.
|
||||
rv = NS_ConsumeStream(iconStream, PR_UINT32_MAX, aNewData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS4(FaviconLoadListener,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener,
|
||||
|
@ -926,9 +984,6 @@ FaviconLoadListener::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext
|
|||
nsIInputStream *aInputStream,
|
||||
PRUint32 aOffset, PRUint32 aCount)
|
||||
{
|
||||
if (aOffset + aCount > MAX_FAVICON_SIZE)
|
||||
return NS_ERROR_FAILURE; // too big
|
||||
|
||||
nsCString buffer;
|
||||
nsresult rv = NS_ConsumeStream(aInputStream, aCount, buffer);
|
||||
if (rv != NS_BASE_STREAM_WOULD_BLOCK && NS_FAILED(rv))
|
||||
|
|
|
@ -87,6 +87,9 @@ public:
|
|||
nsresult GetFaviconLinkForIconString(const nsCString& aIcon, nsIURI** aOutput);
|
||||
void GetFaviconSpecForIconString(const nsCString& aIcon, nsACString& aOutput);
|
||||
|
||||
static nsresult OptimizeFaviconImage(const PRUint8* aData, PRUint32 aDataLen,
|
||||
const nsACString& aMimeType,
|
||||
nsACString& aNewData, nsACString& aNewMimeType);
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFAVICONSERVICE
|
||||
|
||||
|
|
|
@ -100,9 +100,6 @@ var iconsvc;
|
|||
function run_test() {
|
||||
try {
|
||||
|
||||
// Disable test for now.
|
||||
return;
|
||||
|
||||
/* ========== 0 ========== */
|
||||
var testnum = 0;
|
||||
var testdesc = "nsIFaviconService setup";
|
||||
|
@ -113,6 +110,13 @@ iconsvc = Cc["@mozilla.org/browser/favicon-service;1"].
|
|||
if (!iconsvc)
|
||||
throw "Couldn't get nsIFaviconService service"
|
||||
|
||||
// Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes
|
||||
// +/- 1 value compared to other platforms, so we need to compare against a
|
||||
// different set of reference images. nsIXULRuntime.OS doesn't seem to be
|
||||
// available in xpcshell, so we'll use this as a kludgy way to figure out if
|
||||
// we're running on Windows.
|
||||
var isWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
|
||||
|
||||
|
||||
/* ========== 1 ========== */
|
||||
testnum++;
|
||||
|
@ -220,8 +224,11 @@ var expectedData = readFileData(expectedFile);
|
|||
|
||||
// Compare thet expected data to the actual data.
|
||||
do_check_eq("image/png", outMimeType);
|
||||
// Disabled on Windows due to problems with pixels varying slightly.
|
||||
if (!isWindows)
|
||||
compareArrays(expectedData, outData);
|
||||
|
||||
|
||||
/* ========== 6 ========== */
|
||||
testnum++;
|
||||
testdesc = "test storing an oversize 48x48 icon ";
|
||||
|
|
Загрузка…
Ссылка в новой задаче