mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Backed out changeset ada34cba0052 (bug 1348941) for image-related bustages
CLOSED TREE
This commit is contained in:
parent
4cb08c4110
commit
57f1484fe3
@ -10,7 +10,6 @@
|
||||
#include "nsString.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::image;
|
||||
@ -59,11 +58,6 @@ nsBMPEncoder::InitFromData(const uint8_t* aData,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
CheckedInt32 check = CheckedInt32(aWidth) * 4;
|
||||
if (MOZ_UNLIKELY(!check.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Stride is the padded width of each row, so it better be longer
|
||||
if ((aInputFormat == INPUT_FORMAT_RGB &&
|
||||
aStride < aWidth * 3) ||
|
||||
@ -92,19 +86,19 @@ nsBMPEncoder::InitFromData(const uint8_t* aData,
|
||||
|
||||
// Just a helper method to make it explicit in calculations that we are dealing
|
||||
// with bytes and not bits
|
||||
static inline uint16_t
|
||||
BytesPerPixel(uint16_t aBPP)
|
||||
static inline uint32_t
|
||||
BytesPerPixel(uint32_t aBPP)
|
||||
{
|
||||
return aBPP / 8;
|
||||
}
|
||||
|
||||
// Calculates the number of padding bytes that are needed per row of image data
|
||||
static inline uint32_t
|
||||
PaddingBytes(uint16_t aBPP, uint32_t aWidth)
|
||||
PaddingBytes(uint32_t aBPP, uint32_t aWidth)
|
||||
{
|
||||
uint32_t rowSize = aWidth * BytesPerPixel(aBPP);
|
||||
uint8_t paddingSize = 0;
|
||||
if (rowSize % 4) {
|
||||
if(rowSize % 4) {
|
||||
paddingSize = (4 - (rowSize % 4));
|
||||
}
|
||||
return paddingSize;
|
||||
@ -131,21 +125,14 @@ nsBMPEncoder::StartImageEncode(uint32_t aWidth,
|
||||
|
||||
// parse and check any provided output options
|
||||
Version version;
|
||||
uint16_t bpp;
|
||||
uint32_t bpp;
|
||||
nsresult rv = ParseOptions(aOutputOptions, version, bpp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(bpp <= 32);
|
||||
|
||||
rv = InitFileHeader(version, bpp, aWidth, aHeight);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = InitInfoHeader(version, bpp, aWidth, aHeight);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
InitFileHeader(version, bpp, aWidth, aHeight);
|
||||
InitInfoHeader(version, bpp, aWidth, aHeight);
|
||||
|
||||
mImageBufferSize = mBMPFileHeader.filesize;
|
||||
mImageBufferStart = static_cast<uint8_t*>(malloc(mImageBufferSize));
|
||||
@ -200,26 +187,12 @@ nsBMPEncoder::AddImageFrame(const uint8_t* aData,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (mBMPInfoHeader.width < 0) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
CheckedUint32 size =
|
||||
CheckedUint32(mBMPInfoHeader.width) * CheckedUint32(BytesPerPixel(mBMPInfoHeader.bpp));
|
||||
if (MOZ_UNLIKELY(!size.isValid())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
auto row = MakeUniqueFallible<uint8_t[]>(size.value());
|
||||
auto row = MakeUniqueFallible<uint8_t[]>(mBMPInfoHeader.width *
|
||||
BytesPerPixel(mBMPInfoHeader.bpp));
|
||||
if (!row) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
CheckedUint32 check = CheckedUint32(mBMPInfoHeader.height) * aStride;
|
||||
if (MOZ_UNLIKELY(!check.isValid())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// write each row: if we add more input formats, we may want to
|
||||
// generalize the conversions
|
||||
if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
|
||||
@ -283,7 +256,7 @@ nsBMPEncoder::EndImageEncode()
|
||||
// See InitFromData for a description of the parse options
|
||||
nsresult
|
||||
nsBMPEncoder::ParseOptions(const nsAString& aOptions, Version& aVersionOut,
|
||||
uint16_t& aBppOut)
|
||||
uint32_t& aBppOut)
|
||||
{
|
||||
aVersionOut = VERSION_3;
|
||||
aBppOut = 24;
|
||||
@ -451,7 +424,7 @@ nsBMPEncoder::ConvertHostARGBRow(const uint8_t* aSrc,
|
||||
const UniquePtr<uint8_t[]>& aDest,
|
||||
uint32_t aPixelWidth)
|
||||
{
|
||||
uint16_t bytes = BytesPerPixel(mBMPInfoHeader.bpp);
|
||||
int bytes = BytesPerPixel(mBMPInfoHeader.bpp);
|
||||
|
||||
if (mBMPInfoHeader.bpp == 32) {
|
||||
for (uint32_t x = 0; x < aPixelWidth; x++) {
|
||||
@ -500,8 +473,8 @@ nsBMPEncoder::NotifyListener()
|
||||
}
|
||||
|
||||
// Initializes the BMP file header mBMPFileHeader to the passed in values
|
||||
nsresult
|
||||
nsBMPEncoder::InitFileHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
void
|
||||
nsBMPEncoder::InitFileHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
|
||||
uint32_t aHeight)
|
||||
{
|
||||
memset(&mBMPFileHeader, 0, sizeof(mBMPFileHeader));
|
||||
@ -518,25 +491,13 @@ nsBMPEncoder::InitFileHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
if (aBPP <= 8) {
|
||||
uint32_t numColors = 1 << aBPP;
|
||||
mBMPFileHeader.dataoffset += 4 * numColors;
|
||||
CheckedUint32 filesize =
|
||||
CheckedUint32(mBMPFileHeader.dataoffset) + CheckedUint32(aWidth) * aHeight;
|
||||
if (MOZ_UNLIKELY(!filesize.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mBMPFileHeader.filesize = filesize.value();
|
||||
mBMPFileHeader.filesize = mBMPFileHeader.dataoffset + aWidth * aHeight;
|
||||
} else {
|
||||
CheckedUint32 filesize =
|
||||
CheckedUint32(mBMPFileHeader.dataoffset) +
|
||||
(CheckedUint32(aWidth) * BytesPerPixel(aBPP) + PaddingBytes(aBPP, aWidth)) * aHeight;
|
||||
if (MOZ_UNLIKELY(!filesize.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mBMPFileHeader.filesize = filesize.value();
|
||||
mBMPFileHeader.filesize = mBMPFileHeader.dataoffset +
|
||||
(aWidth * BytesPerPixel(aBPP) + PaddingBytes(aBPP, aWidth)) * aHeight;
|
||||
}
|
||||
|
||||
mBMPFileHeader.reserved = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define ENCODE(pImageBufferCurr, value) \
|
||||
@ -544,8 +505,8 @@ nsBMPEncoder::InitFileHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
*pImageBufferCurr += sizeof value;
|
||||
|
||||
// Initializes the bitmap info header mBMPInfoHeader to the passed in values
|
||||
nsresult
|
||||
nsBMPEncoder::InitInfoHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
void
|
||||
nsBMPEncoder::InitInfoHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
|
||||
uint32_t aHeight)
|
||||
{
|
||||
memset(&mBMPInfoHeader, 0, sizeof(mBMPInfoHeader));
|
||||
@ -555,39 +516,18 @@ nsBMPEncoder::InitInfoHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
MOZ_ASSERT(aVersion == VERSION_5);
|
||||
mBMPInfoHeader.bihsize = InfoHeaderLength::WIN_V5;
|
||||
}
|
||||
|
||||
CheckedInt32 width(aWidth);
|
||||
CheckedInt32 height(aHeight);
|
||||
if (MOZ_UNLIKELY(!width.isValid() || !height.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mBMPInfoHeader.width = width.value();
|
||||
mBMPInfoHeader.height = height.value();
|
||||
|
||||
mBMPInfoHeader.width = aWidth;
|
||||
mBMPInfoHeader.height = aHeight;
|
||||
mBMPInfoHeader.planes = 1;
|
||||
mBMPInfoHeader.bpp = aBPP;
|
||||
mBMPInfoHeader.compression = 0;
|
||||
mBMPInfoHeader.colors = 0;
|
||||
mBMPInfoHeader.important_colors = 0;
|
||||
|
||||
CheckedUint32 check = CheckedUint32(aWidth) * BytesPerPixel(aBPP);
|
||||
if (MOZ_UNLIKELY(check.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (aBPP <= 8) {
|
||||
CheckedUint32 imagesize = CheckedUint32(aWidth) * aHeight;
|
||||
if (MOZ_UNLIKELY(imagesize.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mBMPInfoHeader.image_size = imagesize.value();
|
||||
mBMPInfoHeader.image_size = aWidth * aHeight;
|
||||
} else {
|
||||
CheckedUint32 imagesize =
|
||||
CheckedUint32(aWidth) * BytesPerPixel(aBPP) + PaddingBytes(aBPP, aWidth) * CheckedUint32(aHeight);
|
||||
if (MOZ_UNLIKELY(imagesize.isValid())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
mBMPInfoHeader.image_size = imagesize.value();
|
||||
mBMPInfoHeader.image_size =
|
||||
(aWidth * BytesPerPixel(aBPP) + PaddingBytes(aBPP, aWidth)) * aHeight;
|
||||
}
|
||||
mBMPInfoHeader.xppm = 0;
|
||||
mBMPInfoHeader.yppm = 0;
|
||||
@ -614,8 +554,6 @@ nsBMPEncoder::InitInfoHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
mBMPInfoHeader.profile_size = 0;
|
||||
mBMPInfoHeader.reserved = 0;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Encodes the BMP file header mBMPFileHeader
|
||||
|
@ -104,7 +104,7 @@ protected:
|
||||
|
||||
// See InitData in the cpp for valid parse options
|
||||
nsresult ParseOptions(const nsAString& aOptions, Version& aVersionOut,
|
||||
uint16_t& aBppOut);
|
||||
uint32_t& aBppOut);
|
||||
// Obtains data with no alpha in machine-independent byte order
|
||||
void ConvertHostARGBRow(const uint8_t* aSrc,
|
||||
const mozilla::UniquePtr<uint8_t[]>& aDest,
|
||||
@ -113,11 +113,11 @@ protected:
|
||||
void NotifyListener();
|
||||
|
||||
// Initializes the bitmap file header member mBMPFileHeader
|
||||
nsresult InitFileHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
uint32_t aHeight);
|
||||
void InitFileHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
|
||||
uint32_t aHeight);
|
||||
// Initializes the bitmap info header member mBMPInfoHeader
|
||||
nsresult InitInfoHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
|
||||
uint32_t aHeight);
|
||||
void InitInfoHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
|
||||
uint32_t aHeight);
|
||||
|
||||
// Encodes the bitmap file header member mBMPFileHeader
|
||||
void EncodeFileHeader();
|
||||
|
@ -228,11 +228,10 @@ nsICOEncoder::StartImageEncode(uint32_t aWidth,
|
||||
}
|
||||
|
||||
// parse and check any provided output options
|
||||
uint16_t bpp = 24;
|
||||
uint32_t bpp = 24;
|
||||
bool usePNG = true;
|
||||
nsresult rv = ParseOptions(aOutputOptions, bpp, usePNG);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ASSERT(bpp <= 32);
|
||||
|
||||
mUsePNG = usePNG;
|
||||
|
||||
@ -266,7 +265,7 @@ nsICOEncoder::EndImageEncode()
|
||||
// Parses the encoder options and sets the bits per pixel to use and PNG or BMP
|
||||
// See InitFromData for a description of the parse options
|
||||
nsresult
|
||||
nsICOEncoder::ParseOptions(const nsAString& aOptions, uint16_t& aBppOut,
|
||||
nsICOEncoder::ParseOptions(const nsAString& aOptions, uint32_t& aBppOut,
|
||||
bool& aUsePNGOut)
|
||||
{
|
||||
// If no parsing options just use the default of 24BPP and PNG yes
|
||||
@ -470,7 +469,7 @@ nsICOEncoder::InitFileHeader()
|
||||
|
||||
// Initializes the icon directory info header mICODirEntry
|
||||
void
|
||||
nsICOEncoder::InitInfoHeader(uint16_t aBPP, uint8_t aWidth, uint8_t aHeight)
|
||||
nsICOEncoder::InitInfoHeader(uint32_t aBPP, uint8_t aWidth, uint8_t aHeight)
|
||||
{
|
||||
memset(&mICODirEntry, 0, sizeof(mICODirEntry));
|
||||
mICODirEntry.mBitCount = aBPP;
|
||||
|
@ -50,14 +50,14 @@ public:
|
||||
protected:
|
||||
~nsICOEncoder();
|
||||
|
||||
nsresult ParseOptions(const nsAString& aOptions, uint16_t& aBppOut,
|
||||
nsresult ParseOptions(const nsAString& aOptions, uint32_t& aBppOut,
|
||||
bool& aUsePNGOut);
|
||||
void NotifyListener();
|
||||
|
||||
// Initializes the icon file header mICOFileHeader
|
||||
void InitFileHeader();
|
||||
// Initializes the icon directory info header mICODirEntry
|
||||
void InitInfoHeader(uint16_t aBPP, uint8_t aWidth, uint8_t aHeight);
|
||||
void InitInfoHeader(uint32_t aBPP, uint8_t aWidth, uint8_t aHeight);
|
||||
// Encodes the icon file header mICOFileHeader
|
||||
void EncodeFileHeader();
|
||||
// Encodes the icon directory info header mICODirEntry
|
||||
|
Loading…
Reference in New Issue
Block a user