Bug 276692 move image->GdkPixbuf conversion code to nsImageGTK

r=bryner sr=roc
This commit is contained in:
cbiesinger@web.de
2005-01-24 18:10:06 +00:00
parent f705b35161
commit 3fd76f88c3
5 changed files with 179 additions and 107 deletions

View File

@@ -54,6 +54,8 @@
#include "nsIImageLoadingContent.h"
#include "imgIRequest.h"
#include "imgIContainer.h"
#include "nsIImage.h"
#include "nsIGdkPixbufImage.h"
#include "nsColor.h"
#include <glib.h>
@@ -342,113 +344,15 @@ nsGNOMEShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
static nsresult
WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
{
PRInt32 width, height;
aImage->GetWidth(&width);
aImage->GetHeight(&height);
nsCOMPtr<nsIGdkPixbufImage> pixImg(do_GetInterface(aImage));
if (!pixImg)
return NS_ERROR_NOT_AVAILABLE;
PRInt32 format;
aImage->GetFormat(&format);
GdkPixbuf* pixbuf = pixImg->GetGdkPixbuf();
if (!pixbuf)
return NS_ERROR_NOT_AVAILABLE;
aImage->LockImageData();
PRUint32 bytesPerRow;
aImage->GetImageBytesPerRow(&bytesPerRow);
PRUint32 bpp = bytesPerRow / width * 8;
// XXX If bpp is not 24, we will need to do something else, like
// allocate a new pixbuf and copy the data in ourselves.
if (bpp != 24)
return NS_ERROR_FAILURE;
PRUint8 *bits;
PRUint32 length;
aImage->GetImageData(&bits, &length);
if (!bits) return NS_ERROR_FAILURE;
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(bits,
GDK_COLORSPACE_RGB,
PR_FALSE,
8,
width,
height,
bytesPerRow,
NULL,
NULL);
GdkPixbuf *alphaPixbuf = nsnull;
if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::RGB_A8) {
aImage->LockAlphaData();
PRUint32 alphaBytesPerRow, alphaDepth, alphaLength;
aImage->GetAlphaBytesPerRow(&alphaBytesPerRow);
#if 0
if (format == gfxIFormats::RGB_A1)
alphaDepth = 1;
else
alphaDepth = 8;
#endif
switch (format) {
case gfxIFormats::RGB_A1:
alphaDepth = 1;
break;
case gfxIFormats::RGB_A8:
alphaDepth = 8;
break;
default:
// not reached
return NS_ERROR_UNEXPECTED;
}
PRUint8 *alphaBits;
aImage->GetAlphaData(&alphaBits, &alphaLength);
alphaPixbuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
// Run through alphaBits and copy the alpha mask into the pixbuf's
// alpha channel.
PRUint8 *maskRow = alphaBits;
PRUint8 *pixbufRow = gdk_pixbuf_get_pixels(alphaPixbuf);
gint pixbufRowStride = gdk_pixbuf_get_rowstride(alphaPixbuf);
gint pixbufChannels = gdk_pixbuf_get_n_channels(alphaPixbuf);
for (PRInt32 y = 0; y < height; ++y) {
PRUint8 *pixbufPixel = pixbufRow;
PRUint8 *maskPixel = maskRow;
// If using 1-bit alpha, we must expand it to 8-bit
PRUint32 bitPos = 7;
for (PRInt32 x = 0; x < width; ++x) {
if (alphaDepth == 1) {
pixbufPixel[pixbufChannels - 1] = ((*maskPixel >> bitPos) & 1) ? 255 : 0;
if (bitPos-- == 0) { // wrapped around, move forward a byte
++maskPixel;
bitPos = 7;
}
} else {
pixbufPixel[pixbufChannels - 1] = *maskPixel++;
}
pixbufPixel += pixbufChannels;
}
pixbufRow += pixbufRowStride;
maskRow += alphaBytesPerRow;
}
}
gboolean res = gdk_pixbuf_save(alphaPixbuf ? alphaPixbuf : pixbuf,
aPath.get(), "png", NULL, NULL);
if (alphaPixbuf) {
aImage->UnlockAlphaData();
g_object_unref(alphaPixbuf);
}
gboolean res = gdk_pixbuf_save(pixbuf, aPath.get(), "png", NULL, NULL);
aImage->UnlockImageData();
g_object_unref(pixbuf);