diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /image/encoders/ico | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'image/encoders/ico')
-rw-r--r-- | image/encoders/ico/moz.build | 20 | ||||
-rw-r--r-- | image/encoders/ico/nsICOEncoder.cpp | 499 | ||||
-rw-r--r-- | image/encoders/ico/nsICOEncoder.h | 95 |
3 files changed, 614 insertions, 0 deletions
diff --git a/image/encoders/ico/moz.build b/image/encoders/ico/moz.build new file mode 100644 index 0000000000..27e41489fd --- /dev/null +++ b/image/encoders/ico/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +SOURCES += [ + "nsICOEncoder.cpp", +] + +# Decoders need RasterImage.h +LOCAL_INCLUDES += [ + "/image", + "/image/encoders/bmp", + "/image/encoders/png", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" diff --git a/image/encoders/ico/nsICOEncoder.cpp b/image/encoders/ico/nsICOEncoder.cpp new file mode 100644 index 0000000000..518acc9a0b --- /dev/null +++ b/image/encoders/ico/nsICOEncoder.cpp @@ -0,0 +1,499 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCRT.h" +#include "mozilla/EndianUtils.h" +#include "nsBMPEncoder.h" +#include "BMPHeaders.h" +#include "nsPNGEncoder.h" +#include "nsICOEncoder.h" +#include "nsString.h" +#include "nsStreamUtils.h" +#include "nsTArray.h" + +using namespace mozilla; +using namespace mozilla::image; + +NS_IMPL_ISUPPORTS(nsICOEncoder, imgIEncoder, nsIInputStream, + nsIAsyncInputStream) + +nsICOEncoder::nsICOEncoder() + : mICOFileHeader{}, + mICODirEntry{}, + mImageBufferStart(nullptr), + mImageBufferCurr(0), + mImageBufferSize(0), + mImageBufferReadPoint(0), + mFinished(false), + mUsePNG(true), + mNotifyThreshold(0) {} + +nsICOEncoder::~nsICOEncoder() { + if (mImageBufferStart) { + free(mImageBufferStart); + mImageBufferStart = nullptr; + mImageBufferCurr = nullptr; + } +} + +// nsICOEncoder::InitFromData +// Two output options are supported: format=<png|bmp>;bpp=<bpp_value> +// format specifies whether to use png or bitmap format +// bpp specifies the bits per pixel to use where bpp_value can be 24 or 32 +NS_IMETHODIMP +nsICOEncoder::InitFromData(const uint8_t* aData, uint32_t aLength, + uint32_t aWidth, uint32_t aHeight, uint32_t aStride, + uint32_t aInputFormat, + const nsAString& aOutputOptions) { + // validate input format + if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA && + aInputFormat != INPUT_FORMAT_HOSTARGB) { + 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) || + ((aInputFormat == INPUT_FORMAT_RGBA || + aInputFormat == INPUT_FORMAT_HOSTARGB) && + aStride < aWidth * 4)) { + NS_WARNING("Invalid stride for InitFromData"); + return NS_ERROR_INVALID_ARG; + } + + nsresult rv; + rv = StartImageEncode(aWidth, aHeight, aInputFormat, aOutputOptions); + NS_ENSURE_SUCCESS(rv, rv); + + rv = AddImageFrame(aData, aLength, aWidth, aHeight, aStride, aInputFormat, + aOutputOptions); + NS_ENSURE_SUCCESS(rv, rv); + + rv = EndImageEncode(); + return rv; +} + +// Returns the number of bytes in the image buffer used +// For an ICO file, this is all bytes in the buffer. +NS_IMETHODIMP +nsICOEncoder::GetImageBufferUsed(uint32_t* aOutputSize) { + NS_ENSURE_ARG_POINTER(aOutputSize); + *aOutputSize = mImageBufferSize; + return NS_OK; +} + +// Returns a pointer to the start of the image buffer +NS_IMETHODIMP +nsICOEncoder::GetImageBuffer(char** aOutputBuffer) { + NS_ENSURE_ARG_POINTER(aOutputBuffer); + *aOutputBuffer = reinterpret_cast<char*>(mImageBufferStart); + return NS_OK; +} + +NS_IMETHODIMP +nsICOEncoder::AddImageFrame(const uint8_t* aData, uint32_t aLength, + uint32_t aWidth, uint32_t aHeight, uint32_t aStride, + uint32_t aInputFormat, + const nsAString& aFrameOptions) { + if (mUsePNG) { + mContainedEncoder = new nsPNGEncoder(); + nsresult rv; + nsAutoString noParams; + rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight, + aStride, aInputFormat, noParams); + NS_ENSURE_SUCCESS(rv, rv); + + uint32_t PNGImageBufferSize; + mContainedEncoder->GetImageBufferUsed(&PNGImageBufferSize); + mImageBufferSize = + ICONFILEHEADERSIZE + ICODIRENTRYSIZE + PNGImageBufferSize; + mImageBufferStart = static_cast<uint8_t*>(malloc(mImageBufferSize)); + if (!mImageBufferStart) { + return NS_ERROR_OUT_OF_MEMORY; + } + mImageBufferCurr = mImageBufferStart; + mICODirEntry.mBytesInRes = PNGImageBufferSize; + + EncodeFileHeader(); + EncodeInfoHeader(); + + char* imageBuffer; + rv = mContainedEncoder->GetImageBuffer(&imageBuffer); + NS_ENSURE_SUCCESS(rv, rv); + memcpy(mImageBufferCurr, imageBuffer, PNGImageBufferSize); + mImageBufferCurr += PNGImageBufferSize; + } else { + mContainedEncoder = new nsBMPEncoder(); + nsresult rv; + + nsAutoString params; + params.AppendLiteral("bpp="); + params.AppendInt(mICODirEntry.mBitCount); + + rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight, + aStride, aInputFormat, params); + NS_ENSURE_SUCCESS(rv, rv); + + uint32_t andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask + GetRealHeight(); // num rows + + uint32_t BMPImageBufferSize; + mContainedEncoder->GetImageBufferUsed(&BMPImageBufferSize); + mImageBufferSize = + ICONFILEHEADERSIZE + ICODIRENTRYSIZE + BMPImageBufferSize + andMaskSize; + mImageBufferStart = static_cast<uint8_t*>(malloc(mImageBufferSize)); + if (!mImageBufferStart) { + return NS_ERROR_OUT_OF_MEMORY; + } + mImageBufferCurr = mImageBufferStart; + + // Icon files that wrap a BMP file must not include the BITMAPFILEHEADER + // section at the beginning of the encoded BMP data, so we must skip over + // bmp::FILE_HEADER_LENGTH bytes when adding the BMP content to the icon + // file. + mICODirEntry.mBytesInRes = + BMPImageBufferSize - bmp::FILE_HEADER_LENGTH + andMaskSize; + + // Encode the icon headers + EncodeFileHeader(); + EncodeInfoHeader(); + + char* imageBuffer; + rv = mContainedEncoder->GetImageBuffer(&imageBuffer); + NS_ENSURE_SUCCESS(rv, rv); + memcpy(mImageBufferCurr, imageBuffer + bmp::FILE_HEADER_LENGTH, + BMPImageBufferSize - bmp::FILE_HEADER_LENGTH); + // We need to fix the BMP height to be *2 for the AND mask + uint32_t fixedHeight = GetRealHeight() * 2; + NativeEndian::swapToLittleEndianInPlace(&fixedHeight, 1); + // The height is stored at an offset of 8 from the DIB header + memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight)); + mImageBufferCurr += BMPImageBufferSize - bmp::FILE_HEADER_LENGTH; + + // Calculate rowsize in DWORD's + uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up + int32_t currentLine = GetRealHeight(); + + // Write out the AND mask + while (currentLine > 0) { + currentLine--; + uint8_t* encoded = mImageBufferCurr + currentLine * rowSize; + uint8_t* encodedEnd = encoded + rowSize; + while (encoded != encodedEnd) { + *encoded = 0; // make everything visible + encoded++; + } + } + + mImageBufferCurr += andMaskSize; + } + + return NS_OK; +} + +// See ::InitFromData for other info. +NS_IMETHODIMP +nsICOEncoder::StartImageEncode(uint32_t aWidth, uint32_t aHeight, + uint32_t aInputFormat, + const nsAString& aOutputOptions) { + // can't initialize more than once + if (mImageBufferStart || mImageBufferCurr) { + return NS_ERROR_ALREADY_INITIALIZED; + } + + // validate input format + if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA && + aInputFormat != INPUT_FORMAT_HOSTARGB) { + return NS_ERROR_INVALID_ARG; + } + + // Icons are only 1 byte, so make sure our bitmap is in range + if (aWidth > 256 || aHeight > 256) { + return NS_ERROR_INVALID_ARG; + } + + // parse and check any provided output options + uint16_t bpp = 24; + bool usePNG = true; + nsresult rv = ParseOptions(aOutputOptions, bpp, usePNG); + NS_ENSURE_SUCCESS(rv, rv); + MOZ_ASSERT(bpp <= 32); + + mUsePNG = usePNG; + + InitFileHeader(); + // The width and height are stored as 0 when we have a value of 256 + InitInfoHeader(bpp, aWidth == 256 ? 0 : (uint8_t)aWidth, + aHeight == 256 ? 0 : (uint8_t)aHeight); + + return NS_OK; +} + +NS_IMETHODIMP +nsICOEncoder::EndImageEncode() { + // must be initialized + if (!mImageBufferStart || !mImageBufferCurr) { + return NS_ERROR_NOT_INITIALIZED; + } + + mFinished = true; + NotifyListener(); + + // if output callback can't get enough memory, it will free our buffer + if (!mImageBufferStart || !mImageBufferCurr) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; +} + +// 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, bool& aUsePNGOut) { + // If no parsing options just use the default of 24BPP and PNG yes + if (aOptions.Length() == 0) { + aUsePNGOut = true; + aBppOut = 24; + } + + // Parse the input string into a set of name/value pairs. + // From format: format=<png|bmp>;bpp=<bpp_value> + // to format: [0] = format=<png|bmp>, [1] = bpp=<bpp_value> + nsTArray<nsCString> nameValuePairs; + ParseString(NS_ConvertUTF16toUTF8(aOptions), ';', nameValuePairs); + + // For each name/value pair in the set + for (unsigned i = 0; i < nameValuePairs.Length(); ++i) { + // Split the name value pair [0] = name, [1] = value + nsTArray<nsCString> nameValuePair; + ParseString(nameValuePairs[i], '=', nameValuePair); + if (nameValuePair.Length() != 2) { + return NS_ERROR_INVALID_ARG; + } + + // Parse the format portion of the string format=<png|bmp>;bpp=<bpp_value> + if (nameValuePair[0].Equals("format", nsCaseInsensitiveCStringComparator)) { + if (nameValuePair[1].Equals("png", nsCaseInsensitiveCStringComparator)) { + aUsePNGOut = true; + } else if (nameValuePair[1].Equals("bmp", + nsCaseInsensitiveCStringComparator)) { + aUsePNGOut = false; + } else { + return NS_ERROR_INVALID_ARG; + } + } + + // Parse the bpp portion of the string format=<png|bmp>;bpp=<bpp_value> + if (nameValuePair[0].Equals("bpp", nsCaseInsensitiveCStringComparator)) { + if (nameValuePair[1].EqualsLiteral("24")) { + aBppOut = 24; + } else if (nameValuePair[1].EqualsLiteral("32")) { + aBppOut = 32; + } else { + return NS_ERROR_INVALID_ARG; + } + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsICOEncoder::Close() { + if (mImageBufferStart) { + free(mImageBufferStart); + mImageBufferStart = nullptr; + mImageBufferSize = 0; + mImageBufferReadPoint = 0; + mImageBufferCurr = nullptr; + } + + return NS_OK; +} + +// Obtains the available bytes to read +NS_IMETHODIMP +nsICOEncoder::Available(uint64_t* _retval) { + if (!mImageBufferStart || !mImageBufferCurr) { + return NS_BASE_STREAM_CLOSED; + } + + *_retval = GetCurrentImageBufferOffset() - mImageBufferReadPoint; + return NS_OK; +} + +// Obtains the stream's status +NS_IMETHODIMP +nsICOEncoder::StreamStatus() { + return mImageBufferStart && mImageBufferCurr ? NS_OK : NS_BASE_STREAM_CLOSED; +} + +// [noscript] Reads bytes which are available +NS_IMETHODIMP +nsICOEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval) { + return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval); +} + +// [noscript] Reads segments +NS_IMETHODIMP +nsICOEncoder::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, + uint32_t aCount, uint32_t* _retval) { + uint32_t maxCount = GetCurrentImageBufferOffset() - mImageBufferReadPoint; + if (maxCount == 0) { + *_retval = 0; + return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK; + } + + if (aCount > maxCount) { + aCount = maxCount; + } + + nsresult rv = aWriter( + this, aClosure, + reinterpret_cast<const char*>(mImageBufferStart + mImageBufferReadPoint), + 0, aCount, _retval); + if (NS_SUCCEEDED(rv)) { + NS_ASSERTION(*_retval <= aCount, "bad write count"); + mImageBufferReadPoint += *_retval; + } + // errors returned from the writer end here! + return NS_OK; +} + +NS_IMETHODIMP +nsICOEncoder::IsNonBlocking(bool* _retval) { + *_retval = true; + return NS_OK; +} + +NS_IMETHODIMP +nsICOEncoder::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags, + uint32_t aRequestedCount, nsIEventTarget* aTarget) { + if (aFlags != 0) { + return NS_ERROR_NOT_IMPLEMENTED; + } + + if (mCallback || mCallbackTarget) { + return NS_ERROR_UNEXPECTED; + } + + mCallbackTarget = aTarget; + // 0 means "any number of bytes except 0" + mNotifyThreshold = aRequestedCount; + if (!aRequestedCount) { + mNotifyThreshold = 1024; // We don't want to notify incessantly + } + + // We set the callback absolutely last, because NotifyListener uses it to + // determine if someone needs to be notified. If we don't set it last, + // NotifyListener might try to fire off a notification to a null target + // which will generally cause non-threadsafe objects to be used off the + // main thread + mCallback = aCallback; + + // What we are being asked for may be present already + NotifyListener(); + return NS_OK; +} + +NS_IMETHODIMP +nsICOEncoder::CloseWithStatus(nsresult aStatus) { return Close(); } + +void nsICOEncoder::NotifyListener() { + if (mCallback && (GetCurrentImageBufferOffset() - mImageBufferReadPoint >= + mNotifyThreshold || + mFinished)) { + nsCOMPtr<nsIInputStreamCallback> callback; + if (mCallbackTarget) { + callback = NS_NewInputStreamReadyEvent("nsICOEncoder::NotifyListener", + mCallback, mCallbackTarget); + } else { + callback = mCallback; + } + + NS_ASSERTION(callback, "Shouldn't fail to make the callback"); + // Null the callback first because OnInputStreamReady could reenter + // AsyncWait + mCallback = nullptr; + mCallbackTarget = nullptr; + mNotifyThreshold = 0; + + callback->OnInputStreamReady(this); + } +} + +// Initializes the icon file header mICOFileHeader +void nsICOEncoder::InitFileHeader() { + memset(&mICOFileHeader, 0, sizeof(mICOFileHeader)); + mICOFileHeader.mReserved = 0; + mICOFileHeader.mType = 1; + mICOFileHeader.mCount = 1; +} + +// Initializes the icon directory info header mICODirEntry +void nsICOEncoder::InitInfoHeader(uint16_t aBPP, uint8_t aWidth, + uint8_t aHeight) { + memset(&mICODirEntry, 0, sizeof(mICODirEntry)); + mICODirEntry.mBitCount = aBPP; + mICODirEntry.mBytesInRes = 0; + mICODirEntry.mColorCount = 0; + mICODirEntry.mWidth = aWidth; + mICODirEntry.mHeight = aHeight; + mICODirEntry.mImageOffset = ICONFILEHEADERSIZE + ICODIRENTRYSIZE; + mICODirEntry.mPlanes = 1; + mICODirEntry.mReserved = 0; +} + +// Encodes the icon file header mICOFileHeader +void nsICOEncoder::EncodeFileHeader() { + IconFileHeader littleEndianIFH = mICOFileHeader; + NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mReserved, 1); + NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mType, 1); + NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mCount, 1); + + memcpy(mImageBufferCurr, &littleEndianIFH.mReserved, + sizeof(littleEndianIFH.mReserved)); + mImageBufferCurr += sizeof(littleEndianIFH.mReserved); + memcpy(mImageBufferCurr, &littleEndianIFH.mType, + sizeof(littleEndianIFH.mType)); + mImageBufferCurr += sizeof(littleEndianIFH.mType); + memcpy(mImageBufferCurr, &littleEndianIFH.mCount, + sizeof(littleEndianIFH.mCount)); + mImageBufferCurr += sizeof(littleEndianIFH.mCount); +} + +// Encodes the icon directory info header mICODirEntry +void nsICOEncoder::EncodeInfoHeader() { + IconDirEntry littleEndianmIDE = mICODirEntry; + + NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mPlanes, 1); + NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mBitCount, 1); + NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mBytesInRes, 1); + NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mImageOffset, 1); + + memcpy(mImageBufferCurr, &littleEndianmIDE.mWidth, + sizeof(littleEndianmIDE.mWidth)); + mImageBufferCurr += sizeof(littleEndianmIDE.mWidth); + memcpy(mImageBufferCurr, &littleEndianmIDE.mHeight, + sizeof(littleEndianmIDE.mHeight)); + mImageBufferCurr += sizeof(littleEndianmIDE.mHeight); + memcpy(mImageBufferCurr, &littleEndianmIDE.mColorCount, + sizeof(littleEndianmIDE.mColorCount)); + mImageBufferCurr += sizeof(littleEndianmIDE.mColorCount); + memcpy(mImageBufferCurr, &littleEndianmIDE.mReserved, + sizeof(littleEndianmIDE.mReserved)); + mImageBufferCurr += sizeof(littleEndianmIDE.mReserved); + memcpy(mImageBufferCurr, &littleEndianmIDE.mPlanes, + sizeof(littleEndianmIDE.mPlanes)); + mImageBufferCurr += sizeof(littleEndianmIDE.mPlanes); + memcpy(mImageBufferCurr, &littleEndianmIDE.mBitCount, + sizeof(littleEndianmIDE.mBitCount)); + mImageBufferCurr += sizeof(littleEndianmIDE.mBitCount); + memcpy(mImageBufferCurr, &littleEndianmIDE.mBytesInRes, + sizeof(littleEndianmIDE.mBytesInRes)); + mImageBufferCurr += sizeof(littleEndianmIDE.mBytesInRes); + memcpy(mImageBufferCurr, &littleEndianmIDE.mImageOffset, + sizeof(littleEndianmIDE.mImageOffset)); + mImageBufferCurr += sizeof(littleEndianmIDE.mImageOffset); +} diff --git a/image/encoders/ico/nsICOEncoder.h b/image/encoders/ico/nsICOEncoder.h new file mode 100644 index 0000000000..ef601ba97e --- /dev/null +++ b/image/encoders/ico/nsICOEncoder.h @@ -0,0 +1,95 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_image_encoders_ico_nsICOEncoder_h +#define mozilla_image_encoders_ico_nsICOEncoder_h + +#include "mozilla/Attributes.h" +#include "mozilla/ReentrantMonitor.h" +#include "mozilla/image/ICOFileHeaders.h" + +#include "imgIEncoder.h" + +#include "nsCOMPtr.h" + +#define NS_ICOENCODER_CID \ + { /*92AE3AB2-8968-41B1-8709-B6123BCEAF21 */ \ + 0x92ae3ab2, 0x8968, 0x41b1, { \ + 0x87, 0x09, 0xb6, 0x12, 0x3b, 0Xce, 0xaf, 0x21 \ + } \ + } + +// Provides ICO encoding functionality. Use InitFromData() to do the +// encoding. See that function definition for encoding options. + +class nsICOEncoder final : public imgIEncoder { + typedef mozilla::ReentrantMonitor ReentrantMonitor; + + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_IMGIENCODER + NS_DECL_NSIINPUTSTREAM + NS_DECL_NSIASYNCINPUTSTREAM + + nsICOEncoder(); + + // Obtains the width of the icon directory entry + uint32_t GetRealWidth() const { + return mICODirEntry.mWidth == 0 ? 256 : mICODirEntry.mWidth; + } + + // Obtains the height of the icon directory entry + uint32_t GetRealHeight() const { + return mICODirEntry.mHeight == 0 ? 256 : mICODirEntry.mHeight; + } + + protected: + ~nsICOEncoder(); + + nsresult ParseOptions(const nsAString& aOptions, uint16_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); + // Encodes the icon file header mICOFileHeader + void EncodeFileHeader(); + // Encodes the icon directory info header mICODirEntry + void EncodeInfoHeader(); + // Obtains the current offset filled up to for the image buffer + inline int32_t GetCurrentImageBufferOffset() { + return static_cast<int32_t>(mImageBufferCurr - mImageBufferStart); + } + + // Holds either a PNG or a BMP depending on the encoding options specified + // or if no encoding options specified will use the default (PNG) + nsCOMPtr<imgIEncoder> mContainedEncoder; + + // These headers will always contain endian independent stuff. + // Don't trust the width and height of mICODirEntry directly, + // instead use the accessors GetRealWidth() and GetRealHeight(). + mozilla::image::IconFileHeader mICOFileHeader; + mozilla::image::IconDirEntry mICODirEntry; + + // Keeps track of the start of the image buffer + uint8_t* mImageBufferStart; + // Keeps track of the current position in the image buffer + uint8_t* mImageBufferCurr; + // Keeps track of the image buffer size + uint32_t mImageBufferSize; + // Keeps track of the number of bytes in the image buffer which are read + uint32_t mImageBufferReadPoint; + // Stores true if the image is done being encoded + bool mFinished; + // Stores true if the contained image is a PNG + bool mUsePNG; + + nsCOMPtr<nsIInputStreamCallback> mCallback; + nsCOMPtr<nsIEventTarget> mCallbackTarget; + uint32_t mNotifyThreshold; +}; + +#endif // mozilla_image_encoders_ico_nsICOEncoder_h |