Bug 274244: Display more broken GIFs. r=stuart sr=tor

This commit is contained in:
paper%animecity.nu 2005-03-08 03:44:28 +00:00
Родитель 270349107e
Коммит d541f29d90
23 изменённых файлов: 115 добавлений и 889 удалений

Просмотреть файл

@ -57,7 +57,7 @@ native nsRectRef(nsIntRect &);
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
*/
[scriptable, uuid(20caf74f-2c35-450f-9f87-c3ecc213553c)]
[scriptable, uuid(f6d00ee7-defc-4101-b2dc-e72cf4c37c3c)]
interface gfxIImageFrame : nsISupports
{
/**
@ -116,6 +116,11 @@ interface gfxIImageFrame : nsISupports
*/
readonly attribute gfx_format format;
/**
* returns whether the image requires the background to be painted
*/
readonly attribute boolean needsBackground;
/* data accessors */
readonly attribute unsigned long imageBytesPerRow;

Просмотреть файл

@ -164,6 +164,13 @@ public:
* @param aUpdateRect The rectangle to update
*/
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect) = 0;
/**
* Get whether this image's region is completely filled with data.
* @return PR_TRUE if image is complete, PR_FALSE if image is not yet
* complete or broken
*/
virtual PRBool GetIsImageComplete() = 0;
/**
* Converted this pixelmap to an optimized pixelmap for the device

Просмотреть файл

@ -154,6 +154,16 @@ void nsImageBeOS::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRec
mDecodedX2 = aUpdateRect->XMost();
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageBeOS::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}
// Draw the bitmap, this method has a source and destination coordinates
NS_IMETHODIMP nsImageBeOS::Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,

Просмотреть файл

@ -78,6 +78,7 @@ public:
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
nsMaskRequirements aMaskRequirements);

Просмотреть файл

@ -163,6 +163,13 @@ nsCairoImage::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *a
{
}
PRBool
nsCairoImage::GetIsImageComplete()
{
/* TODO: nsCairoImage needs to store coords of decoded data */
return PR_TRUE;
}
nsresult
nsCairoImage::Optimize(nsIDeviceContext* aContext)
{

Просмотреть файл

@ -63,6 +63,7 @@ public:
virtual PRBool GetHasAlphaMask();
virtual PRUint8 * GetAlphaBits();
virtual PRInt32 GetAlphaLineStride();
virtual PRBool GetIsImageComplete();
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual nsColorMap * GetColorMap();

Просмотреть файл

@ -309,6 +309,16 @@ void nsImageGTK::ImageUpdated(nsIDeviceContext *aContext,
mDecodedX2 = aUpdateRect->XMost();
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageGTK::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}
void nsImageGTK::UpdateCachedImage()
{
#ifdef TRACE_IMAGE_ALLOCATION

Просмотреть файл

@ -98,6 +98,7 @@ public:
void UpdateCachedImage();
virtual void ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth,
nsMaskRequirements aMaskRequirements);

Просмотреть файл

@ -193,6 +193,15 @@ nsImageMac::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
mDecodedX2 = aUpdateRect->XMost();
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageMac::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}
void DataProviderReleaseFunc(void *info, const void *data, size_t size)
{

Просмотреть файл

@ -70,6 +70,7 @@ public:
// mAlphaBits). 'aFlags' is ignored.
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags,
nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
// Optimizes memory usage for object.
virtual nsresult Optimize(nsIDeviceContext* aContext);

Просмотреть файл

@ -248,6 +248,17 @@ void nsImageOS2::ImageUpdated( nsIDeviceContext *aContext,
}
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageOS2::GetIsImageComplete() {
return mInfo &&
mDecodedRect.x == 0 &&
mDecodedRect.y == 0 &&
mDecodedRect.width == mInfo->cx &&
mDecodedRect.height == mInfo->cy;
}
void nsImageOS2::BuildBlenderLookup (void)
{
for (int y = 0 ; y < 256 ; y++)

Просмотреть файл

@ -75,6 +75,7 @@ public:
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
virtual nsColorMap* GetColorMap() {return mColorMap;}
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }

Просмотреть файл

@ -243,6 +243,16 @@ nsresult nsImagePh :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMas
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImagePh::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}
/** ----------------------------------------------------------------
* Draw the bitmap, this method has a source and destination coordinates
* @update dc - 11/20/98

Просмотреть файл

@ -106,6 +106,7 @@ public:
mDirtyFlags = aFlags;
mPhImage.size.h = mDecodedY2;
}
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
// virtual PRBool IsOptimized() { return mIsOptimized; }

Просмотреть файл

@ -1,538 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Lars Knoll <knoll@kde.org>
* Zack Rusin <zack@kde.org>
* John C. Griggs <johng@corel.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsImageQt.h"
#include "nsRenderingContextQt.h"
#include <qimage.h>
#include "nspr.h"
#include "qtlog.h"
#define IsFlagSet(a,b) ((a) & (b))
#ifdef CHECK_PIXMAPS
#include <qfileinfo.h>
static void savePixmap(const QPixmap &px)
{
static int i = 0;
QString baseFile( "saved_pixmap" );
const char *format = "PNG";
QString fileName = QString("%1%2.%2").arg(baseFile)
.arg(i).arg(format);
while (QFileInfo(fileName).exists()) {
++i;
fileName = QString("%1%2.%2").arg(baseFile)
.arg(i).arg(format);
}
px.save(fileName, format);
}
#endif
NS_IMPL_ISUPPORTS1(nsImageQt, nsIImage)
//------------------------------------------------------------
nsImageQt::nsImageQt()
: mWidth(0)
, mHeight(0)
, mDepth(0)
, mRowBytes(0)
, mImageBits(nsnull)
, mAlphaDepth(0)
, mAlphaRowBytes(0)
, mAlphaBits(nsnull)
, mNumBytesPixel(0)
, pixmapDirty(PR_FALSE)
{
}
//------------------------------------------------------------
nsImageQt::~nsImageQt()
{
if (nsnull != mImageBits) {
delete[] mImageBits;
mImageBits = nsnull;
}
if (nsnull != mAlphaBits) {
delete[] mAlphaBits;
mAlphaBits = nsnull;
}
}
//------------------------------------------------------------
nsresult nsImageQt::Init(PRInt32 aWidth,PRInt32 aHeight,
PRInt32 aDepth,
nsMaskRequirements aMaskRequirements)
{
qDebug("creating a pixmap with [%d,%d,%d]", aWidth, aHeight, aDepth);
// gfxImageFrame forces only one nsImageQt::Init
if (aWidth == 0 || aHeight == 0) {
return NS_ERROR_FAILURE;
}
// if (32 == aDepth) {
// mNumBytesPixel = 4;
// mDepth = aDepth;
// }
// else
if (24 == aDepth) {
mNumBytesPixel = 3;
mDepth = aDepth;
}
else {
NS_NOTREACHED("unexpected image depth");
return NS_ERROR_UNEXPECTED;
}
mWidth = aWidth;
mHeight = aHeight;
mRowBytes = (mWidth*mDepth/8 + 3) & ~0x3;
switch (aMaskRequirements) {
case nsMaskRequirements_kNeeds1Bit:
mAlphaRowBytes = (aWidth + 7) / 8;
mAlphaDepth = 1;
// 32-bit align each row
mAlphaRowBytes = (mAlphaRowBytes + 3) & ~0x3;
break;
case nsMaskRequirements_kNeeds8Bit:
mAlphaRowBytes = aWidth;
mAlphaDepth = 8;
// 32-bit align each row
mAlphaRowBytes = (mAlphaRowBytes + 3) & ~0x3;
break;
default:
mAlphaDepth = 0;
mAlphaRowBytes = 0;
break;
}
mImageBits = (PRUint8*)new PRUint8[mRowBytes * mHeight];
mAlphaBits = new PRUint8[mAlphaRowBytes * mHeight];
pixmapDirty = PR_TRUE;
PR_LOG(gQtLogModule, QT_BASIC, ("nsImageQt::Init succeeded"));
return NS_OK;
}
//------------------------------------------------------------
PRInt32 nsImageQt::GetHeight()
{
return mHeight;
}
PRInt32 nsImageQt::GetWidth()
{
return mWidth;
}
PRUint8 *nsImageQt::GetBits()
{
return mImageBits;
}
void *nsImageQt::GetBitInfo()
{
return nsnull;
}
PRInt32 nsImageQt::GetLineStride()
{
return mRowBytes;
}
nsColorMap *nsImageQt::GetColorMap()
{
return nsnull;
}
PRUint8 *nsImageQt::GetAlphaBits()
{
return mAlphaBits;
}
PRInt32 nsImageQt::GetAlphaLineStride()
{
return mAlphaRowBytes;
}
//------------------------------------------------------------
// set up the palette to the passed in color array, RGB only in this array
void nsImageQt::ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags,nsRect *aUpdateRect)
{
//qDebug("image updated");
if (IsFlagSet(nsImageUpdateFlags_kBitsChanged,aFlags))
pixmapDirty = PR_TRUE;
mDecodedRect.UnionRect(mDecodedRect, *aUpdateRect);
}
// Draw the bitmap, this method has a source and destination coordinates
NS_IMETHODIMP nsImageQt::Draw(nsIRenderingContext &aContext,
nsIDrawingSurface *aSurface,
PRInt32 aSX, PRInt32 aSY,
PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY,
PRInt32 aDWidth, PRInt32 aDHeight)
{
// qDebug("draw x = %d, y = %d, w = %d, h = %d, dx = %d, dy = %d, dw = %d, dy = %d",
// aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight);
if (aSWidth <= 0 || aDWidth <= 0 || aSHeight <= 0 || aDHeight <= 0)
return NS_OK;
if (nsnull == aSurface) {
return NS_ERROR_FAILURE;
}
if (pixmapDirty)
updatePixmap();
nsDrawingSurfaceQt *drawing = (nsDrawingSurfaceQt*)aSurface;
// The code below seems to be wrong and not what gecko expects.
// if ((aSWidth != aDWidth || aSHeight != aDHeight)
// && (aSWidth != mWidth || aSHeight != mHeight)) {
// QPixmap tmp(aSWidth, aSHeight);
// copyBlt(&tmp, 0, 0, &pixmap, aSX, aSY, aSWidth, aSHeight);
// drawing->GetGC()->drawPixmap(aDX, aDY, pixmap, aSX, aSY, aSWidth, aSHeight);
// }
nsRect sourceRect(aSX, aSY, aSWidth, aSHeight);
if (!sourceRect.IntersectRect(sourceRect, mDecodedRect))
return NS_OK;
// Now get the part of the image that should be drawn
// Copy into a new image so we can scale afterwards
QImage image(pixmap.convertToImage().copy(sourceRect.x, sourceRect.y,
sourceRect.width, sourceRect.height));
if (image.isNull())
return NS_ERROR_FAILURE;
// Find the scale factor
float w_factor = (float)aDWidth / aSWidth;
float h_factor = (float)aDHeight / aSHeight;
// If we had to draw only part of the requested image, must adjust
// destination coordinates
aDX += PRInt32((sourceRect.x - aSX) * w_factor);
aDY += PRInt32((sourceRect.y - aSY) * h_factor);
image = image.scale(int(sourceRect.width * w_factor), int(sourceRect.height * h_factor));
drawing->GetGC()->drawImage(QPoint(aDX, aDY), image);
//drawing->GetGC()->drawPixmap(aDX, aDY, pixmap, aSX, aSY, aSWidth, aSHeight);
return NS_OK;
}
//------------------------------------------------------------
// Draw the bitmap, this draw just has destination coordinates
NS_IMETHODIMP nsImageQt::Draw(nsIRenderingContext &aContext,
nsIDrawingSurface *aSurface,
PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight)
{
return Draw(aContext, aSurface, 0, 0, mWidth, mHeight, aX, aY, aWidth, aHeight);
}
void nsImageQt::updatePixmap()
{
//qDebug("updatePixmap");
QImage qimage(mWidth, mHeight, 32);
const PRInt32 bytesPerPixel = mDepth / 8;
PRUint8 *image = mImageBits;
PRUint8 *alpha = mAlphaBits;
PRInt32 i,j;
QRgb *line;
qimage.setAlphaBuffer(mAlphaDepth != 0);
switch(mAlphaDepth) {
case 0:
for (i = 0; i < mHeight; i++) {
line = (QRgb*)qimage.scanLine(i);
PRUint8 *imagePtr = image;
for (j = 0; j < mWidth; j++) {
line[j] = qRgb(*imagePtr, *(imagePtr+1), *(imagePtr+2));
imagePtr += bytesPerPixel;
}
image += mRowBytes;
}
break;
case 1:
for (i = 0; i < mHeight; i++) {
line = (QRgb*)qimage.scanLine(i);
PRUint8 *imagePtr = image;
for (j = 0; j < mWidth; j++) {
uchar a = (alpha[j / 8] & (1 << (7 - (j % 8)))) ? 0xff : 0;
line[j] = qRgba(*imagePtr, *(imagePtr+1), *(imagePtr+2), a);
imagePtr += bytesPerPixel;
}
image += mRowBytes;
alpha += mAlphaRowBytes;
}
break;
case 8:
for (i = 0; i < mHeight; i++) {
line = (QRgb*)qimage.scanLine(i);
PRUint8 *imagePtr = image;
PRUint8 *alphaPtr = alpha;
for (j = 0; j < mWidth; j++) {
line[j] = qRgba(*imagePtr, *(imagePtr+1), *(imagePtr+2), *alphaPtr);
imagePtr += bytesPerPixel;
alphaPtr++;
}
image += mRowBytes;
alpha += mAlphaRowBytes;
}
break;
}
pixmap = QPixmap(qimage);
#ifdef CHECK_PIXMAPS
savePixmap(pixmap);
#endif
pixmapDirty = PR_FALSE;
}
NS_IMETHODIMP nsImageQt::DrawTile(nsIRenderingContext &aContext,
nsIDrawingSurface *aSurface,
PRInt32 aSXOffset, PRInt32 aSYOffset,
PRInt32 aPadX, PRInt32 aPadY,
const nsRect &aTileRect)
{
//qDebug("draw tile");
#if 1
nsRect aSrcRect(aSXOffset, aSYOffset, mWidth, mHeight);
nsDrawingSurfaceQt *drawing = (nsDrawingSurfaceQt*)aSurface;
if (aTileRect.width <= 0 || aTileRect.height <= 0) {
NS_ASSERTION(aTileRect.width > 0 && aTileRect.height > 0,
"Error: image has 0 width or height!");
return NS_OK;
}
if (drawing->GetDepth() == 8 || mAlphaDepth == 8) {
PRInt32 aY0 = aTileRect.y, aX0 = aTileRect.x;
PRInt32 aY1 = aTileRect.y + aTileRect.height;
PRInt32 aX1 = aTileRect.x + aTileRect.width;
for (PRInt32 y = aY0; y < aY1; y += aSrcRect.height + aPadY)
for (PRInt32 x = aX0; x < aX1; x += aSrcRect.width + aPadX)
Draw(aContext, aSurface, x, y, PR_MIN(aSrcRect.width, aX1 - x),
PR_MIN(aSrcRect.height, aY1 - y));
return NS_OK;
}
#if 0
// Render unique image bits onto an off screen pixmap only once
// The image bits can change as a result of ImageUpdated() - for
// example: animated GIFs.
if (nsnull == mImagePixmap) {
CreateImagePixmap();
}
if (nsnull == mImagePixmap)
return NS_ERROR_FAILURE;
QPixmap qPmap;
qPmap.convertFromImage(*mImagePixmap);
#endif
/*qDebug("draw tilePixmap x = %d, y = %d, wid = %d, hei = %d, sx = %d, sy = %d",
aTileRect.x, aTileRect.y, aTileRect.width, aTileRect.height,
aSrcRect.x, aSrcRect.y);*/
drawing->GetGC()->drawTiledPixmap(aTileRect.x, aTileRect.y,
aTileRect.width, aTileRect.height,
pixmap, aSrcRect.x, aSrcRect.y);
//qPmap, aSrcRect.x, aSrcRect.y);
#endif
return NS_OK;
}
//------------------------------------------------------------
nsresult nsImageQt::Optimize(nsIDeviceContext* aContext)
{
return NS_OK;
}
PRInt32 nsImageQt::GetBytesPix()
{
return mNumBytesPixel;
}
//------------------------------------------------------------
// lock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageQt::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageQt::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
NS_IMETHODIMP nsImageQt::DrawToImage(nsIImage* aDstImage,
nscoord aDX, nscoord aDY,
nscoord aDWidth, nscoord aDHeight)
{
//qDebug("DrawToIMAGE");
nsImageQt *dest = NS_STATIC_CAST(nsImageQt *, aDstImage);
if (!dest)
return NS_ERROR_FAILURE;
if (aDX >= dest->mWidth || aDY >= dest->mHeight)
return NS_OK;
PRUint8 *rgbPtr=0, *alphaPtr=0;
PRUint32 rgbStride, alphaStride;
rgbPtr = mImageBits;
rgbStride = mRowBytes;
alphaPtr = mAlphaBits;
alphaStride = mAlphaRowBytes;
PRInt32 y;
PRInt32 ValidWidth = ( aDWidth < ( dest->mWidth - aDX ) ) ? aDWidth : ( dest->mWidth - aDX );
PRInt32 ValidHeight = ( aDHeight < ( dest->mHeight - aDY ) ) ? aDHeight : ( dest->mHeight - aDY );
// now composite the two images together
switch (mAlphaDepth) {
case 1:
{
PRUint8 *dst = dest->mImageBits + aDY*dest->mRowBytes + 3*aDX;
PRUint8 *dstAlpha = dest->mAlphaBits + aDY*dest->mAlphaRowBytes;
PRUint8 *src = rgbPtr;
PRUint8 *alpha = alphaPtr;
PRUint8 offset = aDX & 0x7; // x starts at 0
int iterations = (ValidWidth+7)/8; // round up
for (y=0; y<ValidHeight; y++) {
for (int x=0; x<ValidWidth; x += 8, dst += 3*8, src += 3*8) {
PRUint8 alphaPixels = *alpha++;
if (alphaPixels == 0) {
// all 8 transparent; jump forward
continue;
}
// 1 or more bits are set, handle dstAlpha now - may not be aligned.
// Are all 8 of these alpha pixels used?
if (x+7 >= ValidWidth) {
alphaPixels &= 0xff << (8 - (ValidWidth-x)); // no, mask off unused
if (alphaPixels == 0)
continue; // no 1 alpha pixels left
}
if (offset == 0) {
dstAlpha[(aDX+x)>>3] |= alphaPixels; // the cheap aligned case
}
else {
dstAlpha[(aDX+x)>>3] |= alphaPixels >> offset;
// avoid write if no 1's to write - also avoids going past end of array
PRUint8 alphaTemp = alphaPixels << (8U - offset);
if (alphaTemp & 0xff)
dstAlpha[((aDX+x)>>3) + 1] |= alphaTemp;
}
if (alphaPixels == 0xff) {
// fix - could speed up by gathering a run of 0xff's and doing 1 memcpy
// all 8 pixels set; copy and jump forward
memcpy(dst,src,8*3);
continue;
}
else {
// else mix of 1's and 0's in alphaPixels, do 1 bit at a time
// Don't go past end of line!
PRUint8 *d = dst, *s = src;
for (PRUint8 aMask = 1<<7, j = 0; aMask && j < ValidWidth-x; aMask >>= 1, j++) {
// if this pixel is opaque then copy into the destination image
if (alphaPixels & aMask) {
// might be faster with *d++ = *s++ 3 times?
d[0] = s[0];
d[1] = s[1];
d[2] = s[2];
// dstAlpha bit already set
}
d += 3;
s += 3;
}
}
}
// at end of each line, bump pointers. Use wordy code because of
// bug 127455 to avoid possibility of unsigned underflow
dst = (dst - 3*8*iterations) + dest->mRowBytes;
src = (src - 3*8*iterations) + rgbStride;
alpha = (alpha - iterations) + alphaStride;
dstAlpha += dest->mAlphaRowBytes;
}
}
break;
case 0:
default:
for (y=0; y<ValidHeight; y++)
memcpy(dest->mImageBits + (y+aDY)*dest->mRowBytes + 3*aDX,
rgbPtr + y*rgbStride,
3*ValidWidth);
}
nsRect rect(aDX, aDY, ValidWidth, ValidHeight);
dest->ImageUpdated(nsnull, 0, &rect);
return NS_OK;
}

Просмотреть файл

@ -1,138 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Lars Knoll <knoll@kde.org>
* Zack Rusin <zack@kde.org>
* John C. Griggs <johng@corel.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsImageQt_h___
#define nsImageQt_h___
#include "nsIImage.h"
#include "nsRect.h"
#include <qpixmap.h>
#undef Bool
class nsImageQt : public nsIImage
{
public:
nsImageQt();
virtual ~nsImageQt();
NS_DECL_ISUPPORTS
/**
* @see nsIImage.h
*/
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual PRInt32 GetBytesPix();
virtual PRBool GetIsRowOrderTopToBottom() {return PR_TRUE;}
virtual PRInt32 GetHeight();
virtual PRInt32 GetWidth();
virtual PRUint8 *GetBits();
virtual PRInt32 GetLineStride();
virtual PRBool GetHasAlphaMask() {return mAlphaBits != nsnull;}
virtual PRUint8 *GetAlphaBits();
virtual PRInt32 GetAlphaLineStride();
virtual void ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags,nsRect *aUpdateRect);
virtual nsresult Optimize(nsIDeviceContext *aContext);
virtual nsColorMap *GetColorMap();
NS_IMETHOD Draw(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD Draw(nsIRenderingContext &aContext,
nsIDrawingSurface *aSurface,
PRInt32 aSX, PRInt32 aSY,
PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY,
PRInt32 aDWidth, PRInt32 aDHeight);
NS_IMETHOD DrawTile(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aSXOffset, PRInt32 aSYOffset,
PRInt32 aPadX, PRInt32 aPadY,
const nsRect &aTileRect);
NS_IMETHOD DrawToImage(nsIImage *aDstImage, PRInt32 aDX, PRInt32 aDY,
PRInt32 aDWidth, PRInt32 aDHeight);
virtual PRInt8 GetAlphaDepth() { return(mAlphaDepth); }
virtual void *GetBitInfo();
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
/**
* Calculate the amount of memory needed for the initialization of the
* image
*/
void updatePixmap();
private:
PRInt32 mWidth;
PRInt32 mHeight;
PRInt32 mDepth;
PRInt32 mRowBytes;
PRUint8 *mImageBits;
PRInt8 mAlphaDepth; // alpha layer depth
PRInt16 mAlphaRowBytes; // alpha bytes per row
PRUint8 *mAlphaBits;
PRInt8 mNumBytesPixel;
nsRect mDecodedRect; // Keeps track of what part of image has been decoded.
QPixmap pixmap;
PRBool pixmapDirty;
};
#endif

Просмотреть файл

@ -232,6 +232,19 @@ NS_IMETHODIMP gfxImageFrame::GetFormat(gfx_format *aFormat)
return NS_OK;
}
/* readonly attribute boolean needsBackground; */
NS_IMETHODIMP gfxImageFrame::GetNeedsBackground(PRBool *aNeedsBackground)
{
if (!mInitalized)
return NS_ERROR_NOT_INITIALIZED;
*aNeedsBackground = (mFormat != gfxIFormats::RGB &&
mFormat != gfxIFormats::BGR) ||
!mImage->GetIsImageComplete();
return NS_OK;
}
/* readonly attribute unsigned long imageBytesPerRow; */
NS_IMETHODIMP gfxImageFrame::GetImageBytesPerRow(PRUint32 *aBytesPerRow)
{

Просмотреть файл

@ -259,6 +259,17 @@ nsImageWin :: ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *a
mDecodedX2 = aUpdateRect->XMost();
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageWin::GetIsImageComplete() {
return mInitialized &&
mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mBHead->biWidth &&
mDecodedY2 == mBHead->biHeight;
}
//------------------------------------------------------------
struct MONOBITMAPINFO {
@ -1088,8 +1099,7 @@ nsImageWin::ProgressiveDoubleBlit(nsIDeviceContext *aContext,
return PR_FALSE;
}
}
mTmpHBitmap = ::CreateCompatibleBitmap(theHDC, mBHead->biWidth,
mBHead->biHeight);
mTmpHBitmap = ::CreateCompatibleBitmap(theHDC, mDecodedX2, mDecodedY2);
if (!mTmpHBitmap) {
::DeleteDC(imgDC);
if (maskDC) {

Просмотреть файл

@ -101,6 +101,7 @@ public:
nscoord aDWidth, nscoord aDHeight);
virtual nsColorMap* GetColorMap() {return mColorMap;}
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool GetIsImageComplete();
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }

Просмотреть файл

@ -265,6 +265,16 @@ void nsImageXlib::ImageUpdated(nsIDeviceContext *aContext,
mDecodedX2 = aUpdateRect->XMost();
}
/** ---------------------------------------------------
* See documentation in nsIImage.h
*/
PRBool nsImageXlib::GetIsImageComplete() {
return mDecodedX1 == 0 &&
mDecodedY1 == 0 &&
mDecodedX2 == mWidth &&
mDecodedY2 == mHeight;
}
void nsImageXlib::UpdateCachedImage()
{
nsRegionRectIterator ri(mUpdateRegion);

Просмотреть файл

@ -1,198 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Hartshorn <peter@igelaus.com.au>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsImageXlib_h__
#define nsImageXlib_h__
#include "nsIImage.h"
#include "nsPoint.h"
#include "nsGCCache.h"
#include "nsRegion.h"
#include "xlibrgb.h"
class nsImageXlib : public nsIImage {
public:
nsImageXlib();
virtual ~nsImageXlib();
NS_DECL_ISUPPORTS
virtual PRInt32 GetBytesPix() { return mNumBytesPixel; }
virtual PRInt32 GetHeight();
virtual PRInt32 GetWidth();
virtual PRUint8* GetBits();
virtual void* GetBitInfo();
virtual PRBool GetIsRowOrderTopToBottom() { return PR_TRUE; }
virtual PRInt32 GetLineStride();
virtual nsColorMap* GetColorMap();
NS_IMETHOD Draw(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aX, PRInt32 aY,
PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD Draw(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
NS_IMETHOD DrawToImage(nsIImage* aDstImage, nscoord aDX, nscoord aDY,
nscoord aDWidth, nscoord aDHeight);
NS_IMETHOD DrawTile(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aSXOffset, PRInt32 aSYOffset,
PRInt32 aPadX, PRInt32 aPadY,
const nsRect &aTileRect);
void UpdateCachedImage();
virtual void ImageUpdated(nsIDeviceContext *aContext,
PRUint8 aFlags, nsRect *aUpdateRect);
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth,
nsMaskRequirements aMaskRequirements);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRUint8* GetAlphaBits();
virtual PRInt32 GetAlphaLineStride();
/**
* Get the alpha depth for the image mask
* @update - lordpixel 2001/05/16
* @return the alpha mask depth for the image, ie, 0, 1 or 8
*/
virtual PRInt8 GetAlphaDepth() {return(mAlphaDepth);}
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
/**
* Calculate the amount of memory needed for the initialization of the image
*/
void ComputeMetrics() {
mRowBytes = (mWidth * mDepth) >> 5;
if (((PRUint32)mWidth * mDepth) & 0x1F)
mRowBytes++;
mRowBytes <<= 2;
mSizeImage = mRowBytes * mHeight;
};
void ComputePaletteSize(PRIntn nBitCount);
private:
NS_IMETHODIMP DrawScaled(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
static unsigned scaled6[1<<6];
static unsigned scaled5[1<<5];
void DrawComposited32(PRBool isLSB, PRBool flipBytes,
PRUint8 *imageOrigin, PRUint32 imageStride,
PRUint8 *alphaOrigin, PRUint32 alphaStride,
unsigned width, unsigned height,
XImage *ximage, unsigned char *readData);
void DrawComposited24(PRBool isLSB, PRBool flipBytes,
PRUint8 *imageOrigin, PRUint32 imageStride,
PRUint8 *alphaOrigin, PRUint32 alphaStride,
unsigned width, unsigned height,
XImage *ximage, unsigned char *readData);
void DrawComposited16(PRBool isLSB, PRBool flipBytes,
PRUint8 *imageOrigin, PRUint32 imageStride,
PRUint8 *alphaOrigin, PRUint32 alphaStride,
unsigned width, unsigned height,
XImage *ximage, unsigned char *readData);
void DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
PRUint8 *imageOrigin, PRUint32 imageStride,
PRUint8 *alphaOrigin, PRUint32 alphaStride,
unsigned width, unsigned height,
XImage *ximage, unsigned char *readData);
inline void DrawComposited(nsIRenderingContext &aContext,
nsIDrawingSurface* aSurface,
PRInt32 aSX, PRInt32 aSY,
PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY,
PRInt32 aDWidth, PRInt32 aDHeight);
inline void TilePixmap(Pixmap src, Pixmap dest, PRInt32 aSXOffset, PRInt32 aSYOffset,
const nsRect &destRect, const nsRect &clipRect, PRBool useClip);
inline void CreateAlphaBitmap(PRInt32 aWidth, PRInt32 aHeight);
inline void CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight);
inline void DrawImageOffscreen(PRInt32 aSX, PRInt32 aSY,
PRInt32 aWidth, PRInt32 aHeight);
inline void SetupGCForAlpha(GC aGC, PRInt32 aX, PRInt32 aY);
// image bits
PRUint8 *mImageBits;
PRUint8 *mAlphaBits;
Pixmap mImagePixmap;
Pixmap mAlphaPixmap;
PRInt32 mWidth;
PRInt32 mHeight;
PRInt32 mDepth; // bits per pixel
PRInt32 mRowBytes;
GC mGC;
PRInt32 mSizeImage;
PRInt8 mNumBytesPixel;
PRInt32 mDecodedX1; //Keeps track of what part of image
PRInt32 mDecodedY1; // has been decoded.
PRInt32 mDecodedX2;
PRInt32 mDecodedY2;
nsRegion mUpdateRegion;
static XlibRgbHandle *mXlibRgbHandle;
static Display *mDisplay;
// alpha layer members
PRInt8 mAlphaDepth; // alpha layer depth
PRInt16 mAlphaRowBytes; // alpha bytes per row
PRPackedBool mAlphaValid;
PRPackedBool mIsSpacer;
PRPackedBool mPendingUpdate;
PRUint8 mFlags; // flags set by ImageUpdated
};
#endif /* !nsImageXlib_h__ */

Просмотреть файл

@ -2936,12 +2936,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
nsCOMPtr<gfxIImageFrame> gfxImgFrame;
image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
if (gfxImgFrame) {
gfx_format frameFormat;
gfxImgFrame->GetFormat(&frameFormat);
NS_ASSERTION(frameFormat >= 0 && frameFormat <= 7,
"Unknown gfxIFormats value");
needBackgroundColor = frameFormat != gfxIFormats::RGB &&
frameFormat != gfxIFormats::BGR;
gfxImgFrame->GetNeedsBackground(&needBackgroundColor);
/* check for tiling of a image where frame smaller than container */
nsSize iSize;

Просмотреть файл

@ -239,7 +239,7 @@ NS_IMETHODIMP nsGIFDecoder2::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
PRUint32 numFrames = 0;
if (mImageContainer)
mImageContainer->GetNumFrames(&numFrames);
if (numFrames <= 1)
if (numFrames <= 0)
return NS_ERROR_FAILURE;
}
@ -359,11 +359,7 @@ int nsGIFDecoder2::EndImageFrame(
}
decoder->mImageContainer->EndFrameDecode(aFrameNumber, aDelayTimeout);
// if the gif is corrupt don't mark the frame as complete, as nsCSSRendering
// will happily try using it to draw a background
if (decoder->mObserver &&
decoder->mImageFrame &&
decoder->mGIFStruct->state != gif_error) {
if (decoder->mObserver && decoder->mImageFrame) {
decoder->FlushImageData();
if (aFrameNumber == 1) {