Backed out changeset 388ac5609ceb (bug 1615394) for MinGW build bustage. CLOSED TREE

--HG--
extra : amend_source : cf3cec59ae1efd99b9de0d19b7a09c135138daf5
This commit is contained in:
Dorel Luca 2020-03-03 13:02:04 +02:00
parent 97a2bca5b9
commit 284433eb29
9 changed files with 52 additions and 366 deletions

View File

@ -903,12 +903,10 @@ static struct curveType *curve_from_gamma(float gamma)
//XXX: should this also be taking a black_point?
/* similar to CGColorSpaceCreateCalibratedRGB */
qcms_profile* qcms_profile_create_rgb_with_gamma_set(
qcms_profile* qcms_profile_create_rgb_with_gamma(
qcms_CIE_xyY white_point,
qcms_CIE_xyYTRIPLE primaries,
float redGamma,
float greenGamma,
float blueGamma)
float gamma)
{
qcms_profile* profile = qcms_profile_create();
if (!profile)
@ -920,9 +918,9 @@ qcms_profile* qcms_profile_create_rgb_with_gamma_set(
return INVALID_PROFILE;
}
profile->redTRC = curve_from_gamma(redGamma);
profile->blueTRC = curve_from_gamma(blueGamma);
profile->greenTRC = curve_from_gamma(greenGamma);
profile->redTRC = curve_from_gamma(gamma);
profile->blueTRC = curve_from_gamma(gamma);
profile->greenTRC = curve_from_gamma(gamma);
if (!profile->redTRC || !profile->blueTRC || !profile->greenTRC) {
qcms_profile_release(profile);
@ -935,14 +933,6 @@ qcms_profile* qcms_profile_create_rgb_with_gamma_set(
return profile;
}
qcms_profile* qcms_profile_create_rgb_with_gamma(
qcms_CIE_xyY white_point,
qcms_CIE_xyYTRIPLE primaries,
float gamma)
{
return qcms_profile_create_rgb_with_gamma_set(white_point, primaries, gamma, gamma, gamma);
}
qcms_profile* qcms_profile_create_rgb_with_table(
qcms_CIE_xyY white_point,
qcms_CIE_xyYTRIPLE primaries,
@ -1026,11 +1016,6 @@ static qcms_CIE_xyY white_point_from_temp(int temp_K)
return white_point;
}
qcms_CIE_xyY qcms_white_point_sRGB(void)
{
return white_point_from_temp(6504);
}
qcms_profile* qcms_profile_sRGB(void)
{
qcms_profile *profile;
@ -1043,7 +1028,7 @@ qcms_profile* qcms_profile_sRGB(void)
};
qcms_CIE_xyY D65;
D65 = qcms_white_point_sRGB();
D65 = white_point_from_temp(6504);
table = build_sRGB_gamma_table(1024);

View File

@ -129,13 +129,6 @@ typedef struct
qcms_CIE_xyY blue;
} qcms_CIE_xyYTRIPLE;
qcms_profile* qcms_profile_create_rgb_with_gamma_set(
qcms_CIE_xyY white_point,
qcms_CIE_xyYTRIPLE primaries,
float redGamma,
float blueGamma,
float greenGamma);
qcms_profile* qcms_profile_create_rgb_with_gamma(
qcms_CIE_xyY white_point,
qcms_CIE_xyYTRIPLE primaries,
@ -159,10 +152,7 @@ void qcms_data_from_path(const char *path, void **mem, size_t *size);
qcms_profile* qcms_profile_from_unicode_path(const wchar_t *path);
void qcms_data_from_unicode_path(const wchar_t *path, void **mem, size_t *size);
#endif
qcms_CIE_xyY qcms_white_point_sRGB(void);
qcms_profile* qcms_profile_sRGB(void);
void qcms_profile_release(qcms_profile *profile);
bool qcms_profile_is_bogus(qcms_profile *profile);

View File

@ -31,21 +31,6 @@ struct InfoHeaderLength {
};
};
enum class InfoColorSpace : uint32_t {
CALIBRATED_RGB = 0x00000000,
SRGB = 0x73524742,
WINDOWS = 0x57696E20,
PROFILE_LINKED = 0x4C494E4B,
PROFILE_EMBEDDED = 0x4D424544,
};
enum class InfoColorIntent : uint32_t {
BUSINESS = 0x00000001,
GRAPHICS = 0x00000002,
IMAGES = 0x00000004,
ABS_COLORIMETRIC = 0x00000008,
};
} // namespace bmp
} // namespace image
} // namespace mozilla

View File

@ -434,7 +434,6 @@ class Decoder {
protected:
friend class AutoRecordDecoderTelemetry;
friend class DecoderTestHelper;
friend class nsBMPDecoder;
friend class nsICODecoder;
friend class PalettedSurfaceSink;
friend class SurfaceSink;

View File

@ -103,7 +103,6 @@
#include "RasterImage.h"
#include "SurfacePipeFactory.h"
#include "gfxPlatform.h"
#include <algorithm>
using namespace mozilla::gfx;
@ -133,32 +132,6 @@ struct RLE {
using namespace bmp;
static double FixedPoint2Dot30_To_Double(uint32_t aFixed) {
constexpr double factor = 1.0 / 1073741824.0; // 2^-30
return double(aFixed) * factor;
}
static float FixedPoint16Dot16_To_Float(uint32_t aFixed) {
constexpr double factor = 1.0 / 65536.0; // 2^-16
return double(aFixed) * factor;
}
static float CalRbgEndpointToQcms(const CalRgbEndpoint& aIn,
qcms_CIE_xyY& aOut) {
aOut.x = FixedPoint2Dot30_To_Double(aIn.mX);
aOut.y = FixedPoint2Dot30_To_Double(aIn.mY);
aOut.Y = FixedPoint2Dot30_To_Double(aIn.mZ);
return FixedPoint16Dot16_To_Float(aIn.mGamma);
}
static void ReadCalRgbEndpoint(const char* aData, uint32_t aEndpointOffset,
uint32_t aGammaOffset, CalRgbEndpoint& aOut) {
aOut.mX = LittleEndian::readUint32(aData + aEndpointOffset);
aOut.mY = LittleEndian::readUint32(aData + aEndpointOffset + 4);
aOut.mZ = LittleEndian::readUint32(aData + aEndpointOffset + 8);
aOut.mGamma = LittleEndian::readUint32(aData + aGammaOffset);
}
/// Sets the pixel data in aDecoded to the given values.
/// @param aDecoded pointer to pixel to be set, will be incremented to point to
/// the next pixel.
@ -427,45 +400,35 @@ LexerResult nsBMPDecoder::DoDecode(SourceBufferIterator& aIterator,
IResumable* aOnResume) {
MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
return mLexer.Lex(
aIterator, aOnResume,
[=](State aState, const char* aData, size_t aLength) {
switch (aState) {
case State::FILE_HEADER:
return ReadFileHeader(aData, aLength);
case State::INFO_HEADER_SIZE:
return ReadInfoHeaderSize(aData, aLength);
case State::INFO_HEADER_REST:
return ReadInfoHeaderRest(aData, aLength);
case State::BITFIELDS:
return ReadBitfields(aData, aLength);
case State::SKIP_TO_COLOR_PROFILE:
return Transition::ContinueUnbuffered(State::SKIP_TO_COLOR_PROFILE);
case State::FOUND_COLOR_PROFILE:
return Transition::To(State::COLOR_PROFILE,
mH.mColorSpace.mProfile.mLength);
case State::COLOR_PROFILE:
return ReadColorProfile(aData, aLength);
case State::ALLOCATE_SURFACE:
return AllocateSurface();
case State::COLOR_TABLE:
return ReadColorTable(aData, aLength);
case State::GAP:
return SkipGap();
case State::AFTER_GAP:
return AfterGap();
case State::PIXEL_ROW:
return ReadPixelRow(aData);
case State::RLE_SEGMENT:
return ReadRLESegment(aData);
case State::RLE_DELTA:
return ReadRLEDelta(aData);
case State::RLE_ABSOLUTE:
return ReadRLEAbsolute(aData, aLength);
default:
MOZ_CRASH("Unknown State");
}
});
return mLexer.Lex(aIterator, aOnResume,
[=](State aState, const char* aData, size_t aLength) {
switch (aState) {
case State::FILE_HEADER:
return ReadFileHeader(aData, aLength);
case State::INFO_HEADER_SIZE:
return ReadInfoHeaderSize(aData, aLength);
case State::INFO_HEADER_REST:
return ReadInfoHeaderRest(aData, aLength);
case State::BITFIELDS:
return ReadBitfields(aData, aLength);
case State::COLOR_TABLE:
return ReadColorTable(aData, aLength);
case State::GAP:
return SkipGap();
case State::AFTER_GAP:
return AfterGap();
case State::PIXEL_ROW:
return ReadPixelRow(aData);
case State::RLE_SEGMENT:
return ReadRLESegment(aData);
case State::RLE_DELTA:
return ReadRLEDelta(aData);
case State::RLE_ABSOLUTE:
return ReadRLEAbsolute(aData, aLength);
default:
MOZ_CRASH("Unknown State");
}
});
}
LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadFileHeader(
@ -534,43 +497,6 @@ LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadInfoHeaderRest(
mH.mNumColors = aLength >= 32 ? LittleEndian::readUint32(aData + 28) : 0;
// We ignore the important_colors (aData + 36) field.
// Read color management properties we may need later.
mH.mCsType =
aLength >= 56
? static_cast<InfoColorSpace>(LittleEndian::readUint32(aData + 52))
: InfoColorSpace::SRGB;
mH.mCsIntent = aLength >= 108 ? static_cast<InfoColorIntent>(
LittleEndian::readUint32(aData + 104))
: InfoColorIntent::IMAGES;
switch (mH.mCsType) {
case InfoColorSpace::CALIBRATED_RGB:
if (aLength >= 104) {
ReadCalRgbEndpoint(aData, 56, 92, mH.mColorSpace.mCalibrated.mRed);
ReadCalRgbEndpoint(aData, 68, 96, mH.mColorSpace.mCalibrated.mGreen);
ReadCalRgbEndpoint(aData, 80, 100, mH.mColorSpace.mCalibrated.mBlue);
} else {
mH.mCsType = InfoColorSpace::SRGB;
}
break;
case InfoColorSpace::PROFILE_EMBEDDED:
if (aLength >= 116) {
mH.mColorSpace.mProfile.mOffset =
LittleEndian::readUint32(aData + 108);
mH.mColorSpace.mProfile.mLength =
LittleEndian::readUint32(aData + 112);
} else {
mH.mCsType = InfoColorSpace::SRGB;
}
break;
case InfoColorSpace::PROFILE_LINKED:
case InfoColorSpace::SRGB:
case InfoColorSpace::WINDOWS:
default:
// Nothing to be done at this time.
break;
}
// For WinBMPv4, WinBMPv5 and (possibly) OS2-BMPv2 there are additional
// fields in the info header which we ignore, with the possible exception
// of the color bitfields (see below).
@ -717,156 +643,6 @@ LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadBitfields(
mBytesPerColor = (mH.mBIHSize == InfoHeaderLength::WIN_V2) ? 3 : 4;
}
auto cmsMode = gfxPlatform::GetCMSMode();
if (GetSurfaceFlags() & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
cmsMode = eCMSMode_Off;
}
if (cmsMode != eCMSMode_Off) {
switch (mH.mCsType) {
case InfoColorSpace::PROFILE_EMBEDDED:
return SeekColorProfile(aLength);
case InfoColorSpace::CALIBRATED_RGB:
PrepareCalibratedColorProfile();
break;
case InfoColorSpace::SRGB:
case InfoColorSpace::WINDOWS:
MOZ_LOG(sBMPLog, LogLevel::Debug, ("using sRGB color profile\n"));
if (mColors) {
// We will transform the color table instead of the output pixels.
mTransform = gfxPlatform::GetCMSRGBTransform();
} else {
mTransform = gfxPlatform::GetCMSOSRGBATransform();
}
break;
case InfoColorSpace::PROFILE_LINKED:
default:
// Not supported, no color management.
MOZ_LOG(sBMPLog, LogLevel::Debug, ("color space type not provided\n"));
break;
}
}
return Transition::To(State::ALLOCATE_SURFACE, 0);
}
void nsBMPDecoder::PrepareCalibratedColorProfile() {
// BMP does not define a white point. Use the same as sRGB. This matches what
// Chrome does as well.
qcms_CIE_xyY white_point = qcms_white_point_sRGB();
qcms_CIE_xyYTRIPLE primaries;
float redGamma =
CalRbgEndpointToQcms(mH.mColorSpace.mCalibrated.mRed, primaries.red);
float greenGamma =
CalRbgEndpointToQcms(mH.mColorSpace.mCalibrated.mGreen, primaries.green);
float blueGamma =
CalRbgEndpointToQcms(mH.mColorSpace.mCalibrated.mBlue, primaries.blue);
// Explicitly verify the profile because sometimes the values from the BMP
// header are just garbage.
mInProfile = qcms_profile_create_rgb_with_gamma_set(
white_point, primaries, redGamma, greenGamma, blueGamma);
if (mInProfile && qcms_profile_is_bogus(mInProfile)) {
// Bad profile, just use sRGB instead. Release the profile here, so that
// our destructor doesn't assume we are the owner for the transform.
qcms_profile_release(mInProfile);
mInProfile = nullptr;
}
if (mInProfile) {
MOZ_LOG(sBMPLog, LogLevel::Debug, ("using calibrated RGB color profile\n"));
PrepareColorProfileTransform();
} else {
MOZ_LOG(sBMPLog, LogLevel::Debug,
("failed to create calibrated RGB color profile, using sRGB\n"));
if (mColors) {
// We will transform the color table instead of the output pixels.
mTransform = gfxPlatform::GetCMSRGBTransform();
} else {
mTransform = gfxPlatform::GetCMSOSRGBATransform();
}
}
}
void nsBMPDecoder::PrepareColorProfileTransform() {
if (!mInProfile || !gfxPlatform::GetCMSOutputProfile()) {
return;
}
qcms_data_type inType;
qcms_data_type outType;
if (mColors) {
// We will transform the color table instead of the output pixels.
inType = QCMS_DATA_RGB_8;
outType = QCMS_DATA_RGB_8;
} else {
inType = gfxPlatform::GetCMSOSRGBAType();
outType = inType;
}
qcms_intent intent;
switch (mH.mCsIntent) {
case InfoColorIntent::BUSINESS:
intent = QCMS_INTENT_SATURATION;
break;
case InfoColorIntent::GRAPHICS:
intent = QCMS_INTENT_RELATIVE_COLORIMETRIC;
break;
case InfoColorIntent::ABS_COLORIMETRIC:
intent = QCMS_INTENT_ABSOLUTE_COLORIMETRIC;
break;
case InfoColorIntent::IMAGES:
default:
intent = QCMS_INTENT_PERCEPTUAL;
break;
}
mTransform = qcms_transform_create(
mInProfile, inType, gfxPlatform::GetCMSOutputProfile(), outType, intent);
if (!mTransform) {
MOZ_LOG(sBMPLog, LogLevel::Debug,
("failed to create color profile transform\n"));
}
}
LexerTransition<nsBMPDecoder::State> nsBMPDecoder::SeekColorProfile(
size_t aLength) {
// The offset needs to be at least after the color table.
uint32_t offset = mH.mColorSpace.mProfile.mOffset;
if (offset <= mH.mBIHSize + aLength + mNumColors * mBytesPerColor ||
mH.mColorSpace.mProfile.mLength == 0) {
return Transition::To(State::ALLOCATE_SURFACE, 0);
}
// We have already read the header and bitfields.
offset -= mH.mBIHSize + aLength;
// We need to skip ahead to search for the embedded color profile. We want
// to return to this point once we read it.
mReturnIterator = mLexer.Clone(*mIterator, SIZE_MAX);
if (!mReturnIterator) {
return Transition::TerminateFailure();
}
return Transition::ToUnbuffered(State::FOUND_COLOR_PROFILE,
State::SKIP_TO_COLOR_PROFILE, offset);
}
LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadColorProfile(
const char* aData, size_t aLength) {
mInProfile = qcms_profile_from_memory(aData, aLength);
if (mInProfile) {
MOZ_LOG(sBMPLog, LogLevel::Debug, ("using embedded color profile\n"));
PrepareColorProfileTransform();
}
// Jump back to where we left off.
mIterator = std::move(mReturnIterator);
return Transition::To(State::ALLOCATE_SURFACE, 0);
}
LexerTransition<nsBMPDecoder::State> nsBMPDecoder::AllocateSurface() {
SurfaceFormat format;
SurfacePipeFlags pipeFlags = SurfacePipeFlags();
@ -889,13 +665,9 @@ LexerTransition<nsBMPDecoder::State> nsBMPDecoder::AllocateSurface() {
return Transition::TerminateFailure();
}
// Only give the color transform to the SurfacePipe if we are not transforming
// the color table in advance.
qcms_transform* transform = mColors ? nullptr : mTransform;
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
this, Size(), OutputSize(), FullFrame(), format, format, Nothing(),
transform, pipeFlags);
mTransform, pipeFlags);
if (!pipe) {
return Transition::TerminateFailure();
}
@ -919,14 +691,6 @@ LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadColorTable(
aData += mBytesPerColor;
}
// If we have a color table and a transform, we can avoid transforming each
// pixel by doing the table in advance. We color manage every entry in the
// table, even if it is smaller in case the BMP is malformed and overruns
// its stated color range.
if (mColors && mTransform) {
qcms_transform_data(mTransform, mColors.get(), mColors.get(), 256);
}
// If we are decoding a BMP from the clipboard, we did not know the data
// offset in advance. It is just defined as after the header and color table.
if (mIsForClipboard) {

View File

@ -19,41 +19,19 @@ namespace image {
namespace bmp {
struct CalRgbEndpoint {
uint32_t mGamma;
uint32_t mX;
uint32_t mY;
uint32_t mZ;
};
/// This struct contains the fields from the file header and info header that
/// we use during decoding. (Excluding bitfields fields, which are kept in
/// BitFields.)
struct Header {
uint32_t mDataOffset; // Offset to raster data.
uint32_t mBIHSize; // Header size.
int32_t mWidth; // Image width.
int32_t mHeight; // Image height.
uint16_t mBpp; // Bits per pixel.
uint32_t mCompression; // See struct Compression for valid values.
uint32_t mImageSize; // (compressed) image size. Can be 0 if
// mCompression==0.
uint32_t mNumColors; // Used colors.
InfoColorSpace mCsType; // Color space type.
InfoColorIntent mCsIntent; // Color space intent.
union {
struct {
CalRgbEndpoint mRed;
CalRgbEndpoint mGreen;
CalRgbEndpoint mBlue;
} mCalibrated;
struct {
uint32_t mOffset;
uint32_t mLength;
} mProfile;
} mColorSpace;
uint32_t mDataOffset; // Offset to raster data.
uint32_t mBIHSize; // Header size.
int32_t mWidth; // Image width.
int32_t mHeight; // Image height.
uint16_t mBpp; // Bits per pixel.
uint32_t mCompression; // See struct Compression for valid values.
uint32_t mImageSize; // (compressed) image size. Can be 0 if
// mCompression==0.
uint32_t mNumColors; // Used colors.
Header()
: mDataOffset(0),
@ -63,9 +41,7 @@ struct Header {
mBpp(0),
mCompression(0),
mImageSize(0),
mNumColors(0),
mCsType(InfoColorSpace::SRGB),
mCsIntent(InfoColorIntent::IMAGES) {}
mNumColors(0) {}
};
/// An entry in the color table.
@ -182,10 +158,6 @@ class nsBMPDecoder : public Decoder {
INFO_HEADER_SIZE,
INFO_HEADER_REST,
BITFIELDS,
SKIP_TO_COLOR_PROFILE,
FOUND_COLOR_PROFILE,
COLOR_PROFILE,
ALLOCATE_SURFACE,
COLOR_TABLE,
GAP,
AFTER_GAP,
@ -212,16 +184,10 @@ class nsBMPDecoder : public Decoder {
void FinishRow();
void PrepareCalibratedColorProfile();
void PrepareColorProfileTransform();
LexerTransition<State> ReadFileHeader(const char* aData, size_t aLength);
LexerTransition<State> ReadInfoHeaderSize(const char* aData, size_t aLength);
LexerTransition<State> ReadInfoHeaderRest(const char* aData, size_t aLength);
LexerTransition<State> ReadBitfields(const char* aData, size_t aLength);
LexerTransition<State> SeekColorProfile(size_t aLength);
LexerTransition<State> ReadColorProfile(const char* aData, size_t aLength);
LexerTransition<State> AllocateSurface();
LexerTransition<State> ReadColorTable(const char* aData, size_t aLength);
LexerTransition<State> SkipGap();
LexerTransition<State> AfterGap();
@ -234,9 +200,6 @@ class nsBMPDecoder : public Decoder {
StreamingLexer<State> mLexer;
// Iterator to save return point.
Maybe<SourceBufferIterator> mReturnIterator;
UniquePtr<uint32_t[]> mRowBuffer;
bmp::Header mH;

View File

@ -73,8 +73,7 @@ fuzzy(0-1,0-996) == pal8os2.bmp pal8.png
# BMP: bihsize=108, 127 x 64, bpp=8, compression=0, colors=252
# "A v4 bitmap. Im not sure that the gamma and chromaticity values in this
# file are sensible, because I cant find any detailed documentation of them."
# [We seem to handle the profile wrong in QCMS. See bug 1619332.]
fuzzy(3-3,6376-6376) == pal8v4.bmp pal8.png
fuzzy(0-1,0-996) == pal8v4.bmp pal8.png
# BMP: bihsize=124, 127 x 64, bpp=8, compression=0, colors=252
# "A v5 bitmap. Version 5 has additional colorspace options over v4, so it is

View File

@ -151,15 +151,16 @@ fuzzy(0-1,0-2203) == rgba16-5551.bmp rgba16-5551.png
# BMP: bihsize=124, 127 x 64, bpp=24, compression=0, colors=0
# "My attempt to make a BMP file with an embedded color profile."
fuzzy(1-1,28-28) == rgb24prof.bmp rgb24.png
# [We support it, though we don't do anything with the color profile. Chromium
# also handles it.]
== rgb24prof.bmp rgb24.png
# BMP: bihsize=124, 127 x 64, bpp=24, compression=0, colors=0
# "This image tries to test whether color profiles are fully supported. It has
# the red and green channels swapped, and an embedded color profile that tries
# to swap them back. Support for this is uncommon."
# [The image is significantly closer to the desired output than without color
# management, but we seem to handle the profile wrong in QCMS. See bug 1619332.]
fuzzy(10-10,6597-6597) == rgb24prof2.bmp rgb24.png
# [We don't match rgb24.png as per bmpsuite, but we do match Chrome.]
== rgb24prof2.bmp rgb24prof2.png
# BMP: bihsize=124, 127 x 64, bpp=24, compression=0, colors=0
# "My attempt to make a BMP file with a linked color profile."

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB