зеркало из https://github.com/mozilla/pjs.git
fix icon decoder on mac os x, don't call GetAlphaBytesPerRow and its underlying GetAlphaLineStride which is
plain wrong in Cairo. patch by Alfred Kayser. r=pav sr=tor
This commit is contained in:
Родитель
2e70b37445
Коммит
a3e2590c6d
|
@ -47,6 +47,9 @@
|
|||
#include "nsRect.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder)
|
||||
|
||||
|
@ -98,48 +101,50 @@ NS_IMETHODIMP nsIconDecoder::Flush()
|
|||
|
||||
NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
PRUint8 * const buf = (PRUint8 *)PR_Malloc(count);
|
||||
if (!buf) return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
// read the data from the input stram...
|
||||
PRUint32 readLen;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
PRUint8 buf[2];
|
||||
|
||||
nsresult rv = inStr->Read((char*)buf, 2, &readLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(readLen == 2, NS_ERROR_UNEXPECTED); // w, h
|
||||
count-=2;
|
||||
|
||||
// Read size
|
||||
PRInt32 w = buf[0];
|
||||
PRInt32 h = buf[1];
|
||||
NS_ENSURE_TRUE(w > 0 && h > 0, NS_ERROR_UNEXPECTED);
|
||||
gfx_format format = gfxIFormats::BGRA; // XXX not really
|
||||
#else
|
||||
PRUint8 * const buf = (PRUint8 *)PR_Malloc(count);
|
||||
if (!buf) return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
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;
|
||||
|
||||
// since WriteFrom is only called once, go ahead and fire the on start notifications..
|
||||
|
||||
mObserver->OnStartDecode(nsnull);
|
||||
// Read size
|
||||
PRInt32 w = *(data++);
|
||||
PRInt32 h = *(data++);
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
NS_ENSURE_TRUE(w > 0 && h > 0, NS_ERROR_UNEXPECTED);
|
||||
#else
|
||||
// Read size & alphaBits
|
||||
PRInt32 w = *data++;
|
||||
PRInt32 h = *data++;
|
||||
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
|
||||
|
||||
// since WriteFrom is only called once, go ahead and fire the on start notifications..
|
||||
if (mObserver)
|
||||
mObserver->OnStartDecode(nsnull);
|
||||
mImage->Init(w, h, mObserver);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
rv = mFrame->Init(0, 0, w, h, format, 24);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -148,6 +153,25 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
|
||||
nsIntRect r(0, 0, width, height);
|
||||
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
PRUint8 *data;
|
||||
PRUint8 dataLen;
|
||||
mFrame->GetImageData(&data, &dataLen);
|
||||
|
||||
// Ensure that there enough in the inputStream
|
||||
NS_ENSURE_TRUE(count >= dataLen, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Read the image data direct into the frame data
|
||||
rv = inStr->Read((char*)buf, PR_MIN(count, dataLen), &readLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Notify the image...
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
|
||||
#else
|
||||
PRUint32 bpr, abpr;
|
||||
PRInt32 width, height;
|
||||
mFrame->GetImageBytesPerRow(&bpr);
|
||||
|
@ -155,14 +179,6 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
mFrame->GetWidth(&width);
|
||||
mFrame->GetHeight(&height);
|
||||
|
||||
PRInt32 rownum;
|
||||
#if defined(MOZ_CAIRO_GFX)
|
||||
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);
|
||||
|
||||
|
@ -171,12 +187,11 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
|
||||
for (rownum = 0; rownum < height; ++rownum, data += abpr)
|
||||
mFrame->SetAlphaData(data, abpr, rownum * abpr);
|
||||
#endif
|
||||
nsIntRect r(0, 0, width, height);
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
|
||||
PR_Free(buf);
|
||||
|
||||
#endif
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче