зеркало из https://github.com/mozilla/pjs.git
fix for bug 117983. patch from Mark Wilkinson <mhw@kremvax.net>. r=pavlov sr=ben
This commit is contained in:
Родитель
e91e4ae8ba
Коммит
f5e155d8f3
|
@ -22,6 +22,16 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Current limitations:
|
||||
*
|
||||
* Doesn't handle PGM and PPM files for which the maximum sample value
|
||||
* is something other than 255.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "nsPPMDecoder.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
|
@ -29,6 +39,7 @@
|
|||
#include "imgIContainerObserver.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
|
@ -36,20 +47,66 @@
|
|||
|
||||
NS_IMPL_ISUPPORTS1(nsPPMDecoder, imgIDecoder)
|
||||
|
||||
/*
|
||||
* "F_" stands for "find", so F_TYPE means we're looking for the image type
|
||||
* digit.
|
||||
*/
|
||||
enum ParseState {
|
||||
F_P,
|
||||
F_TYPE,
|
||||
F_WIDTH,
|
||||
F_HEIGHT,
|
||||
F_MAXVAL,
|
||||
F_INITIALIZE,
|
||||
F_TEXTBITDATA,
|
||||
F_TEXTDATA,
|
||||
F_RAWDATA
|
||||
};
|
||||
|
||||
/*
|
||||
* What kind of white space do we skip.
|
||||
*/
|
||||
enum Skip {
|
||||
NOTHING,
|
||||
WHITESPACE,
|
||||
SINGLEWHITESPACE,
|
||||
TOENDOFLINE
|
||||
};
|
||||
|
||||
/*
|
||||
* We look up the digit after the initial 'P' in this string to check
|
||||
* whether it's valid; the index is then used with the following
|
||||
* constants.
|
||||
*/
|
||||
static char ppmTypes[] = "1231456";
|
||||
|
||||
enum {
|
||||
TYPE_PBM = 0,
|
||||
TYPE_PGM = 1,
|
||||
TYPE_PPM = 2,
|
||||
PPMTYPE = 0x3,
|
||||
PPMRAW = 0x4
|
||||
};
|
||||
|
||||
nsPPMDecoder::nsPPMDecoder()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mDataReceived = 0;
|
||||
mDataWritten = 0;
|
||||
|
||||
mDataLeft = 0;
|
||||
mPrevData = nsnull;
|
||||
mBuffer = nsnull;
|
||||
mBufferSize = 0;
|
||||
|
||||
mState = F_P;
|
||||
mSkip = NOTHING;
|
||||
mOldSkip = NOTHING;
|
||||
mType = 0;
|
||||
}
|
||||
|
||||
nsPPMDecoder::~nsPPMDecoder()
|
||||
{
|
||||
|
||||
if (mBuffer != nsnull)
|
||||
PR_Free(mBuffer);
|
||||
if (mRowData != nsnull)
|
||||
PR_Free(mRowData);
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,172 +147,244 @@ NS_IMETHODIMP nsPPMDecoder::Flush()
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static char *__itoa(int n)
|
||||
{
|
||||
char *s;
|
||||
int i, j, sign, tmp;
|
||||
|
||||
/* check sign and convert to positive to stringify numbers */
|
||||
if ( (sign = n) < 0)
|
||||
n = -n;
|
||||
i = 0;
|
||||
s = (char*) malloc(sizeof(char));
|
||||
|
||||
/* grow string as needed to add numbers from powers of 10
|
||||
* down till none left
|
||||
*/
|
||||
do
|
||||
{
|
||||
s = (char*) realloc(s, (i+1)*sizeof(char));
|
||||
s[i++] = n % 10 + '0'; /* '0' or 30 is where ASCII numbers start */
|
||||
s[i] = '\0';
|
||||
}
|
||||
while( (n /= 10) > 0);
|
||||
|
||||
/* tack on minus sign if we found earlier that this was negative */
|
||||
if (sign < 0)
|
||||
{
|
||||
s = (char*) realloc(s, (i+1)*sizeof(char));
|
||||
s[i++] = '-';
|
||||
}
|
||||
s[i] = '\0';
|
||||
|
||||
/* pop numbers (and sign) off of string to push back into right direction */
|
||||
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
|
||||
{
|
||||
tmp = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = tmp;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPPMDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
char *buf = (char *)PR_Malloc(count + mDataLeft);
|
||||
if (!buf)
|
||||
if (mBuffer == nsnull) {
|
||||
mBuffer = (char *)PR_Malloc(count);
|
||||
mBufferSize = count;
|
||||
} else if (mBuffer != nsnull && mBufferSize != count) {
|
||||
PR_Free(mBuffer);
|
||||
mBuffer = (char *)PR_Malloc(count);
|
||||
mBufferSize = count;
|
||||
}
|
||||
if (!mBuffer)
|
||||
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
|
||||
// read the data from the input stram...
|
||||
// read the data from the input stream...
|
||||
PRUint32 readLen;
|
||||
rv = inStr->Read(buf+mDataLeft, count, &readLen);
|
||||
|
||||
PRUint32 dataLen = readLen + mDataLeft;
|
||||
|
||||
if (mPrevData) {
|
||||
strncpy(buf, mPrevData, mDataLeft);
|
||||
PR_Free(mPrevData);
|
||||
mPrevData = nsnull;
|
||||
mDataLeft = 0;
|
||||
}
|
||||
|
||||
char *data = buf;
|
||||
|
||||
rv = inStr->Read(mBuffer, count, &readLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mDataReceived == 0) {
|
||||
|
||||
if (mState == F_P && mObserver)
|
||||
mObserver->OnStartDecode(nsnull, nsnull);
|
||||
|
||||
// Check the magic number
|
||||
char type;
|
||||
if ((sscanf(data, "P%c\n", &type) !=1) || (type != '6')) {
|
||||
return NS_ERROR_FAILURE;
|
||||
char *p = mBuffer;
|
||||
char *bufferEnd = mBuffer+readLen;
|
||||
char *s;
|
||||
int n;
|
||||
|
||||
while (p < bufferEnd) {
|
||||
if (mSkip == WHITESPACE) {
|
||||
while (p < bufferEnd && *p != '#'
|
||||
&& (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'))
|
||||
p++;
|
||||
if (p == bufferEnd)
|
||||
break;
|
||||
if (*p == '#') {
|
||||
mOldSkip = WHITESPACE;
|
||||
mSkip = TOENDOFLINE;
|
||||
continue;
|
||||
}
|
||||
mSkip = NOTHING;
|
||||
} else if (mSkip == SINGLEWHITESPACE) {
|
||||
if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
|
||||
return NS_ERROR_FAILURE;
|
||||
p++;
|
||||
mSkip = NOTHING;
|
||||
} else if (mSkip == TOENDOFLINE) {
|
||||
while (p < bufferEnd && *p != '\n')
|
||||
p++;
|
||||
if (p == bufferEnd)
|
||||
break;
|
||||
mSkip = mOldSkip;
|
||||
mOldSkip = NOTHING;
|
||||
if (mSkip != NOTHING)
|
||||
continue;
|
||||
}
|
||||
int i = 3;
|
||||
data += i;
|
||||
|
||||
#if 0
|
||||
// XXX
|
||||
// Ignore comments
|
||||
while ((input = fgetc(f)) == '#')
|
||||
fgets(junk, 512, f);
|
||||
ungetc(input, f);
|
||||
#endif
|
||||
|
||||
// Read size
|
||||
int w, h, mcv;
|
||||
|
||||
if (sscanf(data, "%d %d\n%d\n", &w, &h, &mcv) != 3) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
char *ws = __itoa(w), *hs = __itoa(h), *mcvs = __itoa(mcv);
|
||||
int j = strlen(ws) + strlen(hs) + strlen(mcvs) + 3;
|
||||
data += j;
|
||||
// free(ws);
|
||||
// free(hs);
|
||||
// free(mcvs);
|
||||
|
||||
readLen -= i + j;
|
||||
dataLen = readLen; // since this is the first pass, we don't have any data waiting that we need to keep track of
|
||||
|
||||
mImage->Init(w, h, mObserver);
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, nsnull, mImage);
|
||||
|
||||
rv = mFrame->Init(0, 0, w, h, gfxIFormats::RGB);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
|
||||
}
|
||||
|
||||
PRUint32 bpr;
|
||||
nscoord width;
|
||||
mFrame->GetImageBytesPerRow(&bpr);
|
||||
mFrame->GetWidth(&width);
|
||||
|
||||
// XXX ceil?
|
||||
PRUint32 real_bpr = width * 3;
|
||||
|
||||
PRUint32 i = 0;
|
||||
PRUint32 rownum = mDataWritten / real_bpr; // XXX this better not have a decimal
|
||||
|
||||
PRUint32 wroteLen = 0;
|
||||
|
||||
if (readLen > real_bpr) {
|
||||
|
||||
do {
|
||||
PRUint8 *line = (PRUint8*)data + i*real_bpr;
|
||||
mFrame->SetImageData(line, real_bpr, (rownum++)*bpr);
|
||||
|
||||
nsRect r(0, rownum, width, 1);
|
||||
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
|
||||
|
||||
|
||||
wroteLen += real_bpr ;
|
||||
i++;
|
||||
} while(dataLen >= real_bpr * (i+1));
|
||||
|
||||
}
|
||||
|
||||
mDataReceived += readLen; // don't double count previous data that is in 'dataLen'
|
||||
mDataWritten += wroteLen;
|
||||
|
||||
PRUint32 dataLeft = dataLen - wroteLen;
|
||||
|
||||
if (dataLeft > 0) {
|
||||
if (mPrevData) {
|
||||
mPrevData = (char *)PR_Realloc(mPrevData, mDataLeft + dataLeft);
|
||||
strncpy(mPrevData + mDataLeft, data+wroteLen, dataLeft);
|
||||
mDataLeft += dataLeft;
|
||||
|
||||
} else {
|
||||
mDataLeft = dataLeft;
|
||||
mPrevData = (char *)PR_Malloc(mDataLeft);
|
||||
strncpy(mPrevData, data+wroteLen, mDataLeft);
|
||||
switch (mState) {
|
||||
case F_P:
|
||||
if (*p != 'P')
|
||||
return NS_ERROR_FAILURE;
|
||||
p++;
|
||||
mState = F_TYPE;
|
||||
break;
|
||||
case F_TYPE:
|
||||
if ((s = PL_strchr(ppmTypes, *p)) == NULL)
|
||||
return NS_ERROR_FAILURE;
|
||||
mType = s-ppmTypes;
|
||||
p++;
|
||||
mState = F_WIDTH;
|
||||
mDigitCount = 0;
|
||||
mSkip = WHITESPACE;
|
||||
break;
|
||||
case F_WIDTH:
|
||||
case F_HEIGHT:
|
||||
case F_MAXVAL:
|
||||
while (mDigitCount < sizeof(mDigits) && p < bufferEnd && isdigit(*p))
|
||||
mDigits[mDigitCount++] = *p++;
|
||||
if (mDigitCount == sizeof(mDigits))
|
||||
return NS_ERROR_FAILURE; // number too big
|
||||
if (p == bufferEnd)
|
||||
break;
|
||||
if (*p == '#') {
|
||||
mOldSkip = NOTHING;
|
||||
mSkip = TOENDOFLINE;
|
||||
break;
|
||||
}
|
||||
mDigits[mDigitCount] = 0;
|
||||
n = strtol(mDigits, (char **)NULL, 10);
|
||||
if (mState == F_WIDTH) {
|
||||
mWidth = n;
|
||||
mDigitCount = 0;
|
||||
mState = F_HEIGHT;
|
||||
mSkip = WHITESPACE;
|
||||
} else if (mState == F_HEIGHT) {
|
||||
mHeight = n;
|
||||
mDigitCount = 0;
|
||||
if ((mType & PPMTYPE) != TYPE_PBM) {
|
||||
mState = F_MAXVAL;
|
||||
mSkip = WHITESPACE;
|
||||
} else
|
||||
mState = F_INITIALIZE;
|
||||
} else if (mState == F_MAXVAL) {
|
||||
mMaxValue = n;
|
||||
mDigitCount = 0;
|
||||
mState = F_INITIALIZE;
|
||||
}
|
||||
break;
|
||||
case F_INITIALIZE:
|
||||
mImage->Init(mWidth, mHeight, mObserver);
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, nsnull, mImage);
|
||||
mFrame->Init(0, 0, mWidth, mHeight, gfxIFormats::RGB);
|
||||
mImage->AppendFrame(mFrame);
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
|
||||
mRow = 0;
|
||||
mBytesPerRow = 3*mWidth;
|
||||
mFrame->GetImageBytesPerRow(&mFrameBytesPerRow);
|
||||
mRowData = (PRUint8 *)PR_Malloc(mFrameBytesPerRow);
|
||||
mRowDataFill = 0;
|
||||
if (mType & PPMRAW) {
|
||||
mState = F_RAWDATA;
|
||||
mSkip = SINGLEWHITESPACE;
|
||||
} else if ((mType & PPMTYPE) == TYPE_PBM) {
|
||||
mState = F_TEXTBITDATA;
|
||||
mSkip = WHITESPACE;
|
||||
} else {
|
||||
mState = F_TEXTDATA;
|
||||
mSkip = WHITESPACE;
|
||||
mDigitCount = 0;
|
||||
}
|
||||
break;
|
||||
case F_TEXTBITDATA:
|
||||
{
|
||||
PRUint8 c = *p++;
|
||||
if (c == '1') {
|
||||
mRowData[mRowDataFill++] = 0;
|
||||
mRowData[mRowDataFill++] = 0;
|
||||
mRowData[mRowDataFill++] = 0;
|
||||
} else {
|
||||
mRowData[mRowDataFill++] = 255;
|
||||
mRowData[mRowDataFill++] = 255;
|
||||
mRowData[mRowDataFill++] = 255;
|
||||
}
|
||||
}
|
||||
mSkip = WHITESPACE;
|
||||
rv = checkSendRow();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
break;
|
||||
case F_TEXTDATA:
|
||||
while (mDigitCount < sizeof(mDigits) && p < bufferEnd && isdigit(*p))
|
||||
mDigits[mDigitCount++] = *p++;
|
||||
if (mDigitCount == sizeof(mDigits))
|
||||
return NS_ERROR_FAILURE; // number too big
|
||||
if (p == bufferEnd)
|
||||
break;
|
||||
mDigits[mDigitCount] = 0;
|
||||
n = strtol(mDigits, (char **)NULL, 10);
|
||||
mDigitCount = 0;
|
||||
switch (mType & PPMTYPE) {
|
||||
case 1:
|
||||
mRowData[mRowDataFill++] = n;
|
||||
mRowData[mRowDataFill++] = n;
|
||||
mRowData[mRowDataFill++] = n;
|
||||
break;
|
||||
case 2:
|
||||
mRowData[mRowDataFill++] = n;
|
||||
break;
|
||||
}
|
||||
mSkip = WHITESPACE;
|
||||
rv = checkSendRow();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
break;
|
||||
case F_RAWDATA:
|
||||
if (mType & PPMRAW) {
|
||||
switch (mType & PPMTYPE) {
|
||||
case TYPE_PBM:
|
||||
{
|
||||
PRUint32 c = *p++;
|
||||
int i = 0;
|
||||
while (mRowDataFill < mBytesPerRow && i < 8) {
|
||||
if (c & 0x80) {
|
||||
mRowData[mRowDataFill++] = 0;
|
||||
mRowData[mRowDataFill++] = 0;
|
||||
mRowData[mRowDataFill++] = 0;
|
||||
} else {
|
||||
mRowData[mRowDataFill++] = 255;
|
||||
mRowData[mRowDataFill++] = 255;
|
||||
mRowData[mRowDataFill++] = 255;
|
||||
}
|
||||
c <<= 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_PGM:
|
||||
{
|
||||
PRUint8 c = *p++;
|
||||
mRowData[mRowDataFill++] = c;
|
||||
mRowData[mRowDataFill++] = c;
|
||||
mRowData[mRowDataFill++] = c;
|
||||
}
|
||||
break;
|
||||
case TYPE_PPM:
|
||||
if (mMaxValue == 255) {
|
||||
PRUint32 bytesInBuffer = bufferEnd-p;
|
||||
PRUint32 bytesNeeded = mBytesPerRow-mRowDataFill;
|
||||
PRUint32 chunk = PR_MIN(bytesInBuffer, bytesNeeded);
|
||||
memcpy(mRowData+mRowDataFill, p, chunk);
|
||||
p += chunk;
|
||||
mRowDataFill += chunk;
|
||||
} else {
|
||||
mRowData[mRowDataFill++] = *p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
rv = checkSendRow();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PR_FREEIF(buf);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsPPMDecoder::checkSendRow()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mRowDataFill == mBytesPerRow) {
|
||||
rv = mFrame->SetImageData(mRowData, mFrameBytesPerRow, mRow*mFrameBytesPerRow);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsRect r(0, mRow, mWidth, 1);
|
||||
if (mObserver)
|
||||
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
|
||||
mRow++;
|
||||
mRowDataFill = 0;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsPPMDecoder_h__
|
||||
#define nsPPMDecoder_h__
|
||||
|
||||
#include "imgIDecoder.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgILoad.h"
|
||||
|
||||
#define NS_PPMDECODER_CID \
|
||||
{ /* e90bfa06-1dd1-11b2-8217-f38fe5d431a2 */ \
|
||||
0xe90bfa06, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0x82, 0x17, 0xf3, 0x8f, 0xe5, 0xd4, 0x31, 0xa2} \
|
||||
}
|
||||
|
||||
class nsPPMDecoder : public imgIDecoder
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIDECODER
|
||||
|
||||
nsPPMDecoder();
|
||||
virtual ~nsPPMDecoder();
|
||||
|
||||
private:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgILoad> mImageLoad;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
|
||||
PRUint32 mDataReceived;
|
||||
PRUint32 mDataWritten;
|
||||
|
||||
PRUint32 mDataLeft;
|
||||
char *mPrevData;
|
||||
};
|
||||
|
||||
#endif // nsPPMDecoder_h__
|
|
@ -1,42 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#include "nsPPMDecoder.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPPMDecoder)
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "ppm decoder",
|
||||
NS_PPMDECODER_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/x-portable-pixmap",
|
||||
nsPPMDecoderConstructor, },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(nsPPMDecoderModule, components)
|
||||
|
|
@ -622,6 +622,23 @@ nsresult imgLoader::GetMimeTypeFromContent(const char* aContents, PRUint32 aLeng
|
|||
else if (aLength >= 8 && !nsCRT::strncmp(aContents, "#define ", 8)) {
|
||||
*aContentType = nsCRT::strndup("image/x-xbitmap", 15);
|
||||
}
|
||||
/* PBM, PGM or PPM? */
|
||||
/* These start with the letter 'P' followed by a digit from 1 through 6
|
||||
* followed by a whitespace character.
|
||||
*/
|
||||
else if (aLength >= 3 && ((unsigned char)aContents[0]==0x50 &&
|
||||
((unsigned char)aContents[2]==0x9 || (unsigned char)aContents[2]==0xa ||
|
||||
(unsigned char)aContents[2]==0xd || (unsigned char)aContents[2]==0x20)))
|
||||
{
|
||||
unsigned char c = (unsigned char)aContents[1];
|
||||
if (c == '1' || c == '4') {
|
||||
*aContentType = nsCRT::strndup("image/x-portable-bitmap", 23);
|
||||
} else if (c == '2' || c == '5') {
|
||||
*aContentType = nsCRT::strndup("image/x-portable-graymap", 24);
|
||||
} else if (c == '3' || c == '6') {
|
||||
*aContentType = nsCRT::strndup("image/x-portable-pixmap", 23);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* none of the above? I give up */
|
||||
/* don't raise an exception, simply return null */
|
||||
|
|
Загрузка…
Ссылка в новой задаче