Back out patch from bug 411718 again due to MH regression again.

This commit is contained in:
reed%reedloden.com 2008-01-21 09:48:18 +00:00
Родитель 61c85dac46
Коммит 5f7e973f96
2 изменённых файлов: 78 добавлений и 71 удалений

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

@ -85,15 +85,14 @@ nsJPEGDecoder::nsJPEGDecoder()
{ {
mState = JPEG_HEADER; mState = JPEG_HEADER;
mReading = PR_TRUE; mReading = PR_TRUE;
mError = NS_OK;
mBytesToSkip = 0; mBytesToSkip = 0;
memset(&mInfo, 0, sizeof(jpeg_decompress_struct)); memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
memset(&mSourceMgr, 0, sizeof(mSourceMgr)); memset(&mSourceMgr, 0, sizeof(mSourceMgr));
mInfo.client_data = (void*)this; mInfo.client_data = (void*)this;
mSegment = nsnull; mBuffer = nsnull;
mSegmentLen = 0; mBufferLen = mBufferSize = 0;
mBackBuffer = nsnull; mBackBuffer = nsnull;
mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0; mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0;
@ -108,6 +107,7 @@ nsJPEGDecoder::nsJPEGDecoder()
nsJPEGDecoder::~nsJPEGDecoder() nsJPEGDecoder::~nsJPEGDecoder()
{ {
PR_FREEIF(mBuffer);
PR_FREEIF(mBackBuffer); PR_FREEIF(mBackBuffer);
if (mTransform) if (mTransform)
cmsDeleteTransform(mTransform); cmsDeleteTransform(mTransform);
@ -125,6 +125,7 @@ nsJPEGDecoder::~nsJPEGDecoder()
/* void init (in imgILoad aLoad); */ /* void init (in imgILoad aLoad); */
NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad) NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad)
{ {
mImageLoad = aLoad;
mObserver = do_QueryInterface(aLoad); mObserver = do_QueryInterface(aLoad);
/* We set up the normal JPEG error routines, then override error_exit. */ /* We set up the normal JPEG error routines, then override error_exit. */
@ -168,14 +169,14 @@ NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad)
* If we have a mismatch in width/height for the container later on we will * If we have a mismatch in width/height for the container later on we will
* generate an error. * generate an error.
*/ */
aLoad->GetImage(getter_AddRefs(mImage)); mImageLoad->GetImage(getter_AddRefs(mImage));
if (!mImage) { if (!mImage) {
mImage = do_CreateInstance("@mozilla.org/image/container;1"); mImage = do_CreateInstance("@mozilla.org/image/container;1");
if (!mImage) if (!mImage)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
aLoad->SetImage(mImage); mImageLoad->SetImage(mImage);
nsresult result = mImage->SetDiscardable("image/jpeg"); nsresult result = mImage->SetDiscardable("image/jpeg");
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
mState = JPEG_ERROR; mState = JPEG_ERROR;
@ -195,17 +196,14 @@ NS_IMETHODIMP nsJPEGDecoder::Close()
PR_LOG(gJPEGlog, PR_LOG_DEBUG, PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::Close\n", this)); ("[this=%p] nsJPEGDecoder::Close\n", this));
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
NS_WARNING("Never finished decoding the JPEG.");
/* Step 8: Release JPEG decompression object */ /* Step 8: Release JPEG decompression object */
mInfo.src = nsnull; mInfo.src = nsnull;
jpeg_destroy_decompress(&mInfo); jpeg_destroy_decompress(&mInfo);
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) {
NS_WARNING("Never finished decoding the JPEG.");
/* Tell imgLoader that image decoding has failed */
return NS_ERROR_FAILURE;
}
return NS_OK; return NS_OK;
} }
@ -216,57 +214,58 @@ NS_IMETHODIMP nsJPEGDecoder::Flush()
PRUint32 ret; PRUint32 ret;
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER && mState != JPEG_ERROR) if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER && mState != JPEG_ERROR)
return this->ProcessData(nsnull, 0, &ret); return this->WriteFrom(nsnull, 0, &ret);
return NS_OK; return NS_OK;
} }
static NS_METHOD ReadDataOut(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
nsJPEGDecoder *decoder = static_cast<nsJPEGDecoder*>(closure);
nsresult rv = decoder->ProcessData(fromRawSegment, count, writeCount);
if (NS_FAILED(rv)) {
/* Tell imgLoader that image decoding has failed */
decoder->mError = rv;
*writeCount = 0;
}
return NS_OK;
}
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */ /* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *writeCount) NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{ {
NS_ENSURE_ARG_POINTER(inStr); LOG_SCOPE_WITH_PARAM(gJPEGlog, "nsJPEGDecoder::WriteFrom", "count", count);
NS_ENSURE_ARG_POINTER(writeCount);
/* necko doesn't propagate the errors from ReadDataOut */ PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
nsresult rv = inStr->ReadSegments(ReadDataOut, this, count, writeCount); ("nsJPEGDecoder::WriteFrom(decoder = %p) {\n"
if (NS_FAILED(mError)) { " image container %s; %u bytes to be added",
/* Tell imgLoader that image decoding has failed */ this,
rv = NS_ERROR_FAILURE; mImage ? "exists" : "does not exist",
} count));
return rv; if (inStr) {
} if (!mBuffer) {
mBuffer = (JOCTET *)PR_Malloc(count);
if (!mBuffer) {
mState = JPEG_ERROR;
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
("} (out of memory allocating buffer)"));
return NS_ERROR_OUT_OF_MEMORY;
}
mBufferSize = count;
} else if (count > mBufferSize) {
JOCTET *buf = (JOCTET *)PR_Realloc(mBuffer, count);
if (!buf) {
mState = JPEG_ERROR;
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
("} (out of memory resizing buffer)"));
return NS_ERROR_OUT_OF_MEMORY;
}
mBuffer = buf;
mBufferSize = count;
}
//****************************************************************************** nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen);
nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *writeCount) NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- inStr->Read failed");
{
LOG_SCOPE_WITH_PARAM(gJPEGlog, "nsJPEGDecoder::ProcessData", "count", count);
mSegment = (const JOCTET *)data; PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
mSegmentLen = count; ("nsJPEGDecoder::WriteFrom(): decoder %p got %u bytes, read %u from the stream (buffer size %u)",
*writeCount = count; this,
count,
mBufferLen,
mBufferSize));
*_retval = mBufferLen;
if (data && count) { nsresult result = mImage->AddRestoreData((char *) mBuffer, count);
nsresult result = mImage->AddRestoreData((char *) data, count);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
mState = JPEG_ERROR; mState = JPEG_ERROR;
@ -302,12 +301,12 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
} }
PR_LOG(gJPEGlog, PR_LOG_DEBUG, PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::ProcessData -- processing JPEG data\n", this)); ("[this=%p] nsJPEGDecoder::WriteFrom -- processing JPEG data\n", this));
switch (mState) { switch (mState) {
case JPEG_HEADER: case JPEG_HEADER:
{ {
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- entering JPEG_HEADER case"); LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_HEADER case");
/* Step 3: read file parameters with jpeg_read_header() */ /* Step 3: read file parameters with jpeg_read_header() */
if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) { if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) {
@ -495,7 +494,7 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
mImage->AppendFrame(mFrame); mImage->AppendFrame(mFrame);
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
(" JPEGDecoderAccounting: nsJPEGDecoder::ProcessData -- created image frame with %ux%u pixels", (" JPEGDecoderAccounting: nsJPEGDecoder::WriteFrom -- created image frame with %ux%u pixels",
mInfo.image_width, mInfo.image_height)); mInfo.image_width, mInfo.image_height));
} }
@ -505,7 +504,7 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
case JPEG_START_DECOMPRESS: case JPEG_START_DECOMPRESS:
{ {
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- entering JPEG_START_DECOMPRESS case"); LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_START_DECOMPRESS case");
/* Step 4: set parameters for decompression */ /* Step 4: set parameters for decompression */
/* FIXME -- Should reset dct_method and dither mode /* FIXME -- Should reset dct_method and dither mode
@ -536,7 +535,7 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
{ {
if (mState == JPEG_DECOMPRESS_SEQUENTIAL) if (mState == JPEG_DECOMPRESS_SEQUENTIAL)
{ {
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- JPEG_DECOMPRESS_SEQUENTIAL case"); LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_SEQUENTIAL case");
if (!OutputScanlines()) { if (!OutputScanlines()) {
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
@ -554,7 +553,7 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
{ {
if (mState == JPEG_DECOMPRESS_PROGRESSIVE) if (mState == JPEG_DECOMPRESS_PROGRESSIVE)
{ {
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- JPEG_DECOMPRESS_PROGRESSIVE case"); LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_PROGRESSIVE case");
int status; int status;
do { do {
@ -619,7 +618,7 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
{ {
nsresult result; nsresult result;
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- entering JPEG_DONE case"); LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case");
/* Step 7: Finish decompression */ /* Step 7: Finish decompression */
@ -644,13 +643,13 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
} }
case JPEG_SINK_NON_JPEG_TRAILER: case JPEG_SINK_NON_JPEG_TRAILER:
PR_LOG(gJPEGlog, PR_LOG_DEBUG, PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::ProcessData -- entering JPEG_SINK_NON_JPEG_TRAILER case\n", this)); ("[this=%p] nsJPEGDecoder::WriteFrom -- entering JPEG_SINK_NON_JPEG_TRAILER case\n", this));
break; break;
case JPEG_ERROR: case JPEG_ERROR:
PR_LOG(gJPEGlog, PR_LOG_DEBUG, PR_LOG(gJPEGlog, PR_LOG_DEBUG,
("[this=%p] nsJPEGDecoder::ProcessData -- entering JPEG_ERROR case\n", this)); ("[this=%p] nsJPEGDecoder::WriteFrom -- entering JPEG_ERROR case\n", this));
break; break;
} }
@ -675,6 +674,7 @@ nsJPEGDecoder::OutputScanlines()
mFrame->GetImageData(&imageData, &imageDataLength); mFrame->GetImageData(&imageData, &imageDataLength);
while ((mInfo.output_scanline < mInfo.output_height)) { while ((mInfo.output_scanline < mInfo.output_height)) {
/* Request one scanline. Returns 0 or 1 scanlines. */
PRUint32 *imageRow = ((PRUint32*)imageData) + PRUint32 *imageRow = ((PRUint32*)imageData) +
(mInfo.output_scanline * mInfo.output_width); (mInfo.output_scanline * mInfo.output_width);
@ -686,7 +686,6 @@ nsJPEGDecoder::OutputScanlines()
sampleRow += mInfo.output_width; sampleRow += mInfo.output_width;
} }
/* Request one scanline. Returns 0 or 1 scanlines. */
if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) { if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) {
rv = PR_FALSE; /* suspend */ rv = PR_FALSE; /* suspend */
break; break;
@ -879,13 +878,13 @@ fill_input_buffer (j_decompress_ptr jd)
nsJPEGDecoder *decoder = (nsJPEGDecoder *)(jd->client_data); nsJPEGDecoder *decoder = (nsJPEGDecoder *)(jd->client_data);
if (decoder->mReading) { if (decoder->mReading) {
const JOCTET *new_buffer = decoder->mSegment; unsigned char *new_buffer = (unsigned char *)decoder->mBuffer;
PRUint32 new_buflen = decoder->mSegmentLen; PRUint32 new_buflen = decoder->mBufferLen;
if (!new_buffer || new_buflen == 0) if (!new_buffer || new_buflen == 0)
return PR_FALSE; /* suspend */ return PR_FALSE; /* suspend */
decoder->mSegmentLen = 0; decoder->mBufferLen = 0;
if (decoder->mBytesToSkip) { if (decoder->mBytesToSkip) {
if (decoder->mBytesToSkip < new_buflen) { if (decoder->mBytesToSkip < new_buflen) {
@ -909,7 +908,7 @@ fill_input_buffer (j_decompress_ptr jd)
return PR_TRUE; return PR_TRUE;
} }
if (src->next_input_byte != decoder->mSegment) { if (src->next_input_byte != decoder->mBuffer) {
/* Backtrack data has been permanently consumed. */ /* Backtrack data has been permanently consumed. */
decoder->mBackBufferUnreadLen = 0; decoder->mBackBufferUnreadLen = 0;
decoder->mBackBufferLen = 0; decoder->mBackBufferLen = 0;
@ -950,7 +949,7 @@ fill_input_buffer (j_decompress_ptr jd)
} }
} }
/* Copy remainder of netlib segment into backtrack buffer. */ /* Copy remainder of netlib buffer into backtrack buffer. */
memmove(decoder->mBackBuffer + decoder->mBackBufferLen, memmove(decoder->mBackBuffer + decoder->mBackBufferLen,
src->next_input_byte, src->next_input_byte,
src->bytes_in_buffer); src->bytes_in_buffer);
@ -981,4 +980,9 @@ term_source (j_decompress_ptr jd)
decoder->mObserver->OnStopContainer(nsnull, decoder->mImage); decoder->mObserver->OnStopContainer(nsnull, decoder->mImage);
decoder->mObserver->OnStopDecode(nsnull, NS_OK, nsnull); decoder->mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
} }
PRBool isMutable = PR_FALSE;
if (decoder->mImageLoad)
decoder->mImageLoad->GetIsMultiPartChannel(&isMutable);
decoder->mFrame->SetMutable(isMutable);
} }

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

@ -91,13 +91,12 @@ public:
nsJPEGDecoder(); nsJPEGDecoder();
virtual ~nsJPEGDecoder(); virtual ~nsJPEGDecoder();
nsresult ProcessData(const char *data, PRUint32 count, PRUint32 *writeCount);
protected: protected:
PRBool OutputScanlines(); PRBool OutputScanlines();
public: public:
nsCOMPtr<imgIContainer> mImage; nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<imgILoad> mImageLoad;
nsCOMPtr<gfxIImageFrame> mFrame; nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIDecoderObserver> mObserver; nsCOMPtr<imgIDecoderObserver> mObserver;
@ -106,12 +105,12 @@ public:
struct jpeg_source_mgr mSourceMgr; struct jpeg_source_mgr mSourceMgr;
decoder_error_mgr mErr; decoder_error_mgr mErr;
jstate mState; jstate mState;
nsresult mError;
PRUint32 mBytesToSkip; PRUint32 mBytesToSkip;
const JOCTET *mSegment; // The current segment we are decoding from JOCTET *mBuffer;
PRUint32 mSegmentLen; // amount of data in mSegment PRUint32 mBufferLen; // amount of data currently in mBuffer
PRUint32 mBufferSize; // size in bytes what mBuffer was created with
JOCTET *mBackBuffer; JOCTET *mBackBuffer;
PRUint32 mBackBufferLen; // Offset of end of active backtrack data PRUint32 mBackBufferLen; // Offset of end of active backtrack data
@ -125,6 +124,10 @@ public:
cmsHTRANSFORM mTransform; cmsHTRANSFORM mTransform;
PRPackedBool mReading; PRPackedBool mReading;
private:
nsresult AddToTmpAccumulateBuffer(JOCTET *src, PRUint32 len);
}; };
#endif // nsJPEGDecoder_h__ #endif // nsJPEGDecoder_h__