зеркало из https://github.com/mozilla/gecko-dev.git
Use a different internal icon format ifdef MOZ_CAIRO_GFX that is easier to convert to the image frame format we use, and make the relevant icon channel implementations produce it. b=333253 r=pavlov
This commit is contained in:
Родитель
3ed1cd85e7
Коммит
c0407d49ab
|
@ -314,7 +314,11 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// Got a bitmap and color space info - convert data to mozilla's icon format
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
PRUint32 iconLength = 2 + iconSize * iconSize * 4;
|
||||
#else
|
||||
PRUint32 iconLength = 3 + iconSize * (iconSize * 3 + alphaBytesPerRow);
|
||||
#endif
|
||||
uint8 *buffer = new uint8[iconLength];
|
||||
if (!buffer)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -322,7 +326,9 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
uint8* destByte = buffer;
|
||||
*(destByte++) = iconSize;
|
||||
*(destByte++) = iconSize;
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
*(destByte++) = 1; // alpha bits per pixel
|
||||
#endif
|
||||
|
||||
// RGB data
|
||||
uint8* sourceByte = (uint8*)nativeIcon.Bits();
|
||||
|
@ -334,15 +340,32 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
if (*sourceByte != B_TRANSPARENT_MAGIC_CMAP8)
|
||||
{
|
||||
rgb_color colorVal = mainScreen.ColorForIndex(*sourceByte);
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
*(destByte++) = colorVal.blue;
|
||||
*(destByte++) = colorVal.green;
|
||||
*(destByte++) = colorVal.red;
|
||||
*(destByte++) = uint8(255);
|
||||
#else
|
||||
*(destByte++) = uint8(255);
|
||||
*(destByte++) = colorVal.red;
|
||||
*(destByte++) = colorVal.green;
|
||||
*(destByte++) = colorVal.blue;
|
||||
#endif
|
||||
#else
|
||||
*(destByte++) = colorVal.blue;
|
||||
*(destByte++) = colorVal.green;
|
||||
*(destByte++) = colorVal.red;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
*destByte++ = 0;
|
||||
*destByte++ = 0;
|
||||
*destByte++ = 0;
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
*destByte++ = 0;
|
||||
#endif
|
||||
}
|
||||
// original code had a conditional here:
|
||||
// if (iconCol < iconSize - 1)
|
||||
|
@ -350,6 +373,7 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
sourceByte++;
|
||||
}
|
||||
}
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
// Alpha data - bitmask, with rows aligned on 32-bit boundaries
|
||||
for(PRUint32 iconRow = 0; iconRow < iconSize; iconRow++)
|
||||
{
|
||||
|
@ -372,6 +396,9 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
destByte++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(buffer + iconLength == destByte, "size miscalculation");
|
||||
|
||||
// Now, create a pipe and stuff our data into it
|
||||
nsCOMPtr<nsIInputStream> inStream;
|
||||
|
|
|
@ -83,35 +83,67 @@ moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI *aURI,
|
|||
NS_ERROR_UNEXPECTED);
|
||||
|
||||
const int n_channels = 4;
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
gsize buf_size = 2 + n_channels * height * width;
|
||||
#else
|
||||
gsize buf_size = 3 + n_channels * height * width;
|
||||
#endif
|
||||
PRUint8 * const buf = (PRUint8*)NS_Alloc(buf_size);
|
||||
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
|
||||
PRUint8 *out = buf;
|
||||
|
||||
*(out++) = width;
|
||||
*(out++) = height;
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
*(out++) = 8; // bits of alpha per pixel
|
||||
#endif
|
||||
|
||||
const guchar * const pixels = gdk_pixbuf_get_pixels(aPixbuf);
|
||||
int rowextra = gdk_pixbuf_get_rowstride(aPixbuf) - width * n_channels;
|
||||
|
||||
// encode the RGB data and the A data
|
||||
const guchar * in = pixels;
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
PRUint8 *alpha_out = out + height * width * 3;
|
||||
#ifdef DEBUG
|
||||
PRUint8 * const alpha_start = alpha_out;
|
||||
#endif
|
||||
#endif
|
||||
for (int y = 0; y < height; ++y, in += rowextra) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
PRUint8 r = *(in++);
|
||||
PRUint8 g = *(in++);
|
||||
PRUint8 b = *(in++);
|
||||
PRUint8 a = *(in++);
|
||||
#define DO_PREMULTIPLY(c_) PRUint8(PRUint16(c_) * PRUint16(a) / PRUint16(255))
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
*(out++) = DO_PREMULTIPLY(b);
|
||||
*(out++) = DO_PREMULTIPLY(g);
|
||||
*(out++) = DO_PREMULTIPLY(r);
|
||||
*(out++) = a;
|
||||
#else
|
||||
*(out++) = a;
|
||||
*(out++) = DO_PREMULTIPLY(r);
|
||||
*(out++) = DO_PREMULTIPLY(g);
|
||||
*(out++) = DO_PREMULTIPLY(b);
|
||||
#endif
|
||||
#undef DO_PREMULTIPLY
|
||||
#else
|
||||
*(out++) = *(in++); // R
|
||||
*(out++) = *(in++); // G
|
||||
*(out++) = *(in++); // B
|
||||
*(alpha_out++) = *(in++); // A
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
NS_ASSERTION(out == buf + buf_size, "size miscalculation");
|
||||
#else
|
||||
NS_ASSERTION(out == alpha_start && alpha_out == buf + buf_size,
|
||||
"size miscalculation");
|
||||
#endif
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringInputStream> stream =
|
||||
|
|
|
@ -312,7 +312,11 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
PRUint8* bitmapRepData = (PRUint8*)[bitmapRep bitmapData];
|
||||
|
||||
// create our buffer
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
PRInt32 bufferCapacity = 2 + desiredImageSize * desiredImageSize * 4;
|
||||
#else
|
||||
PRInt32 bufferCapacity = 3 + desiredImageSize * desiredImageSize * 5;
|
||||
#endif
|
||||
nsAutoBuffer<PRUint8, 3 + 16 * 16 * 5> iconBuffer; // initial size is for 16x16
|
||||
if (!iconBuffer.EnsureElemCapacity(bufferCapacity))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -322,7 +326,9 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
// write header data into buffer
|
||||
*iconBufferPtr++ = desiredImageSize;
|
||||
*iconBufferPtr++ = desiredImageSize;
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
*iconBufferPtr++ = 8; // alpha bits per pixel
|
||||
#endif
|
||||
|
||||
PRUint32 dataCount = (desiredImageSize * desiredImageSize) * 4;
|
||||
PRUint32 index = 0;
|
||||
|
@ -333,6 +339,7 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
PRUint8 b = bitmapRepData[index++];
|
||||
PRUint8 a = bitmapRepData[index++];
|
||||
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
// reverse premultiplication
|
||||
if (a == 0) {
|
||||
r = g = b = 0;
|
||||
|
@ -342,21 +349,35 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
|
|||
g = ((PRUint32) g) * 255 / a;
|
||||
b = ((PRUint32) b) * 255 / a;
|
||||
}
|
||||
#endif
|
||||
|
||||
// write data out to our buffer - the real alpha data is appended to the
|
||||
// end of the stream, the alpha here is just an unused extra channel
|
||||
// write data out to our buffer
|
||||
// non-cairo uses native image format, but the A channel is ignored.
|
||||
// cairo uses ARGB (highest to lowest bits)
|
||||
#if defined(MOZ_CAIRO_GFX) && defined(IS_LITTLE_ENDIAN)
|
||||
*iconBufferPtr++ = b;
|
||||
*iconBufferPtr++ = g;
|
||||
*iconBufferPtr++ = r;
|
||||
*iconBufferPtr++ = a;
|
||||
#else
|
||||
*iconBufferPtr++ = a;
|
||||
*iconBufferPtr++ = r;
|
||||
*iconBufferPtr++ = g;
|
||||
*iconBufferPtr++ = b;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
// add the alpha to the buffer
|
||||
index = 3;
|
||||
while (index < dataCount) {
|
||||
*iconBufferPtr++ = bitmapRepData[index];
|
||||
index += 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(iconBufferPtr == iconBuffer.get() + bufferCapacity,
|
||||
"buffer size miscalculation");
|
||||
|
||||
// Now, create a pipe and stuff our data into it
|
||||
nsCOMPtr<nsIInputStream> inStream;
|
||||
|
|
|
@ -107,7 +107,11 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
PRUint32 readLen;
|
||||
rv = inStr->Read((char*)buf, count, &readLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
NS_ENSURE_TRUE(readLen >= 2, NS_ERROR_UNEXPECTED); // w, h
|
||||
#else
|
||||
NS_ENSURE_TRUE(readLen >= 3, NS_ERROR_UNEXPECTED); // w, h, alphaBits
|
||||
#endif
|
||||
|
||||
PRUint8 * const buf_end = buf + readLen;
|
||||
PRUint8 *data = buf;
|
||||
|
@ -118,16 +122,24 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
// Read size
|
||||
PRInt32 w = *(data++);
|
||||
PRInt32 h = *(data++);
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
NS_ENSURE_TRUE(w > 0 && h > 0, NS_ERROR_UNEXPECTED);
|
||||
#else
|
||||
PRUint8 alphaBits = *(data++);
|
||||
NS_ENSURE_TRUE(w > 0 && h > 0 && (alphaBits == 1 || alphaBits == 8),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
#endif
|
||||
|
||||
mImage->Init(w, h, mObserver);
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
gfx_format format = gfxIFormats::BGRA; // XXX not really
|
||||
#else
|
||||
gfx_format format = alphaBits == 1 ? gfx_format(gfxIFormats::RGB_A1)
|
||||
: gfx_format(gfxIFormats::RGB_A8);
|
||||
#endif
|
||||
rv = mFrame->Init(0, 0, w, h, format, 24);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -145,34 +157,11 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
|
||||
PRInt32 rownum;
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
return NS_ERROR_FAILURE; // this code is totally busted.. fixing shortly.
|
||||
|
||||
PRUint8 *row = (PRUint8*)malloc(bpr);
|
||||
PRUint8 *adata = data + (bpr * height);
|
||||
for (rownum = 0; rownum < height; ++rownum, data += bpr) {
|
||||
PRUint8 *rowdata = data;
|
||||
for (int i = 0; i < bpr; i++) {
|
||||
const PRUint8 r = *rowdata++;
|
||||
const PRUint8 g = *rowdata++;
|
||||
const PRUint8 b = *rowdata++;
|
||||
const PRUint8 a = (format == gfxIFormats::RGB_A1) ? adata[i>>3] : adata[i];
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
// BGRX
|
||||
*row++ = b;
|
||||
*row++ = g;
|
||||
*row++ = r;
|
||||
*row++ = a;
|
||||
#else
|
||||
// XRGB
|
||||
*row++ = a;
|
||||
*row++ = r;
|
||||
*row++ = g;
|
||||
*row++ = b;
|
||||
#endif
|
||||
}
|
||||
mFrame->SetImageData(row, bpr, rownum * bpr);
|
||||
}
|
||||
free(row);
|
||||
NS_ENSURE_TRUE(buf_end - data >= PRInt32(bpr) * height,
|
||||
NS_ERROR_UNEXPECTED);
|
||||
|
||||
for (rownum = 0; rownum < height; ++rownum, data += bpr)
|
||||
mFrame->SetImageData(data, bpr, rownum * bpr);
|
||||
#else
|
||||
NS_ENSURE_TRUE(buf_end - data >= PRInt32(bpr + abpr) * height,
|
||||
NS_ERROR_UNEXPECTED);
|
||||
|
|
|
@ -68,13 +68,23 @@
|
|||
// support multiple ODA calls yet.
|
||||
// (2) the format of the incoming data is as follows:
|
||||
// The first two bytes contain the width and the height of the icon.
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
// The remaining bytes contain the icon data, 4 bytes per pixel, in
|
||||
// ARGB order (platform endianness, A in highest bits, B in lowest
|
||||
// bits), row-primary, top-to-bottom, left-to-right, with
|
||||
// premultiplied alpha.
|
||||
#else
|
||||
// The third byte contains the number of bits per pixel in the alpha
|
||||
// channel (either 1 or 8).
|
||||
// Followed by 3 bytes per pixel for the color bitmap row after row,
|
||||
// from top to bottom, with pixels left to right within rows, and
|
||||
// RGB order within pixels, in platform endianness.
|
||||
// RGB order within pixels, in platform endianness. Alpha is
|
||||
// *not* premultiplied.
|
||||
// XXXldb This isn't quite right -- we're just using
|
||||
// platform-native format.
|
||||
// Followed by alpha data (1 or 8 bits per pixel, see above) in the
|
||||
// same order as the RGB data, and also in platform endianness.
|
||||
#endif
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -244,6 +244,13 @@ nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile ** aLocalFile, PRUint32 *
|
|||
|
||||
nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBlocking)
|
||||
{
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
// This needs to be changed to match the format changes described in
|
||||
// nsIconDecoder.h. For cairo, the icon format is ARGB (A in highest
|
||||
// bits, B in lowest bits, based on platform endianness).
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
||||
// get some details about this icon
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
PRUint32 desiredImageSize;
|
||||
|
|
Загрузка…
Ссылка в новой задаче