Index: branches/2018Q1/www/waterfox/Makefile =================================================================== --- branches/2018Q1/www/waterfox/Makefile (revision 462639) +++ branches/2018Q1/www/waterfox/Makefile (revision 462640) @@ -1,74 +1,74 @@ # $FreeBSD$ PORTNAME= waterfox -DISTVERSION= 56.0.4 -PORTREVISION= 6 +DISTVERSION= 56.0.4-20 +DISTVERSIONSUFFIX= -ge03e284b083d CATEGORIES= www ipv6 MAINTAINER= jbeich@FreeBSD.org COMMENT= Distilled fork of Firefox DEPRECATED= Temporary experiment EXPIRATION_DATE=2018-03-20 BUILD_DEPENDS= nspr>=4.16:devel/nspr \ nss>=3.32.1:security/nss \ icu>=59.1,1:devel/icu \ libevent>=2.1.8:devel/libevent \ harfbuzz>=1.4.7:print/harfbuzz \ graphite2>=1.3.10:graphics/graphite2 \ png>=1.6.31:graphics/png \ libvorbis>=1.3.5,3:audio/libvorbis \ libvpx>=1.5.0:multimedia/libvpx \ sqlite3>=3.19.3:databases/sqlite3 \ ${PYTHON_PKGNAMEPREFIX}sqlite3>0:databases/py-sqlite3@${PY_FLAVOR} \ v4l_compat>0:multimedia/v4l_compat \ autoconf-2.13:devel/autoconf213 \ yasm:devel/yasm \ zip:archivers/zip # soundtouch>=1.9.0:audio/soundtouch \ LIB_DEPENDS= libv4l2.so:multimedia/libv4l USE_GITHUB= yes GH_ACCOUNT= MrAlex94 GH_PROJECT= Waterfox USE_GECKO= gecko MOZ_PKGCONFIG_FILES= # empty USE_MOZILLA= -soundtouch MOZILLA_NAME= Waterfox USE_GL= gl WATERFOX_ICON= ${MOZILLA}.png WATERFOX_ICON_SRC= ${PREFIX}/lib/${MOZILLA}/browser/chrome/icons/default/default256.png WATERFOX_DESKTOP= ${MOZSRC}/taskcluster/docker/firefox-snap/firefox.desktop MOZ_OPTIONS= --enable-application=browser \ --with-app-name=${MOZILLA} \ --with-app-basename=${MOZILLA_NAME} \ --with-distribution-id=org.${MOZILLA}project OPTIONS_DEFAULT= BUNDLED_CAIRO .include "${.CURDIR}/../../www/firefox/Makefile.options" post-patch: @${REINPLACE_CMD} -e 's/%u/%U/' -e '/X-MultipleArgs/d' \ -e 's/firefox/${MOZILLA}/' \ -e 's/Firefox/${MOZILLA_NAME}/' \ ${WATERFOX_DESKTOP} @${REINPLACE_CMD} -e 's|%%LOCALBASE%%|${LOCALBASE}|g' \ ${WRKSRC}/browser/app/nsBrowserApp.cpp pre-configure: (cd ${WRKSRC} && ${LOCALBASE}/bin/autoconf-2.13) (cd ${WRKSRC}/js/src/ && ${LOCALBASE}/bin/autoconf-2.13) post-install: ${INSTALL_DATA} ${WATERFOX_DESKTOP} \ ${STAGEDIR}${PREFIX}/share/applications/${MOZILLA}.desktop ${MKDIR} ${STAGEDIR}${PREFIX}/share/pixmaps ${LN} -sf ${WATERFOX_ICON_SRC} ${STAGEDIR}${PREFIX}/share/pixmaps/${WATERFOX_ICON} .include Index: branches/2018Q1/www/waterfox/distinfo =================================================================== --- branches/2018Q1/www/waterfox/distinfo (revision 462639) +++ branches/2018Q1/www/waterfox/distinfo (revision 462640) @@ -1,3 +1,3 @@ -TIMESTAMP = 1517598190 -SHA256 (MrAlex94-Waterfox-56.0.4_GH0.tar.gz) = 291a7aa8e541802d1705cf68c694e300f9cb14fffc6c1d24e51b9ed486cd44b7 -SIZE (MrAlex94-Waterfox-56.0.4_GH0.tar.gz) = 394233214 +TIMESTAMP = 1519322366 +SHA256 (MrAlex94-Waterfox-56.0.4-20-ge03e284b083d_GH0.tar.gz) = f8103fee10acf9e32fc8d9ea8fca6418a557888a2bda781a92e96beb305c8c4e +SIZE (MrAlex94-Waterfox-56.0.4-20-ge03e284b083d_GH0.tar.gz) = 394048388 Index: branches/2018Q1/www/waterfox/files/patch-bug895096 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug895096 (revision 462639) +++ branches/2018Q1/www/waterfox/files/patch-bug895096 (nonexistent) @@ -1,1234 +0,0 @@ -commit ce1be4b4ebf0 -Author: Ya-Chieh Wu -Date: Tue Sep 12 19:48:00 2017 -0400 - - Bug 895096 - Part 1: Round border-collapsed table borders to device pixels rather than CSS pixels, as for other borders, and store them (as BCPixelSize) as device pixels rather than CSS pixels. r=dbaron - - MozReview-Commit-ID: 3yqj8gAAGYv ---- - layout/painting/nsCSSRendering.cpp | 86 +++++++++++++++++-------------- - layout/painting/nsCSSRendering.h | 1 - - layout/tables/celldata.h | 1 + - layout/tables/nsTableCellFrame.cpp | 20 ++++---- - layout/tables/nsTableColFrame.h | 10 ++-- - layout/tables/nsTableColGroupFrame.cpp | 6 +-- - layout/tables/nsTableFrame.cpp | 92 +++++++++++++++++++--------------- - layout/tables/nsTableFrame.h | 4 +- - layout/tables/nsTableRowFrame.h | 13 ++--- - layout/tables/nsTableRowGroupFrame.cpp | 8 +-- - layout/tables/nsTableRowGroupFrame.h | 8 +-- - 11 files changed, 136 insertions(+), 113 deletions(-) - -diff --git layout/painting/nsCSSRendering.cpp layout/painting/nsCSSRendering.cpp -index bc9d3f780533..753facdb292c 100644 ---- layout/painting/nsCSSRendering.cpp -+++ layout/painting/nsCSSRendering.cpp -@@ -3472,17 +3472,16 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - nscolor aBGColor, - const nsRect& aBorder, - int32_t aAppUnitsPerDevPixel, -- int32_t aAppUnitsPerCSSPixel, - uint8_t aStartBevelSide, - nscoord aStartBevelOffset, - uint8_t aEndBevelSide, - nscoord aEndBevelOffset) - { - bool horizontal = ((eSideTop == aStartBevelSide) || (eSideBottom == aStartBevelSide)); -- nscoord twipsPerPixel = NSIntPixelsToAppUnits(1, aAppUnitsPerCSSPixel); -+ nscoord oneDevPixel = NSIntPixelsToAppUnits(1, aAppUnitsPerDevPixel); - uint8_t ridgeGroove = NS_STYLE_BORDER_STYLE_RIDGE; - -- if ((twipsPerPixel >= aBorder.width) || (twipsPerPixel >= aBorder.height) || -+ if ((oneDevPixel >= aBorder.width) || (oneDevPixel >= aBorder.height) || - (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) || (NS_STYLE_BORDER_STYLE_DOTTED == aBorderStyle)) { - // no beveling for 1 pixel border, dash or dot - aStartBevelOffset = 0; -@@ -3502,46 +3501,48 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - dashLength *= (horizontal) ? aBorder.height : aBorder.width; - // make the min dash length for the ends 1/2 the dash length - nscoord minDashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) -- ? RoundFloatToPixel(((float)dashLength) / 2.0f, twipsPerPixel) : dashLength; -- minDashLength = std::max(minDashLength, twipsPerPixel); -+ ? RoundFloatToPixel(((float)dashLength) / 2.0f, -+ aAppUnitsPerDevPixel) -+ : dashLength; -+ minDashLength = std::max(minDashLength, oneDevPixel); - nscoord numDashSpaces = 0; - nscoord startDashLength = minDashLength; - nscoord endDashLength = minDashLength; - if (horizontal) { -- GetDashInfo(aBorder.width, dashLength, twipsPerPixel, numDashSpaces, -- startDashLength, endDashLength); -+ GetDashInfo(aBorder.width, dashLength, aAppUnitsPerDevPixel, -+ numDashSpaces, startDashLength, endDashLength); - nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height); - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel); -+ aAppUnitsPerDevPixel, oneDevPixel); - - rect.x += startDashLength + dashLength; - rect.width = aBorder.width - - (startDashLength + endDashLength + dashLength); - DrawDashedSegment(aDrawTarget, rect, dashLength, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, horizontal); -+ aAppUnitsPerDevPixel, oneDevPixel, horizontal); - - rect.x += rect.width; - rect.width = endDashLength; - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel); -+ aAppUnitsPerDevPixel, oneDevPixel); - } - else { -- GetDashInfo(aBorder.height, dashLength, twipsPerPixel, numDashSpaces, -- startDashLength, endDashLength); -+ GetDashInfo(aBorder.height, dashLength, aAppUnitsPerDevPixel, -+ numDashSpaces, startDashLength, endDashLength); - nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength); - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel); -+ aAppUnitsPerDevPixel, oneDevPixel); - - rect.y += rect.height + dashLength; - rect.height = aBorder.height - - (startDashLength + endDashLength + dashLength); - DrawDashedSegment(aDrawTarget, rect, dashLength, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, horizontal); -+ aAppUnitsPerDevPixel, oneDevPixel, horizontal); - - rect.y += rect.height; - rect.height = endDashLength; - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel); -+ aAppUnitsPerDevPixel, oneDevPixel); - } - } - break; -@@ -3549,19 +3550,21 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - ridgeGroove = NS_STYLE_BORDER_STYLE_GROOVE; // and fall through to ridge - MOZ_FALLTHROUGH; - case NS_STYLE_BORDER_STYLE_RIDGE: -- if ((horizontal && (twipsPerPixel >= aBorder.height)) || -- (!horizontal && (twipsPerPixel >= aBorder.width))) { -+ if ((horizontal && (oneDevPixel >= aBorder.height)) || -+ (!horizontal && (oneDevPixel >= aBorder.width))) { - // a one pixel border - DrawSolidBorderSegment(aDrawTarget, aBorder, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, aStartBevelOffset, - aEndBevelSide, aEndBevelOffset); - } - else { - nscoord startBevel = (aStartBevelOffset > 0) -- ? RoundFloatToPixel(0.5f * (float)aStartBevelOffset, twipsPerPixel, true) : 0; -+ ? RoundFloatToPixel(0.5f * (float)aStartBevelOffset, -+ aAppUnitsPerDevPixel, true) : 0; - nscoord endBevel = (aEndBevelOffset > 0) -- ? RoundFloatToPixel(0.5f * (float)aEndBevelOffset, twipsPerPixel, true) : 0; -+ ? RoundFloatToPixel(0.5f * (float)aEndBevelOffset, -+ aAppUnitsPerDevPixel, true) : 0; - mozilla::Side ridgeGrooveSide = (horizontal) ? eSideTop : eSideLeft; - // FIXME: In theory, this should use the visited-dependent - // background color, but I don't care. -@@ -3570,7 +3573,8 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - nsRect rect(aBorder); - nscoord half; - if (horizontal) { // top, bottom -- half = RoundFloatToPixel(0.5f * (float)aBorder.height, twipsPerPixel); -+ half = RoundFloatToPixel(0.5f * (float)aBorder.height, -+ aAppUnitsPerDevPixel); - rect.height = half; - if (eSideTop == aStartBevelSide) { - rect.x += startBevel; -@@ -3580,12 +3584,13 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.width -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } - else { // left, right -- half = RoundFloatToPixel(0.5f * (float)aBorder.width, twipsPerPixel); -+ half = RoundFloatToPixel(0.5f * (float)aBorder.width, -+ aAppUnitsPerDevPixel); - rect.width = half; - if (eSideLeft == aStartBevelSide) { - rect.y += startBevel; -@@ -3595,7 +3600,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.height -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3617,7 +3622,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.width -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3632,7 +3637,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.height -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3642,14 +3647,20 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - // We can only do "double" borders if the thickness of the border - // is more than 2px. Otherwise, we fall through to painting a - // solid border. -- if ((aBorder.width > 2*twipsPerPixel || horizontal) && -- (aBorder.height > 2*twipsPerPixel || !horizontal)) { -+ if ((aBorder.width > 2 * oneDevPixel || horizontal) && -+ (aBorder.height > 2 * oneDevPixel || !horizontal)) { - nscoord startBevel = (aStartBevelOffset > 0) -- ? RoundFloatToPixel(0.333333f * (float)aStartBevelOffset, twipsPerPixel) : 0; -+ ? RoundFloatToPixel(0.333333f * -+ (float)aStartBevelOffset, -+ aAppUnitsPerDevPixel) : 0; - nscoord endBevel = (aEndBevelOffset > 0) -- ? RoundFloatToPixel(0.333333f * (float)aEndBevelOffset, twipsPerPixel) : 0; -+ ? RoundFloatToPixel(0.333333f * -+ (float)aEndBevelOffset, -+ aAppUnitsPerDevPixel) : 0; - if (horizontal) { // top, bottom -- nscoord thirdHeight = RoundFloatToPixel(0.333333f * (float)aBorder.height, twipsPerPixel); -+ nscoord thirdHeight = RoundFloatToPixel(0.333333f * -+ (float)aBorder.height, -+ aAppUnitsPerDevPixel); - - // draw the top line or rect - nsRect topRect(aBorder.x, aBorder.y, aBorder.width, thirdHeight); -@@ -3661,7 +3672,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - topRect.width -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, topRect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - -@@ -3676,12 +3687,13 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - bottomRect.width -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, bottomRect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } - else { // left, right -- nscoord thirdWidth = RoundFloatToPixel(0.333333f * (float)aBorder.width, twipsPerPixel); -+ nscoord thirdWidth = RoundFloatToPixel(0.333333f * (float)aBorder.width, -+ aAppUnitsPerDevPixel); - - nsRect leftRect(aBorder.x, aBorder.y, thirdWidth, aBorder.height); - if (eSideLeft == aStartBevelSide) { -@@ -3692,7 +3704,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - leftRect.height -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, leftRect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - -@@ -3706,7 +3718,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rightRect.height -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rightRect, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, -+ aAppUnitsPerDevPixel, oneDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3716,7 +3728,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - MOZ_FALLTHROUGH; - case NS_STYLE_BORDER_STYLE_SOLID: - DrawSolidBorderSegment(aDrawTarget, aBorder, aBorderColor, -- aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, -+ aAppUnitsPerDevPixel, oneDevPixel, aStartBevelSide, - aStartBevelOffset, aEndBevelSide, aEndBevelOffset); - break; - case NS_STYLE_BORDER_STYLE_OUTSET: -diff --git layout/painting/nsCSSRendering.h layout/painting/nsCSSRendering.h -index 8a8086323a59..9437967c5ae8 100644 ---- layout/painting/nsCSSRendering.h -+++ layout/painting/nsCSSRendering.h -@@ -549,7 +549,6 @@ struct nsCSSRendering { - nscolor aBGColor, - const nsRect& aBorderRect, - int32_t aAppUnitsPerDevPixel, -- int32_t aAppUnitsPerCSSPixel, - uint8_t aStartBevelSide = 0, - nscoord aStartBevelOffset = 0, - uint8_t aEndBevelSide = 0, -diff --git layout/tables/celldata.h layout/tables/celldata.h -index d9f902d9a713..e58a8c8823a7 100644 ---- layout/tables/celldata.h -+++ layout/tables/celldata.h -@@ -144,6 +144,7 @@ enum BCBorderOwner - eAjaCellOwner = 10 // cell to the top or to the left - }; - -+// BCPixelSize is in device pixels. - typedef uint16_t BCPixelSize; - - // These are the max sizes that are stored. If they are exceeded, then the max is stored and -diff --git layout/tables/nsTableCellFrame.cpp layout/tables/nsTableCellFrame.cpp -index 283673e84975..6265b41191b6 100644 ---- layout/tables/nsTableCellFrame.cpp -+++ layout/tables/nsTableCellFrame.cpp -@@ -1118,12 +1118,12 @@ nsBCTableCellFrame::GetFrameName(nsAString& aResult) const - LogicalMargin - nsBCTableCellFrame::GetBorderWidth(WritingMode aWM) const - { -- int32_t pixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); - return LogicalMargin(aWM, -- BC_BORDER_END_HALF_COORD(pixelsToTwips, mBStartBorder), -- BC_BORDER_START_HALF_COORD(pixelsToTwips, mIEndBorder), -- BC_BORDER_START_HALF_COORD(pixelsToTwips, mBEndBorder), -- BC_BORDER_END_HALF_COORD(pixelsToTwips, mIStartBorder)); -+ BC_BORDER_END_HALF_COORD(d2a, mBStartBorder), -+ BC_BORDER_START_HALF_COORD(d2a, mIEndBorder), -+ BC_BORDER_START_HALF_COORD(d2a, mBEndBorder), -+ BC_BORDER_END_HALF_COORD(d2a, mIStartBorder)); - } - - BCPixelSize -@@ -1163,12 +1163,12 @@ nsBCTableCellFrame::SetBorderWidth(LogicalSide aSide, BCPixelSize aValue) - nsBCTableCellFrame::GetBorderOverflow() - { - WritingMode wm = GetWritingMode(); -- int32_t p2t = nsPresContext::AppUnitsPerCSSPixel(); -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); - LogicalMargin halfBorder(wm, -- BC_BORDER_START_HALF_COORD(p2t, mBStartBorder), -- BC_BORDER_END_HALF_COORD(p2t, mIEndBorder), -- BC_BORDER_END_HALF_COORD(p2t, mBEndBorder), -- BC_BORDER_START_HALF_COORD(p2t, mIStartBorder)); -+ BC_BORDER_START_HALF_COORD(d2a, mBStartBorder), -+ BC_BORDER_END_HALF_COORD(d2a, mIEndBorder), -+ BC_BORDER_END_HALF_COORD(d2a, mBEndBorder), -+ BC_BORDER_START_HALF_COORD(d2a, mIStartBorder)); - return halfBorder.GetPhysicalMargin(wm); - } - -diff --git layout/tables/nsTableColFrame.h layout/tables/nsTableColFrame.h -index 9fb567f97b49..d310ac5d34db 100644 ---- layout/tables/nsTableColFrame.h -+++ layout/tables/nsTableColFrame.h -@@ -328,14 +328,14 @@ inline nscoord - nsTableColFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM, - mozilla::LogicalMargin& aBorder) - { -- int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); -- aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); -+ aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, - mBStartContBorderWidth); -- aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, -+ aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, - mIEndContBorderWidth); -- aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, -+ aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, - mBEndContBorderWidth); -- return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mIEndContBorderWidth); -+ return BC_BORDER_END_HALF_COORD(d2a, mIEndContBorderWidth); - } - - #endif -diff --git layout/tables/nsTableColGroupFrame.cpp layout/tables/nsTableColGroupFrame.cpp -index 785ac2c3d93e..04a2593181c5 100644 ---- layout/tables/nsTableColGroupFrame.cpp -+++ layout/tables/nsTableColGroupFrame.cpp -@@ -446,13 +446,13 @@ void nsTableColGroupFrame::SetContinuousBCBorderWidth(LogicalSide aForSide, - void nsTableColGroupFrame::GetContinuousBCBorderWidth(WritingMode aWM, - LogicalMargin& aBorder) - { -- int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); - nsTableColFrame* col = GetTableFrame()-> - GetColFrame(mStartColIndex + mColCount - 1); - col->GetContinuousBCBorderWidth(aWM, aBorder); -- aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, -+ aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, - mBStartContBorderWidth); -- aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, -+ aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, - mBEndContBorderWidth); - } - -diff --git layout/tables/nsTableFrame.cpp layout/tables/nsTableFrame.cpp -index 7271426df8e8..fa2ab2257158 100644 ---- layout/tables/nsTableFrame.cpp -+++ layout/tables/nsTableFrame.cpp -@@ -2907,15 +2907,14 @@ nsTableFrame::GetOuterBCBorder(const WritingMode aWM) const - if (NeedToCalcBCBorders()) { - const_cast(this)->CalcBCBorders(); - } -- -- int32_t p2t = nsPresContext::AppUnitsPerCSSPixel(); -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); - BCPropertyData* propData = GetBCProperty(); - if (propData) { - return LogicalMargin(aWM, -- BC_BORDER_START_HALF_COORD(p2t, propData->mBStartBorderWidth), -- BC_BORDER_END_HALF_COORD(p2t, propData->mIEndBorderWidth), -- BC_BORDER_END_HALF_COORD(p2t, propData->mBEndBorderWidth), -- BC_BORDER_START_HALF_COORD(p2t, propData->mIStartBorderWidth)); -+ BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), -+ BC_BORDER_END_HALF_COORD(d2a, propData->mIEndBorderWidth), -+ BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), -+ BC_BORDER_START_HALF_COORD(d2a, propData->mIStartBorderWidth)); - } - return LogicalMargin(aWM); - } -@@ -2927,14 +2926,14 @@ nsTableFrame::GetIncludedOuterBCBorder(const WritingMode aWM) const - const_cast(this)->CalcBCBorders(); - } - -- int32_t p2t = nsPresContext::AppUnitsPerCSSPixel(); -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); - BCPropertyData* propData = GetBCProperty(); - if (propData) { - return LogicalMargin(aWM, -- BC_BORDER_START_HALF_COORD(p2t, propData->mBStartBorderWidth), -- BC_BORDER_END_HALF_COORD(p2t, propData->mIEndCellBorderWidth), -- BC_BORDER_END_HALF_COORD(p2t, propData->mBEndBorderWidth), -- BC_BORDER_START_HALF_COORD(p2t, propData->mIStartCellBorderWidth)); -+ BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), -+ BC_BORDER_END_HALF_COORD(d2a, propData->mIEndCellBorderWidth), -+ BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), -+ BC_BORDER_START_HALF_COORD(d2a, propData->mIStartCellBorderWidth)); - } - return LogicalMargin(aWM); - } -@@ -5038,7 +5037,7 @@ GetColorAndStyle(const nsIFrame* aFrame, - - if (aWidth) { - nscoord width = styleData->GetComputedBorderWidth(physicalSide); -- *aWidth = nsPresContext::AppUnitsToIntCSSPixels(width); -+ *aWidth = aFrame->PresContext()->AppUnitsToDevPixels(width); - } - } - -@@ -6806,6 +6805,7 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) - bool haveIntersect = false; - // find startRowIndex, endRowIndex - nscoord rowB = mInitialOffsetB; -+ nsPresContext* presContext = mTable->PresContext(); - for (uint32_t rgIdx = 0; rgIdx < mRowGroups.Length() && !done; rgIdx++) { - nsTableRowGroupFrame* rgFrame = mRowGroups[rgIdx]; - for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); rowFrame; -@@ -6814,8 +6814,10 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) - nscoord rowBSize = rowFrame->BSize(mTableWM); - if (haveIntersect) { - // conservatively estimate the half border widths outside the row -- nscoord borderHalf = mTable->GetPrevInFlow() ? 0 : nsPresContext:: -- CSSPixelsToAppUnits(rowFrame->GetBStartBCBorderWidth() + 1); -+ nscoord borderHalf = mTable->GetPrevInFlow() ? 0 : -+ presContext->DevPixelsToAppUnits( -+ rowFrame->GetBStartBCBorderWidth() + 1); -+ - if (dirtyRect.BEnd(mTableWM) >= rowB - borderHalf) { - nsTableRowFrame* fifRow = - static_cast(rowFrame->FirstInFlow()); -@@ -6825,8 +6827,9 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) - } - else { - // conservatively estimate the half border widths outside the row -- nscoord borderHalf = mTable->GetNextInFlow() ? 0 : nsPresContext:: -- CSSPixelsToAppUnits(rowFrame->GetBEndBCBorderWidth() + 1); -+ nscoord borderHalf = mTable->GetNextInFlow() ? 0 : -+ presContext->DevPixelsToAppUnits( -+ rowFrame->GetBEndBCBorderWidth() + 1); - if (rowB + rowBSize + borderHalf >= dirtyRect.BStart(mTableWM)) { - mStartRg = rgFrame; - mStartRow = rowFrame; -@@ -6870,8 +6873,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) - nscoord colISize = colFrame->ISize(mTableWM); - if (haveIntersect) { - // conservatively estimate the iStart half border width outside the col -- nscoord iStartBorderHalf = nsPresContext:: -- CSSPixelsToAppUnits(colFrame->GetIStartBorderWidth() + 1); -+ nscoord iStartBorderHalf = presContext->DevPixelsToAppUnits( -+ colFrame->GetIStartBorderWidth() + 1); - if (dirtyRect.IEnd(mTableWM) >= x - iStartBorderHalf) { - endColIndex = colIdx; - } -@@ -6879,8 +6882,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) - } - else { - // conservatively estimate the iEnd half border width outside the col -- nscoord iEndBorderHalf = nsPresContext:: -- CSSPixelsToAppUnits(colFrame->GetIEndBorderWidth() + 1); -+ nscoord iEndBorderHalf = presContext->DevPixelsToAppUnits( -+ colFrame->GetIEndBorderWidth() + 1); - if (x + colISize + iEndBorderHalf >= dirtyRect.IStart(mTableWM)) { - startColIndex = endColIndex = colIdx; - haveIntersect = true; -@@ -7119,7 +7122,8 @@ BCPaintBorderIterator::Next() - * @return - offset in twips - */ - static nscoord --CalcVerCornerOffset(LogicalSide aCornerOwnerSide, -+CalcVerCornerOffset(nsPresContext* aPresContext, -+ LogicalSide aCornerOwnerSide, - BCPixelSize aCornerSubWidth, - BCPixelSize aHorWidth, - bool aIsStartOfSeg, -@@ -7146,7 +7150,7 @@ CalcVerCornerOffset(LogicalSide aCornerOwnerSide, - offset = (aIsStartOfSeg) ? smallHalf : -largeHalf; - } - } -- return nsPresContext::CSSPixelsToAppUnits(offset); -+ return aPresContext->DevPixelsToAppUnits(offset); - } - - /** Compute the horizontal offset of a horizontal border segment -@@ -7158,7 +7162,8 @@ CalcVerCornerOffset(LogicalSide aCornerOwnerSide, - * @return - offset in twips - */ - static nscoord --CalcHorCornerOffset(LogicalSide aCornerOwnerSide, -+CalcHorCornerOffset(nsPresContext* aPresContext, -+ LogicalSide aCornerOwnerSide, - BCPixelSize aCornerSubWidth, - BCPixelSize aVerWidth, - bool aIsStartOfSeg, -@@ -7185,7 +7190,7 @@ CalcHorCornerOffset(LogicalSide aCornerOwnerSide, - offset = (aIsStartOfSeg) ? smallHalf : -largeHalf; - } - } -- return nsPresContext::CSSPixelsToAppUnits(offset); -+ return aPresContext->DevPixelsToAppUnits(offset); - } - - BCBlockDirSeg::BCBlockDirSeg() -@@ -7219,12 +7224,14 @@ BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, - - bool bStartBevel = (aBlockSegISize > 0) ? bevel : false; - BCPixelSize maxInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); -- nscoord offset = CalcVerCornerOffset(ownerSide, cornerSubWidth, -+ nsPresContext* presContext = aIter.mTable->PresContext(); -+ nscoord offset = CalcVerCornerOffset(presContext, -+ ownerSide, cornerSubWidth, - maxInlineSegBSize, true, - bStartBevel); - - mBStartBevelOffset = bStartBevel ? -- nsPresContext::CSSPixelsToAppUnits(maxInlineSegBSize): 0; -+ presContext->DevPixelsToAppUnits(maxInlineSegBSize): 0; - // XXX this assumes that only corners where 2 segments join can be beveled - mBStartBevelSide = (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; - mOffsetB += offset; -@@ -7281,7 +7288,8 @@ BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter, - } - mIsBEndBevel = (mWidth > 0) ? bevel : false; - mBEndInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); -- mBEndOffset = CalcVerCornerOffset(ownerSide, cornerSubWidth, -+ mBEndOffset = CalcVerCornerOffset(aIter.mTable->PresContext(), -+ ownerSide, cornerSubWidth, - mBEndInlineSegBSize, - false, mIsBEndBevel); - mLength += mBEndOffset; -@@ -7306,7 +7314,8 @@ BCBlockDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter, - - // All the tables frames have the same presContext, so we just use any one - // that exists here: -- result.mAppUnitsPerDevPixel = col->PresContext()->AppUnitsPerDevPixel(); -+ nsPresContext* presContext = aIter.mTable->PresContext(); -+ result.mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); - - switch (mOwner) { - case eTableOwner: -@@ -7362,11 +7371,11 @@ BCBlockDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter, - BCPixelSize smallHalf, largeHalf; - DivideBCBorderSize(mWidth, smallHalf, largeHalf); - LogicalRect segRect(aIter.mTableWM, -- mOffsetI - nsPresContext::CSSPixelsToAppUnits(largeHalf), -+ mOffsetI - presContext->DevPixelsToAppUnits(largeHalf), - mOffsetB, -- nsPresContext::CSSPixelsToAppUnits(mWidth), mLength); -+ presContext->DevPixelsToAppUnits(mWidth), mLength); - nscoord bEndBevelOffset = (mIsBEndBevel) ? -- nsPresContext::CSSPixelsToAppUnits(mBEndInlineSegBSize) : 0; -+ presContext->DevPixelsToAppUnits(mBEndInlineSegBSize) : 0; - LogicalSide bEndBevelSide = - (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; - -@@ -7420,7 +7429,6 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, - nsCSSRendering::DrawTableBorderSegment(aDrawTarget, param->mBorderStyle, param->mBorderColor, - param->mBGColor, param->mBorderRect, - param->mAppUnitsPerDevPixel, -- nsPresContext::AppUnitsPerCSSPixel(), - param->mStartBevelSide, param->mStartBevelOffset, - param->mEndBevelSide, param->mEndBevelOffset); - } -@@ -7516,7 +7524,8 @@ BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, - int32_t relColIndex = aIter.GetRelativeColIndex(); - nscoord maxBlockSegISize = std::max(aIter.mBlockDirInfo[relColIndex].mWidth, - aBEndBlockSegISize); -- nscoord offset = CalcHorCornerOffset(cornerOwnerSide, cornerSubWidth, -+ nscoord offset = CalcHorCornerOffset(aIter.mTable->PresContext(), -+ cornerOwnerSide, cornerSubWidth, - maxBlockSegISize, true, iStartBevel); - mIStartBevelOffset = (iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0; - // XXX this assumes that only corners where 2 segments join can be beveled -@@ -7550,11 +7559,12 @@ BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, - int32_t relColIndex = aIter.GetRelativeColIndex(); - nscoord verWidth = std::max(aIter.mBlockDirInfo[relColIndex].mWidth, - aIStartSegISize); -- mEndOffset = CalcHorCornerOffset(ownerSide, cornerSubWidth, verWidth, -- false, mIsIEndBevel); -+ nsPresContext* presContext = aIter.mTable->PresContext(); -+ mEndOffset = CalcHorCornerOffset(presContext, ownerSide, cornerSubWidth, -+ verWidth, false, mIsIEndBevel); - mLength += mEndOffset; - mIEndBevelOffset = (mIsIEndBevel) ? -- nsPresContext::CSSPixelsToAppUnits(verWidth) : 0; -+ presContext->DevPixelsToAppUnits(verWidth) : 0; - mIEndBevelSide = (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; - } - -@@ -7574,7 +7584,8 @@ BCInlineDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter) - - // All the tables frames have the same presContext, so we just use any one - // that exists here: -- result.mAppUnitsPerDevPixel = row->PresContext()->AppUnitsPerDevPixel(); -+ nsPresContext* presContext = aIter.mTable->PresContext(); -+ result.mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); - - result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID; - result.mBorderColor = 0xFFFFFFFF; -@@ -7632,16 +7643,16 @@ BCInlineDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter) - BCPixelSize smallHalf, largeHalf; - DivideBCBorderSize(mWidth, smallHalf, largeHalf); - LogicalRect segRect(aIter.mTableWM, mOffsetI, -- mOffsetB - nsPresContext::CSSPixelsToAppUnits(largeHalf), -+ mOffsetB - presContext->DevPixelsToAppUnits(largeHalf), - mLength, -- nsPresContext::CSSPixelsToAppUnits(mWidth)); -+ presContext->DevPixelsToAppUnits(mWidth)); - - // Convert logical to physical sides/coordinates for DrawTableBorderSegment. - result.mBorderRect = segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize()); - result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide); - result.mEndBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide); - result.mStartBevelOffset = -- nsPresContext::CSSPixelsToAppUnits(mIStartBevelOffset); -+ presContext->DevPixelsToAppUnits(mIStartBevelOffset); - result.mEndBevelOffset = mIEndBevelOffset; - // With inline-RTL directionality, the 'start' and 'end' of the inline-dir - // border segment need to be swapped because DrawTableBorderSegment will -@@ -7679,7 +7690,6 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget) - nsCSSRendering::DrawTableBorderSegment(aDrawTarget, param->mBorderStyle, param->mBorderColor, - param->mBGColor, param->mBorderRect, - param->mAppUnitsPerDevPixel, -- nsPresContext::AppUnitsPerCSSPixel(), - param->mStartBevelSide, param->mStartBevelOffset, - param->mEndBevelSide, param->mEndBevelOffset); - } -diff --git layout/tables/nsTableFrame.h layout/tables/nsTableFrame.h -index c9852a63d463..c23311e8902d 100644 ---- layout/tables/nsTableFrame.h -+++ layout/tables/nsTableFrame.h -@@ -1037,8 +1037,8 @@ inline void nsTableFrame::SetHasBCBorders(bool aValue) - inline nscoord - nsTableFrame::GetContinuousIStartBCBorderWidth() const - { -- int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); -- return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mBits.mIStartContBCBorder); -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); -+ return BC_BORDER_END_HALF_COORD(d2a, mBits.mIStartContBCBorder); - } - - inline void nsTableFrame::SetContinuousIStartBCBorderWidth(nscoord aValue) -diff --git layout/tables/nsTableRowFrame.h layout/tables/nsTableRowFrame.h -index 8263f9b48cda..6a6e3bdd6fca 100644 ---- layout/tables/nsTableRowFrame.h -+++ layout/tables/nsTableRowFrame.h -@@ -425,21 +425,22 @@ inline void nsTableRowFrame::SetHasUnpaginatedBSize(bool aValue) - inline mozilla::LogicalMargin - nsTableRowFrame::GetBCBorderWidth(mozilla::WritingMode aWM) - { -+ nsPresContext* presContext = PresContext(); - return mozilla::LogicalMargin( -- aWM, nsPresContext::CSSPixelsToAppUnits(mBStartBorderWidth), 0, -- nsPresContext::CSSPixelsToAppUnits(mBEndBorderWidth), 0); -+ aWM, presContext->DevPixelsToAppUnits(mBStartBorderWidth), 0, -+ presContext->DevPixelsToAppUnits(mBEndBorderWidth), 0); - } - - inline void - nsTableRowFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM, - mozilla::LogicalMargin& aBorder) - { -- int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); -- aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); -+ aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, - mIStartContBorderWidth); -- aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, -+ aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, - mBStartContBorderWidth); -- aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, -+ aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, - mIEndContBorderWidth); - } - -diff --git layout/tables/nsTableRowGroupFrame.cpp layout/tables/nsTableRowGroupFrame.cpp -index 368dc5b1ec07..adf9c4adabe0 100644 ---- layout/tables/nsTableRowGroupFrame.cpp -+++ layout/tables/nsTableRowGroupFrame.cpp -@@ -1686,10 +1686,10 @@ nsTableRowGroupFrame::GetBCBorderWidth(WritingMode aWM) - lastRowFrame = rowFrame; - } - if (firstRowFrame) { -- border.BStart(aWM) = nsPresContext:: -- CSSPixelsToAppUnits(firstRowFrame->GetBStartBCBorderWidth()); -- border.BEnd(aWM) = nsPresContext:: -- CSSPixelsToAppUnits(lastRowFrame->GetBEndBCBorderWidth()); -+ border.BStart(aWM) = PresContext()->DevPixelsToAppUnits( -+ firstRowFrame->GetBStartBCBorderWidth()); -+ border.BEnd(aWM) = PresContext()->DevPixelsToAppUnits( -+ lastRowFrame->GetBEndBCBorderWidth()); - } - return border; - } -diff --git layout/tables/nsTableRowGroupFrame.h layout/tables/nsTableRowGroupFrame.h -index b5754ccca1bc..cbd2845059a0 100644 ---- layout/tables/nsTableRowGroupFrame.h -+++ layout/tables/nsTableRowGroupFrame.h -@@ -451,12 +451,12 @@ inline void - nsTableRowGroupFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM, - mozilla::LogicalMargin& aBorder) - { -- int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); -- aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, -+ int32_t d2a = PresContext()->AppUnitsPerDevPixel(); -+ aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, - mIEndContBorderWidth); -- aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, -+ aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, - mBEndContBorderWidth); -- aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, -+ aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, - mIStartContBorderWidth); - } - #endif - -commit 70ba00ac0901 -Author: Ya-Chieh Wu -Date: Tue Sep 12 19:49:00 2017 -0400 - - Bug 895096 - Part 2: Merge the identical parameters. r=dbaron - - MozReview-Commit-ID: DNXagFqxLsq ---- - layout/painting/nsCSSRendering.cpp | 37 ++++++++++++++++++------------------- - 1 file changed, 18 insertions(+), 19 deletions(-) - -diff --git layout/painting/nsCSSRendering.cpp layout/painting/nsCSSRendering.cpp -index 753facdb292c..efaccfe32942 100644 ---- layout/painting/nsCSSRendering.cpp -+++ layout/painting/nsCSSRendering.cpp -@@ -3339,7 +3339,6 @@ DrawDashedSegment(DrawTarget& aDrawTarget, - nscoord aDashLength, - nscolor aColor, - int32_t aAppUnitsPerDevPixel, -- nscoord aTwipsPerPixel, - bool aHorizontal) - { - ColorPattern color(ToDeviceColor(aColor)); -@@ -3375,7 +3374,6 @@ DrawSolidBorderSegment(DrawTarget& aDrawTarget, - nsRect aRect, - nscolor aColor, - int32_t aAppUnitsPerDevPixel, -- nscoord aTwipsPerPixel, - uint8_t aStartBevelSide = 0, - nscoord aStartBevelOffset = 0, - uint8_t aEndBevelSide = 0, -@@ -3384,8 +3382,9 @@ DrawSolidBorderSegment(DrawTarget& aDrawTarget, - ColorPattern color(ToDeviceColor(aColor)); - DrawOptions drawOptions(1.f, CompositionOp::OP_OVER, AntialiasMode::NONE); - -+ nscoord oneDevPixel = NSIntPixelsToAppUnits(1, aAppUnitsPerDevPixel); - // We don't need to bevel single pixel borders -- if ((aRect.width == aTwipsPerPixel) || (aRect.height == aTwipsPerPixel) || -+ if ((aRect.width == oneDevPixel) || (aRect.height == oneDevPixel) || - ((0 == aStartBevelOffset) && (0 == aEndBevelOffset))) { - // simple rectangle - aDrawTarget.FillRect(NSRectToSnappedRect(aRect, aAppUnitsPerDevPixel, -@@ -3513,36 +3512,36 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - numDashSpaces, startDashLength, endDashLength); - nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height); - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel); -+ aAppUnitsPerDevPixel); - - rect.x += startDashLength + dashLength; - rect.width = aBorder.width - - (startDashLength + endDashLength + dashLength); - DrawDashedSegment(aDrawTarget, rect, dashLength, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, horizontal); -+ aAppUnitsPerDevPixel, horizontal); - - rect.x += rect.width; - rect.width = endDashLength; - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel); -+ aAppUnitsPerDevPixel); - } - else { - GetDashInfo(aBorder.height, dashLength, aAppUnitsPerDevPixel, - numDashSpaces, startDashLength, endDashLength); - nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength); - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel); -+ aAppUnitsPerDevPixel); - - rect.y += rect.height + dashLength; - rect.height = aBorder.height - - (startDashLength + endDashLength + dashLength); - DrawDashedSegment(aDrawTarget, rect, dashLength, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, horizontal); -+ aAppUnitsPerDevPixel, horizontal); - - rect.y += rect.height; - rect.height = endDashLength; - DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel); -+ aAppUnitsPerDevPixel); - } - } - break; -@@ -3554,7 +3553,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - (!horizontal && (oneDevPixel >= aBorder.width))) { - // a one pixel border - DrawSolidBorderSegment(aDrawTarget, aBorder, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, aStartBevelOffset, - aEndBevelSide, aEndBevelOffset); - } -@@ -3584,7 +3583,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.width -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3600,7 +3599,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.height -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3622,7 +3621,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.width -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3637,7 +3636,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rect.height -= endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rect, bevelColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3672,7 +3671,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - topRect.width -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, topRect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - -@@ -3687,7 +3686,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - bottomRect.width -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, bottomRect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3704,7 +3703,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - leftRect.height -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, leftRect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - -@@ -3718,7 +3717,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - rightRect.height -= aEndBevelOffset - endBevel; - } - DrawSolidBorderSegment(aDrawTarget, rightRect, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, -+ aAppUnitsPerDevPixel, - aStartBevelSide, startBevel, aEndBevelSide, - endBevel); - } -@@ -3728,7 +3727,7 @@ nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget, - MOZ_FALLTHROUGH; - case NS_STYLE_BORDER_STYLE_SOLID: - DrawSolidBorderSegment(aDrawTarget, aBorder, aBorderColor, -- aAppUnitsPerDevPixel, oneDevPixel, aStartBevelSide, -+ aAppUnitsPerDevPixel, aStartBevelSide, - aStartBevelOffset, aEndBevelSide, aEndBevelOffset); - break; - case NS_STYLE_BORDER_STYLE_OUTSET: - -commit 43ae4b41dccd -Author: Ya-Chieh Wu -Date: Tue Sep 12 19:49:00 2017 -0400 - - Bug 895096 - Part 3: Clean up twipsPerPixel to oneDevPixel. r=dbaron - - MozReview-Commit-ID: 70aRd6KFpdd ---- - layout/painting/nsCSSRendering.cpp | 107 +++++++++++++++++++------------------ - 1 file changed, 54 insertions(+), 53 deletions(-) - -diff --git layout/painting/nsCSSRendering.cpp layout/painting/nsCSSRendering.cpp -index efaccfe32942..2da321c2855c 100644 ---- layout/painting/nsCSSRendering.cpp -+++ layout/painting/nsCSSRendering.cpp -@@ -750,13 +750,13 @@ ConstructBorderRenderer(nsPresContext* aPresContext, - } - - // Convert to dev pixels. -- nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1); -- Rect joinedBorderAreaPx = NSRectToRect(joinedBorderArea, twipsPerPixel); -- Float borderWidths[4] = { Float(border.top) / twipsPerPixel, -- Float(border.right) / twipsPerPixel, -- Float(border.bottom) / twipsPerPixel, -- Float(border.left) / twipsPerPixel }; -- Rect dirtyRect = NSRectToRect(aDirtyRect, twipsPerPixel); -+ nscoord oneDevPixel = aPresContext->DevPixelsToAppUnits(1); -+ Rect joinedBorderAreaPx = NSRectToRect(joinedBorderArea, oneDevPixel); -+ Float borderWidths[4] = { Float(border.top) / oneDevPixel, -+ Float(border.right) / oneDevPixel, -+ Float(border.bottom) / oneDevPixel, -+ Float(border.left) / oneDevPixel }; -+ Rect dirtyRect = NSRectToRect(aDirtyRect, oneDevPixel); - - uint8_t borderStyles[4]; - nscolor borderColors[4]; -@@ -1000,15 +1000,15 @@ nsCSSRendering::CreateBorderRendererForOutline(nsPresContext* aPresContext, - outerRect.Size(), Sides(), twipsRadii); - - // Get our conversion values -- nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1); -+ nscoord oneDevPixel = aPresContext->DevPixelsToAppUnits(1); - - // get the outer rectangles -- Rect oRect(NSRectToRect(outerRect, twipsPerPixel)); -+ Rect oRect(NSRectToRect(outerRect, oneDevPixel)); - - // convert the radii - nsMargin outlineMargin(width, width, width, width); - RectCornerRadii outlineRadii; -- ComputePixelRadii(twipsRadii, twipsPerPixel, &outlineRadii); -+ ComputePixelRadii(twipsRadii, oneDevPixel, &outlineRadii); - - uint8_t outlineStyle = ourOutline->mOutlineStyle; - if (outlineStyle == NS_STYLE_BORDER_STYLE_AUTO) { -@@ -1043,11 +1043,11 @@ nsCSSRendering::CreateBorderRendererForOutline(nsPresContext* aPresContext, - outlineColor }; - - // convert the border widths -- Float outlineWidths[4] = { Float(width) / twipsPerPixel, -- Float(width) / twipsPerPixel, -- Float(width) / twipsPerPixel, -- Float(width) / twipsPerPixel }; -- Rect dirtyRect = NSRectToRect(aDirtyRect, twipsPerPixel); -+ Float outlineWidths[4] = { Float(width) / oneDevPixel, -+ Float(width) / oneDevPixel, -+ Float(width) / oneDevPixel, -+ Float(width) / oneDevPixel }; -+ Rect dirtyRect = NSRectToRect(aDirtyRect, oneDevPixel); - - nsIDocument* document = nullptr; - nsIContent* content = aForFrame->GetContent(); -@@ -1441,14 +1441,14 @@ nsCSSRendering::GetBorderRadii(const nsRect& aFrameRect, - nsIFrame* aFrame, - RectCornerRadii& aOutRadii) - { -- const nscoord twipsPerPixel = aFrame->PresContext()->DevPixelsToAppUnits(1); -+ const nscoord oneDevPixel = aFrame->PresContext()->DevPixelsToAppUnits(1); - nscoord twipsRadii[8]; - NS_ASSERTION(aBorderRect.Size() == aFrame->VisualBorderRectRelativeToSelf().Size(), - "unexpected size"); - nsSize sz = aFrameRect.Size(); - bool hasBorderRadius = aFrame->GetBorderRadii(sz, sz, Sides(), twipsRadii); - if (hasBorderRadius) { -- ComputePixelRadii(twipsRadii, twipsPerPixel, &aOutRadii); -+ ComputePixelRadii(twipsRadii, oneDevPixel, &aOutRadii); - } - - return hasBorderRadius; -@@ -1477,7 +1477,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - // Get any border radius, since box-shadow must also have rounded corners if - // the frame does. - RectCornerRadii borderRadii; -- const nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1); -+ const nscoord oneDevPixel = aPresContext->DevPixelsToAppUnits(1); - if (hasBorderRadius) { - nscoord twipsRadii[8]; - NS_ASSERTION(aFrameArea.Size() == aForFrame->VisualBorderRectRelativeToSelf().Size(), -@@ -1485,14 +1485,14 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - nsSize sz = frameRect.Size(); - hasBorderRadius = aForFrame->GetBorderRadii(sz, sz, Sides(), twipsRadii); - if (hasBorderRadius) { -- ComputePixelRadii(twipsRadii, twipsPerPixel, &borderRadii); -+ ComputePixelRadii(twipsRadii, oneDevPixel, &borderRadii); - } - } - - - // We don't show anything that intersects with the frame we're blurring on. So tell the - // blurrer not to do unnecessary work there. -- gfxRect skipGfxRect = ThebesRect(NSRectToRect(frameRect, twipsPerPixel)); -+ gfxRect skipGfxRect = ThebesRect(NSRectToRect(frameRect, oneDevPixel)); - skipGfxRect.Round(); - bool useSkipGfxRect = true; - if (nativeTheme) { -@@ -1504,7 +1504,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - useSkipGfxRect = !aForFrame->IsLeaf(); - nsRect paddingRect = - aForFrame->GetPaddingRect() - aForFrame->GetPosition() + aFrameArea.TopLeft(); -- skipGfxRect = nsLayoutUtils::RectToGfxRect(paddingRect, twipsPerPixel); -+ skipGfxRect = nsLayoutUtils::RectToGfxRect(paddingRect, oneDevPixel); - } else if (hasBorderRadius) { - skipGfxRect.Deflate(gfxMargin( - std::max(borderRadii[C_TL].height, borderRadii[C_TR].height), 0, -@@ -1528,10 +1528,10 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - nsRect shadowRectPlusBlur = shadowRect; - nscoord blurRadius = shadowItem->mRadius; - shadowRectPlusBlur.Inflate( -- nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, twipsPerPixel)); -+ nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, oneDevPixel)); - - Rect shadowGfxRectPlusBlur = -- NSRectToRect(shadowRectPlusBlur, twipsPerPixel); -+ NSRectToRect(shadowRectPlusBlur, oneDevPixel); - shadowGfxRectPlusBlur.RoundOut(); - MaybeSnapToDevicePixels(shadowGfxRectPlusBlur, aDrawTarget, true); - -@@ -1546,7 +1546,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - // and that we're not going to draw directly into aRenderingContext. - gfxContext* shadowContext = - blurringArea.Init(shadowRect, shadowItem->mSpread, blurRadius, -- twipsPerPixel, &aRenderingContext, aDirtyRect, -+ oneDevPixel, &aRenderingContext, aDirtyRect, - useSkipGfxRect ? &skipGfxRect : nullptr, - nsContextBoxBlur::FORCE_MASK); - if (!shadowContext) -@@ -1587,7 +1587,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - aRenderingContext.Save(); - - { -- Rect innerClipRect = NSRectToRect(frameRect, twipsPerPixel); -+ Rect innerClipRect = NSRectToRect(frameRect, oneDevPixel); - if (!MaybeSnapToDevicePixels(innerClipRect, aDrawTarget, true)) { - innerClipRect.Round(); - } -@@ -1643,7 +1643,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - - RectCornerRadii clipRectRadii; - if (hasBorderRadius) { -- Float spreadDistance = Float(shadowItem->mSpread) / twipsPerPixel; -+ Float spreadDistance = Float(shadowItem->mSpread) / oneDevPixel; - - Float borderSizes[4]; - -@@ -1658,7 +1658,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, - } - nsContextBoxBlur::BlurRectangle(&aRenderingContext, - shadowRect, -- twipsPerPixel, -+ oneDevPixel, - hasBorderRadius ? &clipRectRadii : nullptr, - blurRadius, - gfxShadowColor, -@@ -1716,19 +1716,19 @@ nsCSSRendering::GetShadowInnerRadii(nsIFrame* aFrame, - nsSize sz = frameRect.Size(); - nsMargin border = aFrame->GetUsedBorder(); - bool hasBorderRadius = aFrame->GetBorderRadii(sz, sz, Sides(), twipsRadii); -- const nscoord twipsPerPixel = aFrame->PresContext()->DevPixelsToAppUnits(1); -+ const nscoord oneDevPixel = aFrame->PresContext()->DevPixelsToAppUnits(1); - - RectCornerRadii borderRadii; - - hasBorderRadius = GetBorderRadii(frameRect, aFrameArea, aFrame, borderRadii); - if (hasBorderRadius) { -- ComputePixelRadii(twipsRadii, twipsPerPixel, &borderRadii); -+ ComputePixelRadii(twipsRadii, oneDevPixel, &borderRadii); - - Float borderSizes[4] = { -- Float(border.top) / twipsPerPixel, -- Float(border.right) / twipsPerPixel, -- Float(border.bottom) / twipsPerPixel, -- Float(border.left) / twipsPerPixel -+ Float(border.top) / oneDevPixel, -+ Float(border.right) / oneDevPixel, -+ Float(border.bottom) / oneDevPixel, -+ Float(border.left) / oneDevPixel - }; - nsCSSBorderRenderer::ComputeInnerRadii(borderRadii, - borderSizes, -@@ -1759,7 +1759,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, - aFrameArea, - innerRadii); - -- const nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1); -+ const nscoord oneDevPixel = aPresContext->DevPixelsToAppUnits(1); - - for (uint32_t i = shadows->Length(); i > 0; --i) { - nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1); -@@ -1771,7 +1771,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, - // that we will NOT paint in - nscoord blurRadius = shadowItem->mRadius; - nsMargin blurMargin = -- nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, twipsPerPixel); -+ nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, oneDevPixel); - nsRect shadowPaintRect = paddingRect; - shadowPaintRect.Inflate(blurMargin); - -@@ -1780,14 +1780,14 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, - // up values between zero and one device pixels to one device pixel. - // This way of rounding is symmetric around zero, which makes sense for - // the spread radius. -- int32_t spreadDistance = shadowItem->mSpread / twipsPerPixel; -+ int32_t spreadDistance = shadowItem->mSpread / oneDevPixel; - nscoord spreadDistanceAppUnits = aPresContext->DevPixelsToAppUnits(spreadDistance); - - nsRect shadowClipRect = paddingRect; - shadowClipRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset); - shadowClipRect.Deflate(spreadDistanceAppUnits, spreadDistanceAppUnits); - -- Rect shadowClipGfxRect = NSRectToRect(shadowClipRect, twipsPerPixel); -+ Rect shadowClipGfxRect = NSRectToRect(shadowClipRect, oneDevPixel); - shadowClipGfxRect.Round(); - - RectCornerRadii clipRectRadii; -@@ -1820,7 +1820,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, - // including after blurring. - nsRect skipRect = shadowClipRect; - skipRect.Deflate(blurMargin); -- gfxRect skipGfxRect = nsLayoutUtils::RectToGfxRect(skipRect, twipsPerPixel); -+ gfxRect skipGfxRect = nsLayoutUtils::RectToGfxRect(skipRect, oneDevPixel); - if (hasBorderRadius) { - skipGfxRect.Deflate(gfxMargin( - std::max(clipRectRadii[C_TL].height, clipRectRadii[C_TR].height), 0, -@@ -1836,7 +1836,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, - // Clip the context to the area of the frame's padding rect, so no part of the - // shadow is painted outside. Also cut out anything beyond where the inset shadow - // will be. -- Rect shadowGfxRect = NSRectToRect(paddingRect, twipsPerPixel); -+ Rect shadowGfxRect = NSRectToRect(paddingRect, oneDevPixel); - shadowGfxRect.Round(); - - Color shadowColor = GetShadowColor(shadowItem, aForFrame, 1.0); -@@ -1853,14 +1853,14 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, - } - - nsContextBoxBlur insetBoxBlur; -- gfxRect destRect = nsLayoutUtils::RectToGfxRect(shadowPaintRect, twipsPerPixel); -- Point shadowOffset(shadowItem->mXOffset / twipsPerPixel, -- shadowItem->mYOffset / twipsPerPixel); -+ gfxRect destRect = nsLayoutUtils::RectToGfxRect(shadowPaintRect, oneDevPixel); -+ Point shadowOffset(shadowItem->mXOffset / oneDevPixel, -+ shadowItem->mYOffset / oneDevPixel); - - insetBoxBlur.InsetBoxBlur(&aRenderingContext, ToRect(destRect), - shadowClipGfxRect, shadowColor, - blurRadius, spreadDistanceAppUnits, -- twipsPerPixel, hasBorderRadius, -+ oneDevPixel, hasBorderRadius, - clipRectRadii, ToRect(skipGfxRect), - shadowOffset); - aRenderingContext.Restore(); -@@ -3299,26 +3299,27 @@ nsCSSRendering::GetBackgroundLayerRect(nsPresContext* aPresContext, - - static nscoord - RoundIntToPixel(nscoord aValue, -- nscoord aTwipsPerPixel, -+ nscoord aOneDevPixel, - bool aRoundDown = false) - { -- if (aTwipsPerPixel <= 0) -- // We must be rendering to a device that has a resolution greater than Twips! -+ if (aOneDevPixel <= 0) -+ // We must be rendering to a device that has a resolution greater than -+ // one device pixel! - // In that case, aValue is as accurate as it's going to get. - return aValue; - -- nscoord halfPixel = NSToCoordRound(aTwipsPerPixel / 2.0f); -- nscoord extra = aValue % aTwipsPerPixel; -- nscoord finalValue = (!aRoundDown && (extra >= halfPixel)) ? aValue + (aTwipsPerPixel - extra) : aValue - extra; -+ nscoord halfPixel = NSToCoordRound(aOneDevPixel / 2.0f); -+ nscoord extra = aValue % aOneDevPixel; -+ nscoord finalValue = (!aRoundDown && (extra >= halfPixel)) ? aValue + (aOneDevPixel - extra) : aValue - extra; - return finalValue; - } - - static nscoord - RoundFloatToPixel(float aValue, -- nscoord aTwipsPerPixel, -+ nscoord aOneDevPixel, - bool aRoundDown = false) - { -- return RoundIntToPixel(NSToCoordRound(aValue), aTwipsPerPixel, aRoundDown); -+ return RoundIntToPixel(NSToCoordRound(aValue), aOneDevPixel, aRoundDown); - } - - static void SetPoly(const Rect& aRect, Point* poly) -@@ -3443,7 +3444,7 @@ DrawSolidBorderSegment(DrawTarget& aDrawTarget, - static void - GetDashInfo(nscoord aBorderLength, - nscoord aDashLength, -- nscoord aTwipsPerPixel, -+ nscoord aOneDevPixel, - int32_t& aNumDashSpaces, - nscoord& aStartDashLength, - nscoord& aEndDashLength) -@@ -3457,7 +3458,7 @@ GetDashInfo(nscoord aBorderLength, - aNumDashSpaces = (aBorderLength - aDashLength)/ (2 * aDashLength); // round down - nscoord extra = aBorderLength - aStartDashLength - aEndDashLength - (((2 * aNumDashSpaces) - 1) * aDashLength); - if (extra > 0) { -- nscoord half = RoundIntToPixel(extra / 2, aTwipsPerPixel); -+ nscoord half = RoundIntToPixel(extra / 2, aOneDevPixel); - aStartDashLength += half; - aEndDashLength += (extra - half); - } Property changes on: branches/2018Q1/www/waterfox/files/patch-bug895096 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1388020 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1388020 (revision 462639) +++ branches/2018Q1/www/waterfox/files/patch-bug1388020 (revision 462640) @@ -1,439 +1,438 @@ commit 56cb3a82e6f1 Author: Andrew Osmond Date: Wed Feb 7 09:33:12 2018 -0500 Bug 1388020. r=nical a=RyanVM --HG-- extra : source : fd15c14e5efb1874591f4e113c1ae1c49154804f --- gfx/layers/client/TextureClient.h | 2 +- gfx/layers/composite/TextureHost.cpp | 65 +++++++++++++++++++----- gfx/layers/composite/X11TextureHost.cpp | 13 +++-- gfx/layers/d3d11/TextureD3D11.cpp | 6 +-- gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp | 8 +++ gfx/layers/opengl/TextureHostOGL.cpp | 25 ++------- gfx/tests/gtest/TestLayers.h | 16 ++++++ gfx/tests/gtest/TestTextureCompatibility.cpp | 12 +++-- gfx/tests/gtest/TestTextures.cpp | 7 ++- gfx/tests/gtest/TextureHelper.h | 3 +- 10 files changed, 108 insertions(+), 49 deletions(-) diff --git gfx/layers/client/TextureClient.h gfx/layers/client/TextureClient.h index e56ea21841ad..81be2867ca7a 100644 --- gfx/layers/client/TextureClient.h +++ gfx/layers/client/TextureClient.h @@ -761,7 +761,7 @@ protected: friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*); friend void TestTextureClientYCbCr(TextureClient*, PlanarYCbCrData&); friend already_AddRefed CreateTextureHostWithBackend( - TextureClient*, LayersBackend&); + TextureClient*, ISurfaceAllocator*, LayersBackend&); #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL public: diff --git gfx/layers/composite/TextureHost.cpp gfx/layers/composite/TextureHost.cpp index a48a9081e155..e0a74920fbe5 100644 --- gfx/layers/composite/TextureHost.cpp +++ gfx/layers/composite/TextureHost.cpp @@ -116,15 +116,9 @@ TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator, uint64_t aSerial, const wr::MaybeExternalImageId& aExternalImageId) { - if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer && - aSharedData.get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::Tuintptr_t && - !aAllocator->IsSameProcess()) - { - NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!"); - return nullptr; - } TextureParent* actor = new TextureParent(aAllocator, aSerial, aExternalImageId); if (!actor->Init(aSharedData, aLayersBackend, aFlags)) { + actor->ActorDestroy(ipc::IProtocol::ActorDestroyReason::FailedConstructor); delete actor; return nullptr; } @@ -232,6 +226,11 @@ TextureHost::Create(const SurfaceDescriptor& aDesc, #ifdef MOZ_X11 case SurfaceDescriptor::TSurfaceDescriptorX11: { + if (!aDeallocator->IsSameProcess()) { + NS_ERROR("A client process is trying to peek at our address space using a X11Texture!"); + return nullptr; + } + const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11(); result = MakeAndAddRef(aFlags, desc); break; @@ -248,7 +247,7 @@ TextureHost::Create(const SurfaceDescriptor& aDesc, MOZ_CRASH("GFX: Unsupported Surface type host"); } - if (WrapWithWebRenderTextureHost(aDeallocator, aBackend, aFlags)) { + if (result && WrapWithWebRenderTextureHost(aDeallocator, aBackend, aFlags)) { MOZ_ASSERT(aExternalImageId.isSome()); result = new WebRenderTextureHost(aDesc, aFlags, result, aExternalImageId.ref()); } -@@ -269,13 +268,50 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, +@@ -269,13 +268,49 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, const MemoryOrShmem& data = bufferDesc.data(); switch (data.type()) { case MemoryOrShmem::TShmem: { - result = new ShmemTextureHost(data.get_Shmem(), - bufferDesc.desc(), - aDeallocator, - aFlags); + const ipc::Shmem& shmem = data.get_Shmem(); + const BufferDescriptor& desc = bufferDesc.desc(); + if (!shmem.IsReadable()) { + // We failed to map the shmem so we can't verify its size. This + // should not be a fatal error, so just create the texture with + // nothing backing it. + result = new ShmemTextureHost(shmem, desc, aDeallocator, aFlags); + break; + } + + size_t bufSize = shmem.Size(); + size_t reqSize = SIZE_MAX; + switch (desc.type()) { + case BufferDescriptor::TYCbCrDescriptor: { + const YCbCrDescriptor& ycbcr = desc.get_YCbCrDescriptor(); + reqSize = -+ ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.ySize().width, -+ ycbcr.cbCrSize(), ycbcr.cbCrSize().width); ++ ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.cbCrSize()); + break; + } + case BufferDescriptor::TRGBDescriptor: { + const RGBDescriptor& rgb = desc.get_RGBDescriptor(); + reqSize = ImageDataSerializer::ComputeRGBBufferSize(rgb.size(), rgb.format()); + break; + } + default: + gfxCriticalError() << "Bad buffer host descriptor " << (int)desc.type(); + MOZ_CRASH("GFX: Bad descriptor"); + } + + if (bufSize < reqSize) { + NS_ERROR("A client process gave a shmem too small to fit for its descriptor!"); + return nullptr; + } + + result = new ShmemTextureHost(shmem, desc, aDeallocator, aFlags); break; } case MemoryOrShmem::Tuintptr_t: { + if (!aDeallocator->IsSameProcess()) { + NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!"); + return nullptr; + } + result = new MemoryTextureHost(reinterpret_cast(data.get_uintptr_t()), bufferDesc.desc(), aFlags); @@ -293,6 +329,11 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, } #ifdef XP_WIN case SurfaceDescriptor::TSurfaceDescriptorDIB: { + if (!aDeallocator->IsSameProcess()) { + NS_ERROR("A client process is trying to peek at our address space using a DIBTexture!"); + return nullptr; + } + result = new DIBTextureHost(aFlags, aDesc); break; } diff --git gfx/layers/composite/X11TextureHost.cpp gfx/layers/composite/X11TextureHost.cpp index e2251f0c531a..94cb3f2f9594 100644 --- gfx/layers/composite/X11TextureHost.cpp +++ gfx/layers/composite/X11TextureHost.cpp @@ -23,10 +23,9 @@ X11TextureHost::X11TextureHost(TextureFlags aFlags, const SurfaceDescriptorX11& aDescriptor) : TextureHost(aFlags) { - RefPtr surface = aDescriptor.OpenForeign(); - mSurface = surface.get(); + mSurface = aDescriptor.OpenForeign(); - if (!(aFlags & TextureFlags::DEALLOCATE_CLIENT)) { + if (mSurface && !(aFlags & TextureFlags::DEALLOCATE_CLIENT)) { mSurface->TakePixmap(); } } @@ -34,7 +33,7 @@ X11TextureHost::X11TextureHost(TextureFlags aFlags, bool X11TextureHost::Lock() { - if (!mCompositor) { + if (!mCompositor || !mSurface) { return false; } @@ -75,6 +74,9 @@ X11TextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider) SurfaceFormat X11TextureHost::GetFormat() const { + if (!mSurface) { + return SurfaceFormat::UNKNOWN; + } gfxContentType type = mSurface->GetContentType(); #ifdef GL_PROVIDER_GLX if (mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL) { @@ -87,6 +89,9 @@ X11TextureHost::GetFormat() const IntSize X11TextureHost::GetSize() const { + if (!mSurface) { + return IntSize(); + } return mSurface->GetSize(); } diff --git gfx/layers/d3d11/TextureD3D11.cpp gfx/layers/d3d11/TextureD3D11.cpp index 379686418ef0..4ad758849b93 100644 --- gfx/layers/d3d11/TextureD3D11.cpp +++ gfx/layers/d3d11/TextureD3D11.cpp @@ -763,10 +763,6 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc, { RefPtr result; switch (aDesc.type()) { - case SurfaceDescriptor::TSurfaceDescriptorBuffer: { - result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags); - break; - } case SurfaceDescriptor::TSurfaceDescriptorD3D10: { result = new DXGITextureHostD3D11(aFlags, aDesc.get_SurfaceDescriptorD3D10()); @@ -778,7 +774,7 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc, break; } default: { - NS_WARNING("Unsupported SurfaceDescriptor type"); + MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type"); } } return result.forget(); diff --git gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp index 291b0eb3d0dc..f363bb5a7cf7 100644 --- gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp +++ gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp @@ -32,6 +32,8 @@ MacIOSurfaceTextureHostOGL::~MacIOSurfaceTextureHostOGL() GLTextureSource* MacIOSurfaceTextureHostOGL::CreateTextureSourceForPlane(size_t aPlane) { + MOZ_ASSERT(mSurface); + GLuint textureHandle; gl::GLContext* gl = mProvider->GetGLContext(); gl->fGenTextures(1, &textureHandle); @@ -94,11 +96,17 @@ MacIOSurfaceTextureHostOGL::SetTextureSourceProvider(TextureSourceProvider* aPro gfx::SurfaceFormat MacIOSurfaceTextureHostOGL::GetFormat() const { + if (!mSurface) { + return gfx::SurfaceFormat::UNKNOWN; + } return mSurface->GetFormat(); } gfx::SurfaceFormat MacIOSurfaceTextureHostOGL::GetReadFormat() const { + if (!mSurface) { + return gfx::SurfaceFormat::UNKNOWN; + } return mSurface->GetReadFormat(); } diff --git gfx/layers/opengl/TextureHostOGL.cpp gfx/layers/opengl/TextureHostOGL.cpp index bdcd8778c10d..2b28c19a126d 100644 --- gfx/layers/opengl/TextureHostOGL.cpp +++ gfx/layers/opengl/TextureHostOGL.cpp @@ -26,10 +26,6 @@ #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h" #endif -#ifdef GL_PROVIDER_GLX -#include "mozilla/layers/X11TextureHost.h" -#endif - using namespace mozilla::gl; using namespace mozilla::gfx; @@ -46,14 +42,6 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc, { RefPtr result; switch (aDesc.type()) { - case SurfaceDescriptor::TSurfaceDescriptorBuffer: { - result = CreateBackendIndependentTextureHost(aDesc, - aDeallocator, - aBackend, - aFlags); - break; - } - #ifdef MOZ_WIDGET_ANDROID case SurfaceDescriptor::TSurfaceTextureDescriptor: { const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor(); @@ -88,14 +76,6 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc, } #endif -#ifdef GL_PROVIDER_GLX - case SurfaceDescriptor::TSurfaceDescriptorX11: { - const auto& desc = aDesc.get_SurfaceDescriptorX11(); - result = new X11TextureHost(aFlags, desc); - break; - } -#endif - case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: { const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture(); result = new GLTextureHost(aFlags, desc.texture(), @@ -105,7 +85,10 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc, desc.hasAlpha()); break; } - default: return nullptr; + default: { + MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type"); + break; + } } return result.forget(); } diff --git gfx/tests/gtest/TestLayers.h gfx/tests/gtest/TestLayers.h index 18e351f7718c..fc6b750f1c62 100644 --- gfx/tests/gtest/TestLayers.h +++ gfx/tests/gtest/TestLayers.h @@ -8,6 +8,22 @@ #include "Layers.h" #include "nsTArray.h" +#include "mozilla/layers/ISurfaceAllocator.h" + +namespace mozilla { +namespace layers { + +class TestSurfaceAllocator final : public ISurfaceAllocator +{ +public: + TestSurfaceAllocator() {} + ~TestSurfaceAllocator() override {} + + bool IsSameProcess() const override { return true; } +}; + +} // layers +} // mozilla /* Create layer tree from a simple layer tree description syntax. * Each index is either the first letter of the layer type or diff --git gfx/tests/gtest/TestTextureCompatibility.cpp gfx/tests/gtest/TestTextureCompatibility.cpp index 45db4943ed1c..0815823b81ce 100644 --- gfx/tests/gtest/TestTextureCompatibility.cpp +++ gfx/tests/gtest/TestTextureCompatibility.cpp @@ -14,6 +14,7 @@ #include "mozilla/layers/TextureClient.h" #include "mozilla/layers/TextureHost.h" #include "mozilla/RefPtr.h" +#include "TestLayers.h" #include "TextureHelper.h" using mozilla::gfx::Feature; @@ -22,6 +23,7 @@ using mozilla::layers::BasicCompositor; using mozilla::layers::Compositor; using mozilla::layers::CompositorOptions; using mozilla::layers::LayersBackend; +using mozilla::layers::TestSurfaceAllocator; using mozilla::layers::TextureClient; using mozilla::layers::TextureHost; using mozilla::widget::CompositorWidget; @@ -31,8 +33,9 @@ using mozilla::widget::InProcessCompositorWidget; * This function will create the possible TextureClient and TextureHost pairs * according to the given backend. */ -void +static void CreateTextureWithBackend(LayersBackend& aLayersBackend, + ISurfaceAllocator* aDeallocator, nsTArray>& aTextureClients, nsTArray>& aTextureHosts) { @@ -43,7 +46,8 @@ CreateTextureWithBackend(LayersBackend& aLayersBackend, for (uint32_t i = 0; i < aTextureClients.Length(); i++) { aTextureHosts.AppendElement( - CreateTextureHostWithBackend(aTextureClients[i], aLayersBackend)); + CreateTextureHostWithBackend(aTextureClients[i], aDeallocator, + aLayersBackend)); } } @@ -115,13 +119,15 @@ CheckCompatibilityWithBasicCompositor(LayersBackend aBackends, TEST(Gfx, TestTextureCompatibility) { nsTArray backendHints; + RefPtr deallocator = new TestSurfaceAllocator(); GetPlatformBackends(backendHints); for (uint32_t i = 0; i < backendHints.Length(); i++) { nsTArray> textureClients; nsTArray> textureHosts; - CreateTextureWithBackend(backendHints[i], textureClients, textureHosts); + CreateTextureWithBackend(backendHints[i], deallocator, + textureClients, textureHosts); CheckCompatibilityWithBasicCompositor(backendHints[i], textureHosts); } } diff --git gfx/tests/gtest/TestTextures.cpp gfx/tests/gtest/TestTextures.cpp index 19b94b867117..291eb55ca7e5 100644 --- gfx/tests/gtest/TestTextures.cpp +++ gfx/tests/gtest/TestTextures.cpp @@ -5,6 +5,7 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" +#include "TestLayers.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Tools.h" @@ -147,7 +148,8 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t); // host deserialization - RefPtr host = CreateBackendIndependentTextureHost(descriptor, nullptr, + RefPtr deallocator = new TestSurfaceAllocator(); + RefPtr host = CreateBackendIndependentTextureHost(descriptor, deallocator, LayersBackend::LAYERS_NONE, texture->GetFlags()); @@ -193,7 +195,8 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) { ASSERT_EQ(ycbcrDesc.stereoMode(), ycbcrData.mStereoMode); // host deserialization - RefPtr textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr, + RefPtr deallocator = new TestSurfaceAllocator(); + RefPtr textureHost = CreateBackendIndependentTextureHost(descriptor, deallocator, LayersBackend::LAYERS_NONE, client->GetFlags()); diff --git gfx/tests/gtest/TextureHelper.h gfx/tests/gtest/TextureHelper.h index 144a237b17d4..770f7464f829 100644 --- gfx/tests/gtest/TextureHelper.h +++ gfx/tests/gtest/TextureHelper.h @@ -140,6 +140,7 @@ CreateTextureClientWithBackend(LayersBackend aLayersBackend) */ already_AddRefed CreateTextureHostWithBackend(TextureClient* aClient, + ISurfaceAllocator* aDeallocator, LayersBackend& aLayersBackend) { if (!aClient) { @@ -153,7 +154,7 @@ CreateTextureHostWithBackend(TextureClient* aClient, aClient->ToSurfaceDescriptor(descriptor); wr::MaybeExternalImageId id = Nothing(); - return TextureHost::Create(descriptor, nullptr, aLayersBackend, + return TextureHost::Create(descriptor, aDeallocator, aLayersBackend, aClient->GetFlags(), id); } Index: branches/2018Q1/www/waterfox/files/patch-bug1398021 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1398021 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1398021 (revision 462640) @@ -0,0 +1,2737 @@ +commit 909ebdebd850 +Author: Ryan VanderMeulen +Date: Tue Sep 12 09:00:37 2017 -0400 + + Bug 1398021 - Update lz4 to version 1.8.0. r=froydnj +--- + mfbt/Compression.cpp | 7 +- + mfbt/lz4.c | 1593 ++++++++++++++++++++++++++++++-------------------- + mfbt/lz4.h | 531 +++++++++++------ + 3 files changed, 1319 insertions(+), 812 deletions(-) + +diff --git mfbt/Compression.cpp mfbt/Compression.cpp +index 3f5fff53c425..ed0bb4ef72c7 100644 +--- mfbt/Compression.cpp ++++ mfbt/Compression.cpp +@@ -36,7 +36,8 @@ LZ4::compress(const char* aSource, size_t aInputSize, char* aDest) + { + CheckedInt inputSizeChecked = aInputSize; + MOZ_ASSERT(inputSizeChecked.isValid()); +- return LZ4_compress(aSource, aDest, inputSizeChecked.value()); ++ return LZ4_compress_default(aSource, aDest, inputSizeChecked.value(), ++ LZ4_compressBound(inputSizeChecked.value())); + } + + size_t +@@ -47,8 +48,8 @@ LZ4::compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest, + MOZ_ASSERT(inputSizeChecked.isValid()); + CheckedInt maxOutputSizeChecked = aMaxOutputSize; + MOZ_ASSERT(maxOutputSizeChecked.isValid()); +- return LZ4_compress_limitedOutput(aSource, aDest, inputSizeChecked.value(), +- maxOutputSizeChecked.value()); ++ return LZ4_compress_default(aSource, aDest, inputSizeChecked.value(), ++ maxOutputSizeChecked.value()); + } + + bool +diff --git mfbt/lz4.c mfbt/lz4.c +index c416fe815a42..5752b4d17b0e 100644 +--- mfbt/lz4.c ++++ mfbt/lz4.c +@@ -1,6 +1,7 @@ + /* + LZ4 - Fast LZ compression algorithm +- Copyright (C) 2011-2014, Yann Collet. ++ Copyright (C) 2011-2017, Yann Collet. ++ + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without +@@ -27,118 +28,96 @@ + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : +- - LZ4 source repository : http://code.google.com/p/lz4/ +- - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c ++ - LZ4 homepage : http://www.lz4.org ++ - LZ4 source repository : https://github.com/lz4/lz4 + */ + +-/************************************** +- Tuning parameters ++ ++/*-************************************ ++* Tuning parameters + **************************************/ + /* +- * HEAPMODE : ++ * LZ4_HEAPMODE : + * Select how default compression functions will allocate memory for their hash table, +- * in memory stack (0:default, fastest), or in memory heap (1:requires memory allocation (malloc)). ++ * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). + */ +-#define HEAPMODE 0 +- +- +-/************************************** +- CPU Feature Detection +-**************************************/ +-/* 32 or 64 bits ? */ +-#if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \ +- || defined(__powerpc64__) || defined(__powerpc64le__) \ +- || defined(__ppc64__) || defined(__ppc64le__) \ +- || defined(__PPC64__) || defined(__PPC64LE__) \ +- || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) \ +- || (defined(__mips64) && defined(_ABI64))) /* Detects 64 bits mode */ +-# define LZ4_ARCH64 1 +-#else +-# define LZ4_ARCH64 0 ++#ifndef LZ4_HEAPMODE ++# define LZ4_HEAPMODE 0 + #endif + + /* +- * Little Endian or Big Endian ? +- * Overwrite the #define below if you know your architecture endianess ++ * ACCELERATION_DEFAULT : ++ * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 + */ +-#include /* Apparently required to detect endianess */ +-#if defined (__GLIBC__) +-# include +-# if (__BYTE_ORDER == __BIG_ENDIAN) +-# define LZ4_BIG_ENDIAN 1 ++#define ACCELERATION_DEFAULT 1 ++ ++ ++/*-************************************ ++* CPU Feature Detection ++**************************************/ ++/* LZ4_FORCE_MEMORY_ACCESS ++ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. ++ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. ++ * The below switch allow to select different access method for improved performance. ++ * Method 0 (default) : use `memcpy()`. Safe and portable. ++ * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). ++ * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. ++ * Method 2 : direct access. This method is portable but violate C standard. ++ * It can generate buggy code on targets which assembly generation depends on alignment. ++ * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) ++ * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. ++ * Prefer these methods in priority order (0 > 1 > 2) ++ */ ++#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ ++# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) ++# define LZ4_FORCE_MEMORY_ACCESS 2 ++# elif defined(__INTEL_COMPILER) || defined(__GNUC__) ++# define LZ4_FORCE_MEMORY_ACCESS 1 + # endif +-#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) +-# define LZ4_BIG_ENDIAN 1 +-#elif defined(__sparc) || defined(__sparc__) \ +- || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \ +- || defined(__hpux) || defined(__hppa) \ +- || defined(_MIPSEB) || defined(__s390__) +-# define LZ4_BIG_ENDIAN 1 +-#else +-/* Little Endian assumed. PDP Endian and other very rare endian format are unsupported. */ + #endif + + /* +- * Unaligned memory access is automatically enabled for "common" CPU, such as x86. +- * For others CPU, such as ARM, the compiler may be more cautious, inserting unnecessary extra code to ensure aligned access property +- * If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance ++ * LZ4_FORCE_SW_BITCOUNT ++ * Define this parameter if your target system or compiler does not support hardware bit count + */ +-#if defined(__ARM_FEATURE_UNALIGNED) +-# define LZ4_FORCE_UNALIGNED_ACCESS 1 +-#endif +- +-/* Define this parameter if your target system or compiler does not support hardware bit count */ + #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ + # define LZ4_FORCE_SW_BITCOUNT + #endif + +-/* +- * BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE : +- * This option may provide a small boost to performance for some big endian cpu, although probably modest. +- * You may set this option to 1 if data will remain within closed environment. +- * This option is useless on Little_Endian CPU (such as x86) +- */ + +-/* #define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 */ ++/*-************************************ ++* Dependency ++**************************************/ ++#include "lz4.h" ++/* see also "memory routines" below */ + + +-/************************************** +- Compiler Options ++/*-************************************ ++* Compiler Options + **************************************/ +-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +-/* "restrict" is a known keyword */ +-#else +-# define restrict /* Disable restrict */ +-#endif +- + #ifdef _MSC_VER /* Visual Studio */ +-# define FORCE_INLINE static __forceinline +-# include /* For Visual 2005 */ +-# if LZ4_ARCH64 /* 64-bits */ +-# pragma intrinsic(_BitScanForward64) /* For Visual 2005 */ +-# pragma intrinsic(_BitScanReverse64) /* For Visual 2005 */ +-# else /* 32-bits */ +-# pragma intrinsic(_BitScanForward) /* For Visual 2005 */ +-# pragma intrinsic(_BitScanReverse) /* For Visual 2005 */ +-# endif ++# include + # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +-#else +-# ifdef __GNUC__ +-# define FORCE_INLINE static inline __attribute__((always_inline)) +-# else +-# define FORCE_INLINE static inline +-# endif +-#endif +- +-#ifdef _MSC_VER /* Visual Studio */ +-# define lz4_bswap16(x) _byteswap_ushort(x) +-#else +-# define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) +-#endif +- +-#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) ++# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ ++#endif /* _MSC_VER */ + +-#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) ++#ifndef FORCE_INLINE ++# ifdef _MSC_VER /* Visual Studio */ ++# define FORCE_INLINE static __forceinline ++# else ++# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ ++# ifdef __GNUC__ ++# define FORCE_INLINE static inline __attribute__((always_inline)) ++# else ++# define FORCE_INLINE static inline ++# endif ++# else ++# define FORCE_INLINE static ++# endif /* __STDC_VERSION__ */ ++# endif /* _MSC_VER */ ++#endif /* FORCE_INLINE */ ++ ++#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) + # define expect(expr,value) (__builtin_expect ((expr),(value)) ) + #else + # define expect(expr,value) (expr) +@@ -148,8 +127,8 @@ + #define unlikely(expr) expect((expr) != 0, 0) + + +-/************************************** +- Memory routines ++/*-************************************ ++* Memory routines + **************************************/ + #include /* malloc, calloc, free */ + #define ALLOCATOR(n,s) calloc(n,s) +@@ -158,84 +137,146 @@ + #define MEM_INIT memset + + +-/************************************** +- Includes ++/*-************************************ ++* Basic Types + **************************************/ +-#include "lz4.h" +- +- +-/************************************** +- Basic Types +-**************************************/ +-#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ ++#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) + # include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; ++ typedef uintptr_t uptrval; + #else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; ++ typedef size_t uptrval; /* generally true, except OpenVMS-64 */ + #endif + +-#if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS) +-# define _PACKED __attribute__ ((packed)) ++#if defined(__x86_64__) ++ typedef U64 reg_t; /* 64-bits in x32 mode */ + #else +-# define _PACKED ++ typedef size_t reg_t; /* 32-bits in x32 mode */ + #endif + +-#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) +-# if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +-# pragma pack(1) +-# else +-# pragma pack(push, 1) +-# endif +-#endif ++/*-************************************ ++* Reading and writing into memory ++**************************************/ ++static unsigned LZ4_isLittleEndian(void) ++{ ++ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ ++ return one.c[0]; ++} + +-typedef struct { U16 v; } _PACKED U16_S; +-typedef struct { U32 v; } _PACKED U32_S; +-typedef struct { U64 v; } _PACKED U64_S; +-typedef struct {size_t v;} _PACKED size_t_S; + +-#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) +-# if defined(__SUNPRO_C) || defined(__SUNPRO_CC) +-# pragma pack(0) +-# else +-# pragma pack(pop) +-# endif +-#endif ++#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) ++/* lie to the compiler about data alignment; use with caution */ + +-#define A16(x) (((U16_S *)(x))->v) +-#define A32(x) (((U32_S *)(x))->v) +-#define A64(x) (((U64_S *)(x))->v) +-#define AARCH(x) (((size_t_S *)(x))->v) ++static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } ++static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } ++static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } + ++static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } ++static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } + +-/************************************** +- Constants +-**************************************/ +-#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +-#define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) +-#define HASH_SIZE_U32 (1 << LZ4_HASHLOG) ++#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) ++ ++/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ ++/* currently only defined for gcc and icc */ ++typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign; ++ ++static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } ++static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } ++static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; } ++ ++static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } ++static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } ++ ++#else /* safe and portable access through memcpy() */ + ++static U16 LZ4_read16(const void* memPtr) ++{ ++ U16 val; memcpy(&val, memPtr, sizeof(val)); return val; ++} ++ ++static U32 LZ4_read32(const void* memPtr) ++{ ++ U32 val; memcpy(&val, memPtr, sizeof(val)); return val; ++} ++ ++static reg_t LZ4_read_ARCH(const void* memPtr) ++{ ++ reg_t val; memcpy(&val, memPtr, sizeof(val)); return val; ++} ++ ++static void LZ4_write16(void* memPtr, U16 value) ++{ ++ memcpy(memPtr, &value, sizeof(value)); ++} ++ ++static void LZ4_write32(void* memPtr, U32 value) ++{ ++ memcpy(memPtr, &value, sizeof(value)); ++} ++ ++#endif /* LZ4_FORCE_MEMORY_ACCESS */ ++ ++ ++static U16 LZ4_readLE16(const void* memPtr) ++{ ++ if (LZ4_isLittleEndian()) { ++ return LZ4_read16(memPtr); ++ } else { ++ const BYTE* p = (const BYTE*)memPtr; ++ return (U16)((U16)p[0] + (p[1]<<8)); ++ } ++} ++ ++static void LZ4_writeLE16(void* memPtr, U16 value) ++{ ++ if (LZ4_isLittleEndian()) { ++ LZ4_write16(memPtr, value); ++ } else { ++ BYTE* p = (BYTE*)memPtr; ++ p[0] = (BYTE) value; ++ p[1] = (BYTE)(value>>8); ++ } ++} ++ ++static void LZ4_copy8(void* dst, const void* src) ++{ ++ memcpy(dst,src,8); ++} ++ ++/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ ++static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) ++{ ++ BYTE* d = (BYTE*)dstPtr; ++ const BYTE* s = (const BYTE*)srcPtr; ++ BYTE* const e = (BYTE*)dstEnd; ++ ++ do { LZ4_copy8(d,s); d+=8; s+=8; } while (d=2) ++# include ++# define DEBUGLOG(l, ...) { \ ++ if (l<=LZ4_DEBUG) { \ ++ fprintf(stderr, __FILE__ ": "); \ ++ fprintf(stderr, __VA_ARGS__); \ ++ fprintf(stderr, " \n"); \ ++ } } ++#else ++# define DEBUGLOG(l, ...) {} /* disabled */ ++#endif + +-typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; +-typedef enum { byPtr, byU32, byU16 } tableType_t; + +-typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; +-typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; ++/*-************************************ ++* Common functions ++**************************************/ ++static unsigned LZ4_NbCommonBytes (register reg_t val) ++{ ++ if (LZ4_isLittleEndian()) { ++ if (sizeof(val)==8) { ++# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ unsigned long r = 0; ++ _BitScanForward64( &r, (U64)val ); ++ return (int)(r>>3); ++# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ return (__builtin_ctzll((U64)val) >> 3); ++# else ++ static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; ++ return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; ++# endif ++ } else /* 32 bits */ { ++# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ unsigned long r; ++ _BitScanForward( &r, (U32)val ); ++ return (int)(r>>3); ++# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ return (__builtin_ctz((U32)val) >> 3); ++# else ++ static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; ++ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; ++# endif ++ } ++ } else /* Big Endian CPU */ { ++ if (sizeof(val)==8) { ++# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ unsigned long r = 0; ++ _BitScanReverse64( &r, val ); ++ return (unsigned)(r>>3); ++# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ return (__builtin_clzll((U64)val) >> 3); ++# else ++ unsigned r; ++ if (!(val>>32)) { r=4; } else { r=0; val>>=32; } ++ if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } ++ r += (!val); ++ return r; ++# endif ++ } else /* 32 bits */ { ++# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ unsigned long r = 0; ++ _BitScanReverse( &r, (unsigned long)val ); ++ return (unsigned)(r>>3); ++# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) ++ return (__builtin_clz((U32)val) >> 3); ++# else ++ unsigned r; ++ if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } ++ r += (!val); ++ return r; ++# endif ++ } ++ } ++} + +-typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; +-typedef enum { full = 0, partial = 1 } earlyEnd_directive; ++#define STEPSIZE sizeof(reg_t) ++static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) ++{ ++ const BYTE* const pStart = pIn; + ++ while (likely(pIn=e; */ +-#else +-# define LZ4_WILDCOPY(d,s,e) { if (likely(e-d <= 8)) LZ4_COPY8(d,s) else do { LZ4_COPY8(d,s) } while (d compression run slower on incompressible data */ + + +-/**************************** +- Private local functions +-****************************/ +-#if LZ4_ARCH64 ++/*-************************************ ++* Local Structures and types ++**************************************/ ++typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; ++typedef enum { byPtr, byU32, byU16 } tableType_t; + +-int LZ4_NbCommonBytes (register U64 val) +-{ +-# if defined(LZ4_BIG_ENDIAN) +-# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) +- unsigned long r = 0; +- _BitScanReverse64( &r, val ); +- return (int)(r>>3); +-# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) +- return (__builtin_clzll(val) >> 3); +-# else +- int r; +- if (!(val>>32)) { r=4; } else { r=0; val>>=32; } +- if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } +- r += (!val); +- return r; +-# endif +-# else +-# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) +- unsigned long r = 0; +- _BitScanForward64( &r, val ); +- return (int)(r>>3); +-# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) +- return (__builtin_ctzll(val) >> 3); +-# else +- static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; +- return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; +-# endif +-# endif +-} ++typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; ++typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; + +-#else ++typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; ++typedef enum { full = 0, partial = 1 } earlyEnd_directive; + +-int LZ4_NbCommonBytes (register U32 val) +-{ +-# if defined(LZ4_BIG_ENDIAN) +-# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) +- unsigned long r = 0; +- _BitScanReverse( &r, val ); +- return (int)(r>>3); +-# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) +- return (__builtin_clz(val) >> 3); +-# else +- int r; +- if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } +- r += (!val); +- return r; +-# endif +-# else +-# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) +- unsigned long r; +- _BitScanForward( &r, val ); +- return (int)(r>>3); +-# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) +- return (__builtin_ctz(val) >> 3); +-# else +- static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; +- return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; +-# endif +-# endif +-} + +-#endif ++/*-************************************ ++* Local Utils ++**************************************/ ++int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } ++const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; } ++int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } ++int LZ4_sizeofState() { return LZ4_STREAMSIZE; } + + +-/******************************** +- Compression functions ++/*-****************************** ++* Compression functions + ********************************/ +-int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } +- +-static int LZ4_hashSequence(U32 sequence, tableType_t tableType) ++static U32 LZ4_hash4(U32 sequence, tableType_t const tableType) + { + if (tableType == byU16) +- return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); ++ return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + else +- return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); ++ return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); + } + +-static int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); } ++static U32 LZ4_hash5(U64 sequence, tableType_t const tableType) ++{ ++ static const U64 prime5bytes = 889523592379ULL; ++ static const U64 prime8bytes = 11400714785074694791ULL; ++ const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; ++ if (LZ4_isLittleEndian()) ++ return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); ++ else ++ return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); ++} ++ ++FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) ++{ ++ if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); ++ return LZ4_hash4(LZ4_read32(p), tableType); ++} + +-static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) ++static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) + { + switch (tableType) + { +- case byPtr: { const BYTE** hashTable = (const BYTE**) tableBase; hashTable[h] = p; break; } +- case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); break; } +- case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); break; } ++ case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } ++ case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } ++ case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } + } + } + +-static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) ++FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) + { +- U32 h = LZ4_hashPosition(p, tableType); ++ U32 const h = LZ4_hashPosition(p, tableType); + LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); + } + + static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) + { + if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } +- if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } +- { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ ++ if (tableType == byU32) { const U32* const hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } ++ { const U16* const hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ + } + +-static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) ++FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) + { +- U32 h = LZ4_hashPosition(p, tableType); ++ U32 const h = LZ4_hashPosition(p, tableType); + return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); + } + +-static unsigned LZ4_count(const BYTE* pIn, const BYTE* pRef, const BYTE* pInLimit) +-{ +- const BYTE* const pStart = pIn; +- +- while (likely(pIndictSize; +- const BYTE* const dictionary = dictPtr->dictionary; +- const BYTE* const dictEnd = dictionary + dictPtr->dictSize; +- const size_t dictDelta = dictEnd - (const BYTE*)source; ++ const BYTE* const lowRefLimit = ip - cctx->dictSize; ++ const BYTE* const dictionary = cctx->dictionary; ++ const BYTE* const dictEnd = dictionary + cctx->dictSize; ++ const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source; + const BYTE* anchor = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimit = iend - MFLIMIT; +@@ -455,12 +501,10 @@ static int LZ4_compress_generic( + BYTE* op = (BYTE*) dest; + BYTE* const olimit = op + maxOutputSize; + +- const int skipStrength = SKIPSTRENGTH; + U32 forwardH; +- size_t refDelta=0; + + /* Init conditions */ +- if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ ++ if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */ + switch(dict) + { + case noDict: +@@ -469,125 +513,118 @@ static int LZ4_compress_generic( + lowLimit = (const BYTE*)source; + break; + case withPrefix64k: +- base = (const BYTE*)source - dictPtr->currentOffset; +- lowLimit = (const BYTE*)source - dictPtr->dictSize; ++ base = (const BYTE*)source - cctx->currentOffset; ++ lowLimit = (const BYTE*)source - cctx->dictSize; + break; + case usingExtDict: +- base = (const BYTE*)source - dictPtr->currentOffset; ++ base = (const BYTE*)source - cctx->currentOffset; + lowLimit = (const BYTE*)source; + break; + } +- if ((tableType == byU16) && (inputSize>=(int)LZ4_64KLIMIT)) return 0; /* Size too large (not within 64K limit) */ +- if (inputSize=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ ++ if (inputSizehashTable, tableType, base); + ip++; forwardH = LZ4_hashPosition(ip, tableType); + + /* Main Loop */ +- for ( ; ; ) +- { +- const BYTE* ref; ++ for ( ; ; ) { ++ ptrdiff_t refDelta = 0; ++ const BYTE* match; + BYTE* token; +- { +- const BYTE* forwardIp = ip; +- unsigned step=1; +- unsigned searchMatchNb = (1U << skipStrength); + +- /* Find a match */ ++ /* Find a match */ ++ { const BYTE* forwardIp = ip; ++ unsigned step = 1; ++ unsigned searchMatchNb = acceleration << LZ4_skipTrigger; + do { +- U32 h = forwardH; ++ U32 const h = forwardH; + ip = forwardIp; + forwardIp += step; +- step = searchMatchNb++ >> skipStrength; +- //if (step>8) step=8; // required for valid forwardIp ; slows down uncompressible data a bit ++ step = (searchMatchNb++ >> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimit)) goto _last_literals; + +- ref = LZ4_getPositionOnHash(h, ctx, tableType, base); +- if (dict==usingExtDict) +- { +- if (ref<(const BYTE*)source) +- { ++ match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base); ++ if (dict==usingExtDict) { ++ if (match < (const BYTE*)source) { + refDelta = dictDelta; + lowLimit = dictionary; +- } +- else +- { ++ } else { + refDelta = 0; + lowLimit = (const BYTE*)source; +- } +- } ++ } } + forwardH = LZ4_hashPosition(forwardIp, tableType); +- LZ4_putPositionOnHash(ip, h, ctx, tableType, base); ++ LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base); + +- } while ( ((dictIssue==dictSmall) ? (ref < lowRefLimit) : 0) +- || ((tableType==byU16) ? 0 : (ref + MAX_DISTANCE < ip)) +- || (A32(ref+refDelta) != A32(ip)) ); ++ } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) ++ || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) ++ || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) ); + } + + /* Catch up */ +- while ((ip>anchor) && (ref+refDelta > lowLimit) && (unlikely(ip[-1]==ref[refDelta-1]))) { ip--; ref--; } ++ while (((ip>anchor) & (match+refDelta > lowLimit)) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } + +- { +- /* Encode Literal length */ +- unsigned litLength = (unsigned)(ip - anchor); ++ /* Encode Literals */ ++ { unsigned const litLength = (unsigned)(ip - anchor); + token = op++; +- if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) +- return 0; /* Check output limit */ +- if (litLength>=RUN_MASK) +- { ++ if ((outputLimited) && /* Check output buffer overflow */ ++ (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) ++ return 0; ++ if (litLength >= RUN_MASK) { + int len = (int)litLength-RUN_MASK; +- *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; + *op++ = (BYTE)len; + } + else *token = (BYTE)(litLength< matchlimit) limit = matchlimit; +- matchLength = LZ4_count(ip+MINMATCH, ref+MINMATCH, limit); +- ip += MINMATCH + matchLength; +- if (ip==limit) +- { +- unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); +- matchLength += more; ++ matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); ++ ip += MINMATCH + matchCode; ++ if (ip==limit) { ++ unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit); ++ matchCode += more; + ip += more; + } +- } +- else +- { +- matchLength = LZ4_count(ip+MINMATCH, ref+MINMATCH, matchlimit); +- ip += MINMATCH + matchLength; ++ } else { ++ matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); ++ ip += MINMATCH + matchCode; + } + +- if (matchLength>=ML_MASK) +- { +- if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) +- return 0; /* Check output limit */ ++ if ( outputLimited && /* Check output buffer overflow */ ++ (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) ) ++ return 0; ++ if (matchCode >= ML_MASK) { + *token += ML_MASK; +- matchLength -= ML_MASK; +- for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } +- if (matchLength >= 255) { matchLength-=255; *op++ = 255; } +- *op++ = (BYTE)matchLength; +- } +- else *token += (BYTE)(matchLength); ++ matchCode -= ML_MASK; ++ LZ4_write32(op, 0xFFFFFFFF); ++ while (matchCode >= 4*255) { ++ op+=4; ++ LZ4_write32(op, 0xFFFFFFFF); ++ matchCode -= 4*255; ++ } ++ op += matchCode / 255; ++ *op++ = (BYTE)(matchCode % 255); ++ } else ++ *token += (BYTE)(matchCode); + } + + anchor = ip; +@@ -596,27 +633,22 @@ _next_match: + if (ip > mflimit) break; + + /* Fill table */ +- LZ4_putPosition(ip-2, ctx, tableType, base); ++ LZ4_putPosition(ip-2, cctx->hashTable, tableType, base); + + /* Test next position */ +- ref = LZ4_getPosition(ip, ctx, tableType, base); +- if (dict==usingExtDict) +- { +- if (ref<(const BYTE*)source) +- { ++ match = LZ4_getPosition(ip, cctx->hashTable, tableType, base); ++ if (dict==usingExtDict) { ++ if (match < (const BYTE*)source) { + refDelta = dictDelta; + lowLimit = dictionary; +- } +- else +- { ++ } else { + refDelta = 0; + lowLimit = (const BYTE*)source; +- } +- } +- LZ4_putPosition(ip, ctx, tableType, base); +- if ( ((dictIssue==dictSmall) ? (ref>=lowRefLimit) : 1) +- && (ref+MAX_DISTANCE>=ip) +- && (A32(ref+refDelta)==A32(ip)) ) ++ } } ++ LZ4_putPosition(ip, cctx->hashTable, tableType, base); ++ if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) ++ && (match+MAX_DISTANCE>=ip) ++ && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) + { token=op++; *token=0; goto _next_match; } + + /* Prepare next loop */ +@@ -625,14 +657,20 @@ _next_match: + + _last_literals: + /* Encode Last Literals */ +- { +- int lastRun = (int)(iend - anchor); +- if ((outputLimited) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) +- return 0; /* Check output limit */ +- if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } +- else *op++ = (BYTE)(lastRun< (U32)maxOutputSize) ) ++ return 0; ++ if (lastRun >= RUN_MASK) { ++ size_t accumulator = lastRun - RUN_MASK; ++ *op++ = RUN_MASK << ML_BITS; ++ for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; ++ *op++ = (BYTE) accumulator; ++ } else { ++ *op++ = (BYTE)(lastRun<internal_donotuse; ++ LZ4_resetStream((LZ4_stream_t*)state); ++ if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; ++ ++ if (maxOutputSize >= LZ4_compressBound(inputSize)) { ++ if (inputSize < LZ4_64Klimit) ++ return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); ++ else ++ return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); ++ } else { ++ if (inputSize < LZ4_64Klimit) ++ return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); ++ else ++ return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); ++ } ++} ++ ++ ++int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) ++{ ++#if (LZ4_HEAPMODE) ++ void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + #else +- U32 ctx[LZ4_STREAMSIZE_U32] = {0}; /* Ensure data is aligned on 4-bytes boundaries */ ++ LZ4_stream_t ctx; ++ void* const ctxPtr = &ctx; + #endif +- int result; + +- if (inputSize < (int)LZ4_64KLIMIT) +- result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue); +- else +- result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue); ++ int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + +-#if (HEAPMODE) +- FREEMEM(ctx); ++#if (LZ4_HEAPMODE) ++ FREEMEM(ctxPtr); + #endif + return result; + } + +-int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) ++ ++int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize) + { +-#if (HEAPMODE) +- void* ctx = ALLOCATOR(LZ4_STREAMSIZE_U32, 4); /* Aligned on 4-bytes boundaries */ ++ return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1); ++} ++ ++ ++/* hidden debug function */ ++/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ ++int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) ++{ ++ LZ4_stream_t ctx; ++ LZ4_resetStream(&ctx); ++ ++ if (inputSize < LZ4_64Klimit) ++ return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); ++ else ++ return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration); ++} ++ ++ ++/*-****************************** ++* *_destSize() variant ++********************************/ ++ ++static int LZ4_compress_destSize_generic( ++ LZ4_stream_t_internal* const ctx, ++ const char* const src, ++ char* const dst, ++ int* const srcSizePtr, ++ const int targetDstSize, ++ const tableType_t tableType) ++{ ++ const BYTE* ip = (const BYTE*) src; ++ const BYTE* base = (const BYTE*) src; ++ const BYTE* lowLimit = (const BYTE*) src; ++ const BYTE* anchor = ip; ++ const BYTE* const iend = ip + *srcSizePtr; ++ const BYTE* const mflimit = iend - MFLIMIT; ++ const BYTE* const matchlimit = iend - LASTLITERALS; ++ ++ BYTE* op = (BYTE*) dst; ++ BYTE* const oend = op + targetDstSize; ++ BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */; ++ BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */); ++ BYTE* const oMaxSeq = oMaxLit - 1 /* token */; ++ ++ U32 forwardH; ++ ++ ++ /* Init conditions */ ++ if (targetDstSize < 1) return 0; /* Impossible to store anything */ ++ if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ ++ if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ ++ if (*srcSizePtrhashTable, tableType, base); ++ ip++; forwardH = LZ4_hashPosition(ip, tableType); ++ ++ /* Main Loop */ ++ for ( ; ; ) { ++ const BYTE* match; ++ BYTE* token; ++ ++ /* Find a match */ ++ { const BYTE* forwardIp = ip; ++ unsigned step = 1; ++ unsigned searchMatchNb = 1 << LZ4_skipTrigger; ++ ++ do { ++ U32 h = forwardH; ++ ip = forwardIp; ++ forwardIp += step; ++ step = (searchMatchNb++ >> LZ4_skipTrigger); ++ ++ if (unlikely(forwardIp > mflimit)) goto _last_literals; ++ ++ match = LZ4_getPositionOnHash(h, ctx->hashTable, tableType, base); ++ forwardH = LZ4_hashPosition(forwardIp, tableType); ++ LZ4_putPositionOnHash(ip, h, ctx->hashTable, tableType, base); ++ ++ } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) ++ || (LZ4_read32(match) != LZ4_read32(ip)) ); ++ } ++ ++ /* Catch up */ ++ while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } ++ ++ /* Encode Literal length */ ++ { unsigned litLength = (unsigned)(ip - anchor); ++ token = op++; ++ if (op + ((litLength+240)/255) + litLength > oMaxLit) { ++ /* Not enough space for a last match */ ++ op--; ++ goto _last_literals; ++ } ++ if (litLength>=RUN_MASK) { ++ unsigned len = litLength - RUN_MASK; ++ *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; ++ *op++ = (BYTE)len; ++ } ++ else *token = (BYTE)(litLength< oMaxMatch) { ++ /* Match description too long : reduce it */ ++ matchLength = (15-1) + (oMaxMatch-op) * 255; ++ } ++ ip += MINMATCH + matchLength; ++ ++ if (matchLength>=ML_MASK) { ++ *token += ML_MASK; ++ matchLength -= ML_MASK; ++ while (matchLength >= 255) { matchLength-=255; *op++ = 255; } ++ *op++ = (BYTE)matchLength; ++ } ++ else *token += (BYTE)(matchLength); ++ } ++ ++ anchor = ip; ++ ++ /* Test end of block */ ++ if (ip > mflimit) break; ++ if (op > oMaxSeq) break; ++ ++ /* Fill table */ ++ LZ4_putPosition(ip-2, ctx->hashTable, tableType, base); ++ ++ /* Test next position */ ++ match = LZ4_getPosition(ip, ctx->hashTable, tableType, base); ++ LZ4_putPosition(ip, ctx->hashTable, tableType, base); ++ if ( (match+MAX_DISTANCE>=ip) ++ && (LZ4_read32(match)==LZ4_read32(ip)) ) ++ { token=op++; *token=0; goto _next_match; } ++ ++ /* Prepare next loop */ ++ forwardH = LZ4_hashPosition(++ip, tableType); ++ } ++ ++_last_literals: ++ /* Encode Last Literals */ ++ { size_t lastRunSize = (size_t)(iend - anchor); ++ if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) { ++ /* adapt lastRunSize to fill 'dst' */ ++ lastRunSize = (oend-op) - 1; ++ lastRunSize -= (lastRunSize+240)/255; ++ } ++ ip = anchor + lastRunSize; ++ ++ if (lastRunSize >= RUN_MASK) { ++ size_t accumulator = lastRunSize - RUN_MASK; ++ *op++ = RUN_MASK << ML_BITS; ++ for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; ++ *op++ = (BYTE) accumulator; ++ } else { ++ *op++ = (BYTE)(lastRunSize<= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ ++ return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); ++ } else { ++ if (*srcSizePtr < LZ4_64Klimit) ++ return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, byU16); ++ else ++ return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, sizeof(void*)==8 ? byU32 : byPtr); ++ } ++} ++ ++ ++int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) ++{ ++#if (LZ4_HEAPMODE) ++ LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + #else +- U32 ctx[LZ4_STREAMSIZE_U32] = {0}; /* Ensure data is aligned on 4-bytes boundaries */ ++ LZ4_stream_t ctxBody; ++ LZ4_stream_t* ctx = &ctxBody; + #endif +- int result; + +- if (inputSize < (int)LZ4_64KLIMIT) +- result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue); +- else +- result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue); ++ int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); + +-#if (HEAPMODE) ++#if (LZ4_HEAPMODE) + FREEMEM(ctx); + #endif + return result; + } + + +-/***************************************** +- Experimental : Streaming functions +-*****************************************/ + +-void* LZ4_createStream() ++/*-****************************** ++* Streaming functions ++********************************/ ++ ++LZ4_stream_t* LZ4_createStream(void) + { +- void* lz4s = ALLOCATOR(4, LZ4_STREAMSIZE_U32); +- MEM_INIT(lz4s, 0, LZ4_STREAMSIZE); ++ LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64); ++ LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ ++ LZ4_resetStream(lz4s); + return lz4s; + } + +-int LZ4_free (void* LZ4_stream) ++void LZ4_resetStream (LZ4_stream_t* LZ4_stream) ++{ ++ MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); ++} ++ ++int LZ4_freeStream (LZ4_stream_t* LZ4_stream) + { ++ if (!LZ4_stream) return 0; /* support free on NULL */ + FREEMEM(LZ4_stream); + return (0); + } + + +-int LZ4_loadDict (void* LZ4_dict, const char* dictionary, int dictSize) ++#define HASH_UNIT sizeof(reg_t) ++int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) + { +- LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; ++ LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse; + const BYTE* p = (const BYTE*)dictionary; + const BYTE* const dictEnd = p + dictSize; + const BYTE* base; + +- LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ +- if (dict->initCheck) MEM_INIT(dict, 0, sizeof(LZ4_stream_t_internal)); /* Uninitialized structure detected */ ++ if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */ ++ LZ4_resetStream(LZ4_dict); + +- if (dictSize < MINMATCH) +- { ++ if (dictSize < (int)HASH_UNIT) { + dict->dictionary = NULL; + dict->dictSize = 0; +- return 1; ++ return 0; + } + +- if (p <= dictEnd - 64 KB) p = dictEnd - 64 KB; ++ if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; ++ dict->currentOffset += 64 KB; + base = p - dict->currentOffset; + dict->dictionary = p; + dict->dictSize = (U32)(dictEnd - p); + dict->currentOffset += dict->dictSize; + +- while (p <= dictEnd-MINMATCH) +- { +- LZ4_putPosition(p, dict, byU32, base); ++ while (p <= dictEnd-HASH_UNIT) { ++ LZ4_putPosition(p, dict->hashTable, byU32, base); + p+=3; + } + +- return 1; ++ return dict->dictSize; + } + + +-void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) ++static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) + { + if ((LZ4_dict->currentOffset > 0x80000000) || +- ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ +- { ++ ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) { /* address space overflow */ + /* rescale hash table */ +- U32 delta = LZ4_dict->currentOffset - 64 KB; ++ U32 const delta = LZ4_dict->currentOffset - 64 KB; + const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; + int i; +- for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; + else LZ4_dict->hashTable[i] -= delta; + } +@@ -753,22 +1007,20 @@ void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) + } + + +-FORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* source, char* dest, int inputSize, +- int maxOutputSize, limitedOutput_directive limit) ++int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) + { +- LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; ++ LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse; + const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + const BYTE* smallest = (const BYTE*) source; + if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */ + if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd; + LZ4_renormDictT(streamPtr, smallest); ++ if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; + + /* Check overlapping input/dictionary space */ +- { +- const BYTE* sourceEnd = (const BYTE*) source + inputSize; +- if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) +- { ++ { const BYTE* sourceEnd = (const BYTE*) source + inputSize; ++ if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) { + streamPtr->dictSize = (U32)(dictEnd - sourceEnd); + if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; + if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; +@@ -777,25 +1029,23 @@ FORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* so + } + + /* prefix mode : source data follows dictionary */ +- if (dictEnd == (const BYTE*)source) +- { ++ if (dictEnd == (const BYTE*)source) { + int result; + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) +- result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, dictSmall); ++ result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); + else +- result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, noDictIssue); ++ result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); + streamPtr->dictSize += (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + return result; + } + + /* external dictionary mode */ +- { +- int result; ++ { int result; + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) +- result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, dictSmall); ++ result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); + else +- result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, noDictIssue); ++ result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; +@@ -804,29 +1054,18 @@ FORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* so + } + + +-int LZ4_compress_continue (void* LZ4_stream, const char* source, char* dest, int inputSize) +-{ +- return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, 0, notLimited); +-} +- +-int LZ4_compress_limitedOutput_continue (void* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize) +-{ +- return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput); +-} +- +- +-// Hidden debug function, to force separate dictionary mode ++/* Hidden debug function, to force external dictionary mode */ + int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) + { +- LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; ++ LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse; + int result; + const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + const BYTE* smallest = dictEnd; + if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; +- LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); ++ LZ4_renormDictT(streamPtr, smallest); + +- result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue); ++ result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); + + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; +@@ -836,36 +1075,43 @@ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* + } + + +-int LZ4_saveDict (void* LZ4_dict, char* safeBuffer, int dictSize) ++/*! LZ4_saveDict() : ++ * If previously compressed data block is not guaranteed to remain available at its memory location, ++ * save it into a safer place (char* safeBuffer). ++ * Note : you don't need to call LZ4_loadDict() afterwards, ++ * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue(). ++ * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. ++ */ ++int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) + { +- LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; +- const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; ++ LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; ++ const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize; + + if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ + if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; + +- memcpy(safeBuffer, previousDictEnd - dictSize, dictSize); ++ memmove(safeBuffer, previousDictEnd - dictSize, dictSize); + + dict->dictionary = (const BYTE*)safeBuffer; + dict->dictSize = (U32)dictSize; + +- return 1; ++ return dictSize; + } + + + +-/**************************** +- Decompression functions +-****************************/ +-/* +- * This generic decompression function cover all use cases. +- * It shall be instanciated several times, using different sets of directives +- * Note that it is essential this generic function is really inlined, +- * in order to remove useless branches during compilation optimisation. ++/*-***************************** ++* Decompression functions ++*******************************/ ++/*! LZ4_decompress_generic() : ++ * This generic decompression function cover all use cases. ++ * It shall be instantiated several times, using different sets of directives ++ * Note that it is important this generic function is really inlined, ++ * in order to remove useless branches during compilation optimization. + */ + FORCE_INLINE int LZ4_decompress_generic( +- const char* source, +- char* dest, ++ const char* const source, ++ char* const dest, + int inputSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ + +@@ -873,162 +1119,143 @@ FORCE_INLINE int LZ4_decompress_generic( + int partialDecoding, /* full, partial */ + int targetOutputSize, /* only used if partialDecoding==partial */ + int dict, /* noDict, withPrefix64k, usingExtDict */ +- const char* dictStart, /* only if dict==usingExtDict */ +- int dictSize /* note : = 0 if noDict */ ++ const BYTE* const lowPrefix, /* == dest when no prefix */ ++ const BYTE* const dictStart, /* only if dict==usingExtDict */ ++ const size_t dictSize /* note : = 0 if noDict */ + ) + { + /* Local Variables */ +- const BYTE* restrict ip = (const BYTE*) source; +- const BYTE* ref; ++ const BYTE* ip = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + + BYTE* op = (BYTE*) dest; + BYTE* const oend = op + outputSize; + BYTE* cpy; + BYTE* oexit = op + targetOutputSize; +- const BYTE* const lowLimit = (const BYTE*)dest - dictSize; ++ const BYTE* const lowLimit = lowPrefix - dictSize; + + const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; +-//#define OLD +-#ifdef OLD +- const size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; /* static reduces speed for LZ4_decompress_safe() on GCC64 */ +-#else +- const size_t dec32table[] = {4-0, 4-3, 4-2, 4-3, 4-0, 4-0, 4-0, 4-0}; /* static reduces speed for LZ4_decompress_safe() on GCC64 */ +-#endif +- static const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; ++ const unsigned dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; ++ const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3}; + +- const int checkOffset = (endOnInput) && (dictSize < (int)(64 KB)); ++ const int safeDecode = (endOnInput==endOnInputSize); ++ const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); + + + /* Special cases */ +- if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ +- if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ ++ if ((partialDecoding) && (oexit > oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ ++ if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ + if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); + +- +- /* Main Loop */ +- while (1) +- { +- unsigned token; ++ /* Main Loop : decode sequences */ ++ while (1) { + size_t length; ++ const BYTE* match; ++ size_t offset; + +- /* get runlength */ +- token = *ip++; +- if ((length=(token>>ML_BITS)) == RUN_MASK) +- { ++ /* get literal length */ ++ unsigned const token = *ip++; ++ if ((length=(token>>ML_BITS)) == RUN_MASK) { + unsigned s; +- do +- { ++ do { + s = *ip++; + length += s; +- } +- while (likely((endOnInput)?ipLZ4_MAX_INPUT_SIZE)) goto _output_error; /* overflow detection */ +- if ((sizeof(void*)==4) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error; /* quickfix issue 134 */ +- if ((endOnInput) && (sizeof(void*)==4) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error; /* quickfix issue 134 */ ++ } while ( likely(endOnInput ? ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) +- || ((!endOnInput) && (cpy>oend-COPYLENGTH))) ++ if ( ((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) ++ || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) ) + { +- if (partialDecoding) +- { ++ if (partialDecoding) { + if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ + if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ +- } +- else +- { ++ } else { + if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ + if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ + } + memcpy(op, ip, length); + ip += length; + op += length; +- break; /* Necessarily EOF, due to parsing restrictions */ ++ break; /* Necessarily EOF, due to parsing restrictions */ + } +- LZ4_WILDCOPY(op, ip, cpy); ip -= (op-cpy); op = cpy; ++ LZ4_wildCopy(op, ip, cpy); ++ ip += length; op = cpy; + + /* get offset */ +- LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2; +- if ((checkOffset) && (unlikely(ref < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ ++ offset = LZ4_readLE16(ip); ip+=2; ++ match = op - offset; ++ if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside buffers */ ++ LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ + + /* get matchlength */ +- if ((length=(token&ML_MASK)) == ML_MASK) +- { ++ length = token & ML_MASK; ++ if (length == ML_MASK) { + unsigned s; +- do +- { +- if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; ++ do { + s = *ip++; ++ if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; + length += s; + } while (s==255); +- //if ((sizeof(void*)==4) && unlikely(length>LZ4_MAX_INPUT_SIZE)) goto _output_error; /* overflow detection */ +- if ((sizeof(void*)==4) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* quickfix issue 134 */ ++ if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ + } ++ length += MINMATCH; + + /* check external dictionary */ +- if ((dict==usingExtDict) && (ref < (BYTE* const)dest)) +- { +- if (unlikely(op+length+MINMATCH > oend-LASTLITERALS)) goto _output_error; +- +- if (length+MINMATCH <= (size_t)(dest-(char*)ref)) +- { +- ref = dictEnd - (dest-(char*)ref); +- memcpy(op, ref, length+MINMATCH); +- op += length+MINMATCH; +- } +- else +- { +- size_t copySize = (size_t)(dest-(char*)ref); ++ if ((dict==usingExtDict) && (match < lowPrefix)) { ++ if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ ++ ++ if (length <= (size_t)(lowPrefix-match)) { ++ /* match can be copied as a single segment from external dictionary */ ++ memmove(op, dictEnd - (lowPrefix-match), length); ++ op += length; ++ } else { ++ /* match encompass external dictionary and current block */ ++ size_t const copySize = (size_t)(lowPrefix-match); ++ size_t const restSize = length - copySize; + memcpy(op, dictEnd - copySize, copySize); + op += copySize; +- copySize = length+MINMATCH - copySize; +- if (copySize > (size_t)((char*)op-dest)) /* overlap */ +- { +- BYTE* const cpy = op + copySize; +- const BYTE* ref = (BYTE*)dest; +- while (op < cpy) *op++ = *ref++; +- } +- else +- { +- memcpy(op, dest, copySize); +- op += copySize; +- } +- } ++ if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */ ++ BYTE* const endOfMatch = op + restSize; ++ const BYTE* copyFrom = lowPrefix; ++ while (op < endOfMatch) *op++ = *copyFrom++; ++ } else { ++ memcpy(op, lowPrefix, restSize); ++ op += restSize; ++ } } + continue; + } + +- /* copy repeated sequence */ +- if (unlikely((op-ref)<(int)STEPSIZE)) +- { +- const size_t dec64 = dec64table[(sizeof(void*)==4) ? 0 : op-ref]; +- op[0] = ref[0]; +- op[1] = ref[1]; +- op[2] = ref[2]; +- op[3] = ref[3]; +-#ifdef OLD +- op += 4, ref += 4; ref -= dec32table[op-ref]; +- A32(op) = A32(ref); +- op += STEPSIZE-4; ref -= dec64; +-#else +- ref += dec32table[op-ref]; +- A32(op+4) = A32(ref); +- op += STEPSIZE; ref -= dec64; +-#endif +- } else { LZ4_COPYSTEP(op,ref); } +- cpy = op + length - (STEPSIZE-4); +- +- if (unlikely(cpy>oend-COPYLENGTH-(STEPSIZE-4))) +- { +- if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last 5 bytes must be literals */ +- if (opoend-12)) { ++ BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1); ++ if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ ++ if (op < oCopyLimit) { ++ LZ4_wildCopy(op, match, oCopyLimit); ++ match += oCopyLimit - op; ++ op = oCopyLimit; ++ } ++ while (op16) LZ4_wildCopy(op+8, match+8, cpy); + } +- LZ4_WILDCOPY(op, ref, cpy); + op=cpy; /* correction */ + } + +@@ -1036,64 +1263,59 @@ FORCE_INLINE int LZ4_decompress_generic( + if (endOnInput) + return (int) (((char*)op)-dest); /* Nb of output bytes decoded */ + else +- return (int) (((char*)ip)-source); /* Nb of input bytes read */ ++ return (int) (((const char*)ip)-source); /* Nb of input bytes read */ + + /* Overflow error detected */ + _output_error: +- return (int) (-(((char*)ip)-source))-1; ++ return (int) (-(((const char*)ip)-source))-1; + } + + +-int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxOutputSize) ++int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) + { +- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, noDict, NULL, 0); ++ return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0); + } + +-int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxOutputSize) ++int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize) + { +- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, partial, targetOutputSize, noDict, NULL, 0); ++ return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0); + } + + int LZ4_decompress_fast(const char* source, char* dest, int originalSize) + { +- return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, NULL, 0); ++ return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB); + } + +-/* streaming decompression functions */ + +-//#define LZ4_STREAMDECODESIZE_U32 4 +-//#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U32 * sizeof(unsigned int)) +-//typedef struct { unsigned int table[LZ4_STREAMDECODESIZE_U32]; } LZ4_streamDecode_t; +-typedef struct +-{ +- const char* dictionary; +- int dictSize; +-} LZ4_streamDecode_t_internal; ++/*===== streaming decompression functions =====*/ + +-/* +- * If you prefer dynamic allocation methods, +- * LZ4_createStreamDecode() +- * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure. +- */ +-void* LZ4_createStreamDecode() ++LZ4_streamDecode_t* LZ4_createStreamDecode(void) + { +- void* lz4s = ALLOCATOR(sizeof(U32), LZ4_STREAMDECODESIZE_U32); +- MEM_INIT(lz4s, 0, LZ4_STREAMDECODESIZE); ++ LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t)); + return lz4s; + } + +-/* +- * LZ4_setDictDecode +- * Use this function to instruct where to find the dictionary ++int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) ++{ ++ if (!LZ4_stream) return 0; /* support free on NULL */ ++ FREEMEM(LZ4_stream); ++ return 0; ++} ++ ++/*! ++ * LZ4_setStreamDecode() : ++ * Use this function to instruct where to find the dictionary. + * This function is not necessary if previous data is still available where it was decoded. + * Loading a size of 0 is allowed (same effect as no dictionary). + * Return : 1 if OK, 0 if error + */ +-int LZ4_setDictDecode (void* LZ4_streamDecode, const char* dictionary, int dictSize) ++int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) + { +- LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; +- lz4sd->dictionary = dictionary; +- lz4sd->dictSize = dictSize; ++ LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; ++ lz4sd->prefixSize = (size_t) dictSize; ++ lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; ++ lz4sd->externalDict = NULL; ++ lz4sd->extDictSize = 0; + return 1; + } + +@@ -1102,43 +1324,55 @@ int LZ4_setDictDecode (void* LZ4_streamDecode, const char* dictionary, int dictS + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks must still be available at the memory position where they were decoded. + If it's not possible, save the relevant part of decoded data into a safe buffer, +- and indicate where it stands using LZ4_setDictDecode() ++ and indicate where it stands using LZ4_setStreamDecode() + */ +-int LZ4_decompress_safe_continue (void* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) ++int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) + { +- LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; ++ LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; + int result; + +- result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, lz4sd->dictionary, lz4sd->dictSize); +- if (result <= 0) return result; +- if (lz4sd->dictionary + lz4sd->dictSize == dest) +- { +- lz4sd->dictSize += result; +- } +- else +- { +- lz4sd->dictionary = dest; +- lz4sd->dictSize = result; ++ if (lz4sd->prefixEnd == (BYTE*)dest) { ++ result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, ++ endOnInputSize, full, 0, ++ usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); ++ if (result <= 0) return result; ++ lz4sd->prefixSize += result; ++ lz4sd->prefixEnd += result; ++ } else { ++ lz4sd->extDictSize = lz4sd->prefixSize; ++ lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; ++ result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, ++ endOnInputSize, full, 0, ++ usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); ++ if (result <= 0) return result; ++ lz4sd->prefixSize = result; ++ lz4sd->prefixEnd = (BYTE*)dest + result; + } + + return result; + } + +-int LZ4_decompress_fast_continue (void* LZ4_streamDecode, const char* source, char* dest, int originalSize) ++int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) + { +- LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; ++ LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; + int result; + +- result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, lz4sd->dictionary, lz4sd->dictSize); +- if (result <= 0) return result; +- if (lz4sd->dictionary + lz4sd->dictSize == dest) +- { +- lz4sd->dictSize += result; +- } +- else +- { +- lz4sd->dictionary = dest; +- lz4sd->dictSize = result; ++ if (lz4sd->prefixEnd == (BYTE*)dest) { ++ result = LZ4_decompress_generic(source, dest, 0, originalSize, ++ endOnOutputSize, full, 0, ++ usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); ++ if (result <= 0) return result; ++ lz4sd->prefixSize += originalSize; ++ lz4sd->prefixEnd += originalSize; ++ } else { ++ lz4sd->extDictSize = lz4sd->prefixSize; ++ lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; ++ result = LZ4_decompress_generic(source, dest, 0, originalSize, ++ endOnOutputSize, full, 0, ++ usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); ++ if (result <= 0) return result; ++ lz4sd->prefixSize = originalSize; ++ lz4sd->prefixEnd = (BYTE*)dest + originalSize; + } + + return result; +@@ -1152,12 +1386,97 @@ Advanced decoding functions : + the dictionary must be explicitly provided within parameters + */ + ++FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) ++{ ++ if (dictSize==0) ++ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); ++ if (dictStart+dictSize == dest) { ++ if (dictSize >= (int)(64 KB - 1)) ++ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); ++ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); ++ } ++ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); ++} ++ + int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) + { +- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, dictStart, dictSize); ++ return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize); + } + + int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) + { +- return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, dictStart, dictSize); ++ return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); ++} ++ ++/* debug function */ ++int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) ++{ ++ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); + } ++ ++ ++/*=************************************************* ++* Obsolete Functions ++***************************************************/ ++/* obsolete compression functions */ ++int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); } ++int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); } ++int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); } ++int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); } ++int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); } ++int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); } ++ ++/* ++These function names are deprecated and should no longer be used. ++They are only provided here for compatibility with older user programs. ++- LZ4_uncompress is totally equivalent to LZ4_decompress_fast ++- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe ++*/ ++int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } ++int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } ++ ++ ++/* Obsolete Streaming functions */ ++ ++int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } ++ ++static void LZ4_init(LZ4_stream_t* lz4ds, BYTE* base) ++{ ++ MEM_INIT(lz4ds, 0, sizeof(LZ4_stream_t)); ++ lz4ds->internal_donotuse.bufferStart = base; ++} ++ ++int LZ4_resetStreamState(void* state, char* inputBuffer) ++{ ++ if ((((uptrval)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ ++ LZ4_init((LZ4_stream_t*)state, (BYTE*)inputBuffer); ++ return 0; ++} ++ ++void* LZ4_create (char* inputBuffer) ++{ ++ LZ4_stream_t* lz4ds = (LZ4_stream_t*)ALLOCATOR(8, sizeof(LZ4_stream_t)); ++ LZ4_init (lz4ds, (BYTE*)inputBuffer); ++ return lz4ds; ++} ++ ++char* LZ4_slideInputBuffer (void* LZ4_Data) ++{ ++ LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)LZ4_Data)->internal_donotuse; ++ int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB); ++ return (char*)(ctx->bufferStart + dictSize); ++} ++ ++/* Obsolete streaming decompression functions */ ++ ++int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) ++{ ++ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); ++} ++ ++int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) ++{ ++ return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); ++} ++ ++#endif /* LZ4_COMMONDEFS_ONLY */ +diff --git mfbt/lz4.h mfbt/lz4.h +index bf6780122f6f..86ca0d59c1f4 100644 +--- mfbt/lz4.h ++++ mfbt/lz4.h +@@ -1,7 +1,8 @@ + /* +- LZ4 - Fast LZ compression algorithm +- Header File +- Copyright (C) 2011-2014, Yann Collet. ++ * LZ4 - Fast LZ compression algorithm ++ * Header File ++ * Copyright (C) 2011-2017, Yann Collet. ++ + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without +@@ -28,247 +29,433 @@ + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : +- - LZ4 source repository : http://code.google.com/p/lz4/ +- - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c ++ - LZ4 homepage : http://www.lz4.org ++ - LZ4 source repository : https://github.com/lz4/lz4 + */ +-#pragma once +- + #if defined (__cplusplus) + extern "C" { + #endif + ++#ifndef LZ4_H_2983827168210 ++#define LZ4_H_2983827168210 + +-/************************************** +- Version +-**************************************/ +-#define LZ4_VERSION_MAJOR 1 /* for major interface/format changes */ +-#define LZ4_VERSION_MINOR 2 /* for minor interface/format changes */ ++/* --- Dependency --- */ ++#include /* size_t */ ++ ++ ++/** ++ Introduction ++ ++ LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core, ++ scalable with multi-cores CPU. It features an extremely fast decoder, with speed in ++ multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. ++ ++ The LZ4 compression library provides in-memory compression and decompression functions. ++ Compression can be done in: ++ - a single step (described as Simple Functions) ++ - a single step, reusing a context (described in Advanced Functions) ++ - unbounded multiple steps (described as Streaming compression) ++ ++ lz4.h provides block compression functions. It gives full buffer control to user. ++ Decompressing an lz4-compressed block also requires metadata (such as compressed size). ++ Each application is free to encode such metadata in whichever way it wants. ++ ++ An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md), ++ take care of encoding standard metadata alongside LZ4-compressed blocks. ++ If your application requires interoperability, it's recommended to use it. ++ A library is provided to take care of it, see lz4frame.h. ++*/ ++ ++/*^*************************************************************** ++* Export parameters ++*****************************************************************/ ++/* ++* LZ4_DLL_EXPORT : ++* Enable exporting of functions when building a Windows DLL ++* LZ4LIB_API : ++* Control library symbols visibility. ++*/ ++#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) ++# define LZ4LIB_API __declspec(dllexport) ++#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) ++# define LZ4LIB_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ ++#elif defined(__GNUC__) && (__GNUC__ >= 4) ++# define LZ4LIB_API __attribute__ ((__visibility__ ("default"))) ++#else ++# define LZ4LIB_API ++#endif ++ ++ ++/*------ Version ------*/ ++#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ ++#define LZ4_VERSION_MINOR 8 /* for new (non-breaking) interface capabilities */ + #define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ + ++#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) + +-/************************************** +- Tuning parameter ++#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE ++#define LZ4_QUOTE(str) #str ++#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) ++#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) ++ ++LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; to be used when checking dll version */ ++LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; to be used when checking dll version */ ++ ++ ++/*-************************************ ++* Tuning parameter + **************************************/ +-/* ++/*! + * LZ4_MEMORY_USAGE : + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) + * Increasing memory usage improves compression ratio + * Reduced memory usage can improve speed, due to cache effect + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + */ +-#define LZ4_MEMORY_USAGE 14 +- ++#ifndef LZ4_MEMORY_USAGE ++# define LZ4_MEMORY_USAGE 14 ++#endif + +-/************************************** +- Simple Functions ++/*-************************************ ++* Simple Functions + **************************************/ +- +-int LZ4_compress (const char* source, char* dest, int inputSize); +-int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxOutputSize); +- +-/* +-LZ4_compress() : +- Compresses 'inputSize' bytes from 'source' into 'dest'. +- Destination buffer must be already allocated, +- and must be sized to handle worst cases situations (input data not compressible) +- Worst case size evaluation is provided by function LZ4_compressBound() +- inputSize : Max supported value is LZ4_MAX_INPUT_VALUE +- return : the number of bytes written in buffer dest +- or 0 if the compression fails +- +-LZ4_decompress_safe() : +- compressedSize : is obviously the source size +- maxOutputSize : is the size of the destination buffer, which must be already allocated. +- return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) +- If the destination buffer is not large enough, decoding will stop and output an error code (<0). ++/*! LZ4_compress_default() : ++ Compresses 'sourceSize' bytes from buffer 'source' ++ into already allocated 'dest' buffer of size 'maxDestSize'. ++ Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize). ++ It also runs faster, so it's a recommended setting. ++ If the function cannot compress 'source' into a more limited 'dest' budget, ++ compression stops *immediately*, and the function result is zero. ++ As a consequence, 'dest' content is not valid. ++ This function never writes outside 'dest' buffer, nor read outside 'source' buffer. ++ sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE ++ maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) ++ return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) ++ or 0 if compression fails */ ++LZ4LIB_API int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); ++ ++/*! LZ4_decompress_safe() : ++ compressedSize : is the precise full size of the compressed block. ++ maxDecompressedSize : is the size of destination buffer, which must be already allocated. ++ return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) ++ If destination buffer is not large enough, decoding will stop and output an error code (<0). + If the source stream is detected malformed, the function will stop decoding and return a negative result. +- This function is protected against buffer overflow exploits : +- it never writes outside of output buffer, and never reads outside of input buffer. +- Therefore, it is protected against malicious data packets. +-*/ +- +- +-/* +-Note : +- Should you prefer to explicitly allocate compression-table memory using your own allocation method, +- use the streaming functions provided below, simply reset the memory area between each call to LZ4_compress_continue() ++ This function is protected against buffer overflow exploits, including malicious data packets. ++ It never writes outside output buffer, nor reads outside input buffer. + */ ++LZ4LIB_API int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); + + +-/************************************** +- Advanced Functions ++/*-************************************ ++* Advanced Functions + **************************************/ + #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +-#define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) ++#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +-/* ++/*! + LZ4_compressBound() : +- Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible) +- primarily useful for memory allocation of output buffer. +- macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation). +- +- isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE +- return : maximum output size in a "worst case" scenario +- or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) ++ Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) ++ This function is primarily useful for memory allocation purposes (destination buffer size). ++ Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). ++ Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize) ++ inputSize : max supported value is LZ4_MAX_INPUT_SIZE ++ return : maximum output size in a "worst case" scenario ++ or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) ++*/ ++LZ4LIB_API int LZ4_compressBound(int inputSize); ++ ++/*! ++LZ4_compress_fast() : ++ Same as LZ4_compress_default(), but allows to select an "acceleration" factor. ++ The larger the acceleration value, the faster the algorithm, but also the lesser the compression. ++ It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. ++ An acceleration value of "1" is the same as regular LZ4_compress_default() ++ Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. + */ +-int LZ4_compressBound(int isize); ++LZ4LIB_API int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); + + +-/* +-LZ4_compress_limitedOutput() : +- Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. +- If it cannot achieve it, compression will stop, and result of the function will be zero. +- This function never writes outside of provided output buffer. +- +- inputSize : Max supported value is LZ4_MAX_INPUT_VALUE +- maxOutputSize : is the size of the destination buffer (which must be already allocated) +- return : the number of bytes written in buffer 'dest' +- or 0 if the compression fails ++/*! ++LZ4_compress_fast_extState() : ++ Same compression function, just using an externally allocated memory space to store compression state. ++ Use LZ4_sizeofState() to know how much memory must be allocated, ++ and allocate it on 8-bytes boundaries (using malloc() typically). ++ Then, provide it as 'void* state' to compression function. ++*/ ++LZ4LIB_API int LZ4_sizeofState(void); ++LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); ++ ++ ++/*! ++LZ4_compress_destSize() : ++ Reverse the logic, by compressing as much data as possible from 'source' buffer ++ into already allocated buffer 'dest' of size 'targetDestSize'. ++ This function either compresses the entire 'source' content into 'dest' if it's large enough, ++ or fill 'dest' buffer completely with as much data as possible from 'source'. ++ *sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'. ++ New value is necessarily <= old value. ++ return : Nb bytes written into 'dest' (necessarily <= targetDestSize) ++ or 0 if compression fails + */ +-int LZ4_compress_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); ++LZ4LIB_API int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); + + +-/* ++/*! + LZ4_decompress_fast() : + originalSize : is the original and therefore uncompressed size + return : the number of bytes read from the source buffer (in other words, the compressed size) +- If the source stream is malformed, the function will stop decoding and return a negative result. ++ If the source stream is detected malformed, the function will stop decoding and return a negative result. + Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. +- note : This function is a bit faster than LZ4_decompress_safe() +- It provides fast decompression and fully respect memory boundaries for properly formed compressed data. +- It does not provide full protection against intentionnally modified data stream. +- Use this function in a trusted environment (data to decode comes from a trusted source). ++ note : This function fully respect memory boundaries for properly formed compressed data. ++ It is a bit faster than LZ4_decompress_safe(). ++ However, it does not provide any protection against intentionally modified data stream (malicious input). ++ Use this function in trusted environment only (data to decode comes from a trusted source). + */ +-int LZ4_decompress_fast (const char* source, char* dest, int originalSize); ++LZ4LIB_API int LZ4_decompress_fast (const char* source, char* dest, int originalSize); + +- +-/* ++/*! + LZ4_decompress_safe_partial() : + This function decompress a compressed block of size 'compressedSize' at position 'source' +- into output buffer 'dest' of size 'maxOutputSize'. ++ into destination buffer 'dest' of size 'maxDecompressedSize'. + The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, + reducing decompression time. +- return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) ++ return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) + Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. + Always control how many bytes were decoded. + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets + */ +-int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxOutputSize); ++LZ4LIB_API int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); + + +-/*********************************************** +- Experimental Streaming Compression Functions ++/*-********************************************* ++* Streaming Compression Functions + ***********************************************/ ++typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ + +-#define LZ4_STREAMSIZE_U32 ((1 << (LZ4_MEMORY_USAGE-2)) + 8) +-#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U32 * sizeof(unsigned int)) +-/* +- * LZ4_stream_t +- * information structure to track an LZ4 stream. +- * important : set this structure content to zero before first use ! +- */ +-typedef struct { unsigned int table[LZ4_STREAMSIZE_U32]; } LZ4_stream_t; +- +-/* +- * If you prefer dynamic allocation methods, +- * LZ4_createStream +- * provides a pointer (void*) towards an initialized LZ4_stream_t structure. +- * LZ4_free just frees it. ++/*! LZ4_createStream() and LZ4_freeStream() : ++ * LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure. ++ * LZ4_freeStream() releases its memory. + */ +-void* LZ4_createStream(); +-int LZ4_free (void* LZ4_stream); +- ++LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); ++LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); + +-/* +- * LZ4_loadDict +- * Use this function to load a static dictionary into LZ4_stream. +- * Any previous data will be forgotten, only 'dictionary' will remain in memory. +- * Loading a size of 0 is allowed (same effect as init). +- * Return : 1 if OK, 0 if error ++/*! LZ4_resetStream() : ++ * An LZ4_stream_t structure can be allocated once and re-used multiple times. ++ * Use this function to init an allocated `LZ4_stream_t` structure and start a new compression. + */ +-int LZ4_loadDict (void* LZ4_stream, const char* dictionary, int dictSize); ++LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); + +-/* +- * LZ4_compress_continue +- * Compress data block 'source', using blocks compressed before as dictionary to improve compression ratio +- * Previous data blocks are assumed to still be present at their previous location. ++/*! LZ4_loadDict() : ++ * Use this function to load a static dictionary into LZ4_stream. ++ * Any previous data will be forgotten, only 'dictionary' will remain in memory. ++ * Loading a size of 0 is allowed. ++ * Return : dictionary size, in bytes (necessarily <= 64 KB) + */ +-int LZ4_compress_continue (void* LZ4_stream, const char* source, char* dest, int inputSize); +- +-/* +- * LZ4_compress_limitedOutput_continue +- * Same as before, but also specify a maximum target compressed size (maxOutputSize) +- * If objective cannot be met, compression exits, and returns a zero. ++LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); ++ ++/*! LZ4_compress_fast_continue() : ++ * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. ++ * Important : Previous data blocks are assumed to remain present and unmodified ! ++ * 'dst' buffer must be already allocated. ++ * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. ++ * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function @return==0. ++ * After an error, the stream status is invalid, it can only be reset or freed. + */ +-int LZ4_compress_limitedOutput_continue (void* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize); ++LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + +-/* +- * LZ4_saveDict +- * If previously compressed data block is not guaranteed to remain at its previous memory location +- * save it into a safe place (char* safeBuffer) +- * Note : you don't need to call LZ4_loadDict() afterwards, +- * dictionary is immediately usable, you can therefore call again LZ4_compress_continue() +- * Return : 1 if OK, 0 if error +- * Note : any dictSize > 64 KB will be interpreted as 64KB. ++/*! LZ4_saveDict() : ++ * If previously compressed data block is not guaranteed to remain available at its current memory location, ++ * save it into a safer place (char* safeBuffer). ++ * Note : it's not necessary to call LZ4_loadDict() after LZ4_saveDict(), dictionary is immediately usable. ++ * @return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. + */ +-int LZ4_saveDict (void* LZ4_stream, char* safeBuffer, int dictSize); ++LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); + + +-/************************************************ +- Experimental Streaming Decompression Functions ++/*-********************************************** ++* Streaming Decompression Functions ++* Bufferless synchronous API + ************************************************/ ++typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */ + +-#define LZ4_STREAMDECODESIZE_U32 4 +-#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U32 * sizeof(unsigned int)) +-/* +- * LZ4_streamDecode_t +- * information structure to track an LZ4 stream. +- * important : set this structure content to zero before first use ! ++/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : ++ * creation / destruction of streaming decompression tracking structure */ ++LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); ++LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); ++ ++/*! LZ4_setStreamDecode() : ++ * Use this function to instruct where to find the dictionary. ++ * Setting a size of 0 is allowed (same effect as reset). ++ * @return : 1 if OK, 0 if error + */ +-typedef struct { unsigned int table[LZ4_STREAMDECODESIZE_U32]; } LZ4_streamDecode_t; ++LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); ++ ++/*! LZ4_decompress_*_continue() : ++ * These decoding functions allow decompression of multiple blocks in "streaming" mode. ++ * Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) ++ * In the case of a ring buffers, decoding buffer must be either : ++ * - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions) ++ * In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB). ++ * - Larger than encoding buffer, by a minimum of maxBlockSize more bytes. ++ * maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block. ++ * In which case, encoding and decoding buffers do not need to be synchronized, ++ * and encoding ring buffer can have any size, including small ones ( < 64 KB). ++ * - _At least_ 64 KB + 8 bytes + maxBlockSize. ++ * In which case, encoding and decoding buffers do not need to be synchronized, ++ * and encoding ring buffer can have any size, including larger than decoding buffer. ++ * Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, ++ * and indicate where it is saved using LZ4_setStreamDecode() ++*/ ++LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); ++LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); + +-/* +- * If you prefer dynamic allocation methods, +- * LZ4_createStreamDecode() +- * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure. +- * LZ4_free just frees it. ++ ++/*! LZ4_decompress_*_usingDict() : ++ * These decoding functions work the same as ++ * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue() ++ * They are stand-alone, and don't need an LZ4_streamDecode_t structure. + */ +-void* LZ4_createStreamDecode(); +-int LZ4_free (void* LZ4_stream); /* yes, it's the same one as for compression */ ++LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); ++LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); ++ ++ ++/*^********************************************** ++ * !!!!!! STATIC LINKING ONLY !!!!!! ++ ***********************************************/ ++/*-************************************ ++ * Private definitions ++ ************************************** ++ * Do not use these definitions. ++ * They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. ++ * Using these definitions will expose code to API and/or ABI break in future versions of the library. ++ **************************************/ ++#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) ++#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) ++#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ ++ ++#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ++#include ++ ++typedef struct { ++ uint32_t hashTable[LZ4_HASH_SIZE_U32]; ++ uint32_t currentOffset; ++ uint32_t initCheck; ++ const uint8_t* dictionary; ++ uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */ ++ uint32_t dictSize; ++} LZ4_stream_t_internal; ++ ++typedef struct { ++ const uint8_t* externalDict; ++ size_t extDictSize; ++ const uint8_t* prefixEnd; ++ size_t prefixSize; ++} LZ4_streamDecode_t_internal; ++ ++#else ++ ++typedef struct { ++ unsigned int hashTable[LZ4_HASH_SIZE_U32]; ++ unsigned int currentOffset; ++ unsigned int initCheck; ++ const unsigned char* dictionary; ++ unsigned char* bufferStart; /* obsolete, used for slideInputBuffer */ ++ unsigned int dictSize; ++} LZ4_stream_t_internal; ++ ++typedef struct { ++ const unsigned char* externalDict; ++ size_t extDictSize; ++ const unsigned char* prefixEnd; ++ size_t prefixSize; ++} LZ4_streamDecode_t_internal; + +-/* +-*_continue() : +- These decoding functions allow decompression of multiple blocks in "streaming" mode. +- Previously decoded blocks must still be available at the memory position where they were decoded. +- If it's not possible, save the relevant part of decoded data into a safe buffer, +- and indicate where it stands using LZ4_setDictDecode() +-*/ +-int LZ4_decompress_safe_continue (void* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize); +-int LZ4_decompress_fast_continue (void* LZ4_streamDecode, const char* source, char* dest, int originalSize); ++#endif + +-/* +- * LZ4_setDictDecode +- * Use this function to instruct where to find the dictionary. +- * This function can be used to specify a static dictionary, +- * or to instruct where to find some previously decoded data saved into a different memory space. +- * Setting a size of 0 is allowed (same effect as no dictionary). +- * Return : 1 if OK, 0 if error ++/*! ++ * LZ4_stream_t : ++ * information structure to track an LZ4 stream. ++ * init this structure before first use. ++ * note : only use in association with static linking ! ++ * this definition is not API/ABI safe, ++ * it may change in a future version ! + */ +-int LZ4_setDictDecode (void* LZ4_streamDecode, const char* dictionary, int dictSize); ++#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) ++#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) ++union LZ4_stream_u { ++ unsigned long long table[LZ4_STREAMSIZE_U64]; ++ LZ4_stream_t_internal internal_donotuse; ++} ; /* previously typedef'd to LZ4_stream_t */ ++ ++ ++/*! ++ * LZ4_streamDecode_t : ++ * information structure to track an LZ4 stream during decompression. ++ * init this structure using LZ4_setStreamDecode (or memset()) before first use ++ * note : only use in association with static linking ! ++ * this definition is not API/ABI safe, ++ * and may change in a future version ! ++ */ ++#define LZ4_STREAMDECODESIZE_U64 4 ++#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) ++union LZ4_streamDecode_u { ++ unsigned long long table[LZ4_STREAMDECODESIZE_U64]; ++ LZ4_streamDecode_t_internal internal_donotuse; ++} ; /* previously typedef'd to LZ4_streamDecode_t */ + + +-/* +-Advanced decoding functions : +-*_usingDict() : +- These decoding functions work the same as +- a combination of LZ4_setDictDecode() followed by LZ4_decompress_x_continue() +- all together into a single function call. +- It doesn't use nor update an LZ4_streamDecode_t structure. +-*/ +-int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize); +-int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); ++/*-************************************ ++* Obsolete Functions ++**************************************/ + ++/*! Deprecation warnings ++ Should deprecation warnings be a problem, ++ it is generally possible to disable them, ++ typically with -Wno-deprecated-declarations for gcc ++ or _CRT_SECURE_NO_WARNINGS in Visual. ++ Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */ ++#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS ++# define LZ4_DEPRECATED(message) /* disable deprecation warnings */ ++#else ++# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) ++# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ ++# define LZ4_DEPRECATED(message) [[deprecated(message)]] ++# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__) ++# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) ++# elif (LZ4_GCC_VERSION >= 301) ++# define LZ4_DEPRECATED(message) __attribute__((deprecated)) ++# elif defined(_MSC_VER) ++# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) ++# else ++# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") ++# define LZ4_DEPRECATED(message) ++# endif ++#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ ++ ++/* Obsolete compression functions */ ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress (const char* source, char* dest, int sourceSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); ++ ++/* Obsolete decompression functions */ ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_fast() instead") int LZ4_uncompress (const char* source, char* dest, int outputSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_safe() instead") int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); ++ ++/* Obsolete streaming functions; use new streaming interface whenever possible */ ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state); ++ ++/* Obsolete streaming decoding functions */ ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); ++LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); ++ ++#endif /* LZ4_H_2983827168210 */ + + + #if defined (__cplusplus) Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1398021 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1399412 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1399412 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1399412 (revision 462640) @@ -0,0 +1,31 @@ +commit f2d86a8b3050 +Author: Dimitry Andric +Date: Wed Sep 13 09:43:00 2017 -0400 + + Bug 1399412 - Work around clang assertion by wrapping lz4.c in an extern C block. r=froydnj + + MozReview-Commit-ID: LLgSbJadbyJ + + --HG-- + extra : amend_source : 08d7908fe6807db654411fc291bccc98496d4275 +--- + mfbt/Compression.cpp | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git mfbt/Compression.cpp mfbt/Compression.cpp +index 0a94cc69e224..c675aa90af62 100644 +--- mfbt/Compression.cpp ++++ mfbt/Compression.cpp +@@ -25,8 +25,12 @@ using namespace mozilla::Compression; + + namespace { + ++extern "C" { ++ + #include "lz4.c" + ++} ++ + }/* anonymous namespace */ + + /* Our wrappers */ Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1399412 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1430557 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1430557 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1430557 (revision 462640) @@ -0,0 +1,51 @@ +commit a9691980909f +Author: Jonathan Watt +Date: Tue Feb 20 16:13:05 2018 -0500 + + Bug 1430557. r=longsonr, a=lizzard + + --HG-- + extra : rebase_source : 5109c816d9ad1ce1881e3670b8d74ae0dc475223 +--- + dom/svg/DOMSVGPathSegList.cpp | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git dom/svg/DOMSVGPathSegList.cpp dom/svg/DOMSVGPathSegList.cpp +index edacdfc93e9c..0b811cdb1f11 100644 +--- dom/svg/DOMSVGPathSegList.cpp ++++ dom/svg/DOMSVGPathSegList.cpp +@@ -460,6 +460,18 @@ DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem, + float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS]; + domItem->ToSVGPathSegEncodedData(segAsRaw); + ++ if (AnimListMirrorsBaseList()) { ++ // The anim val list is in sync with the base val list - remove mirroring ++ // animVal item if necessary. We do this *before* touching InternalList() ++ // so the removed item can correctly store its internal value. ++ DOMSVGPathSegList* animVal = ++ GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); ++ if (animVal->ItemAt(aIndex)) { ++ animVal->ItemAt(aIndex)->RemovingFromList(); ++ animVal->ItemAt(aIndex) = nullptr; ++ } ++ } ++ + if (!InternalList().mData.ReplaceElementsAt(internalIndex, 1 + oldArgCount, + segAsRaw, 1 + newArgCount, + fallible)) { +@@ -474,8 +486,13 @@ DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem, + + int32_t delta = newArgCount - oldArgCount; + if (delta != 0) { +- for (uint32_t i = aIndex + 1; i < LengthNoFlush(); ++i) { +- mItems[i].mInternalDataIndex += delta; ++ // Sync up the internal indexes of all ItemProxys that come after aIndex: ++ UpdateListIndicesFromIndex(aIndex + 1, delta); ++ if (AnimListMirrorsBaseList()) { ++ // The anim val list is in sync with the base val list ++ DOMSVGPathSegList* animVal = ++ GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); ++ animVal->UpdateListIndicesFromIndex(aIndex + 1, delta); + } + } + Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1430557 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1437087 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1437087 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1437087 (revision 462640) @@ -0,0 +1,88 @@ +commit a2e5898c8de8 +Author: Makoto Kato +Date: Thu Feb 22 13:43:19 2018 +0200 + + Bug 1437087 - Call Disconnect on Unlink of cycle collector. r=masayuki a=abillings +--- + editor/libeditor/EditorBase.cpp | 17 +++++++++-------- + editor/libeditor/EditorBase.h | 4 ++-- + 2 files changed, 11 insertions(+), 10 deletions(-) + +diff --git editor/libeditor/EditorBase.cpp editor/libeditor/EditorBase.cpp +index 5cb7d62d9982..a30528fc6ebf 100644 +--- editor/libeditor/EditorBase.cpp ++++ editor/libeditor/EditorBase.cpp +@@ -168,7 +168,12 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(EditorBase) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget) +- NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener) ++ ++ if (tmp->mEventListener) { ++ tmp->mEventListener->Disconnect(); ++ tmp->mEventListener = nullptr; ++ } ++ + NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlaceholderTransaction) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mSavedSel); + NS_IMPL_CYCLE_COLLECTION_UNLINK(mRangeUpdater); +@@ -318,9 +323,7 @@ EditorBase::PostCreate() + // If the text control gets reframed during focus, Focus() would not be + // called, so take a chance here to see if we need to spell check the text + // control. +- EditorEventListener* listener = +- reinterpret_cast(mEventListener.get()); +- listener->SpellCheckIfNeeded(); ++ mEventListener->SpellCheckIfNeeded(); + + IMEState newState; + rv = GetPreferredIMEState(&newState); +@@ -358,9 +361,7 @@ EditorBase::InstallEventListeners() + mEventTarget = do_QueryInterface(rootContent->GetParent()); + NS_ENSURE_TRUE(mEventTarget, NS_ERROR_NOT_AVAILABLE); + +- EditorEventListener* listener = +- reinterpret_cast(mEventListener.get()); +- nsresult rv = listener->Connect(this); ++ nsresult rv = mEventListener->Connect(this); + if (mComposition) { + // Restart to handle composition with new editor contents. + mComposition->StartHandlingComposition(this); +@@ -374,7 +375,7 @@ EditorBase::RemoveEventListeners() + if (!IsInitialized() || !mEventListener) { + return; + } +- reinterpret_cast(mEventListener.get())->Disconnect(); ++ mEventListener->Disconnect(); + if (mComposition) { + // Even if this is called, don't release mComposition because this is + // may be reused after reframing. +diff --git editor/libeditor/EditorBase.h editor/libeditor/EditorBase.h +index c59fbd0b0e71..91d390ae5d80 100644 +--- editor/libeditor/EditorBase.h ++++ editor/libeditor/EditorBase.h +@@ -37,7 +37,6 @@ class nsAtom; + class nsIContent; + class nsIDOMDocument; + class nsIDOMEvent; +-class nsIDOMEventListener; + class nsIDOMEventTarget; + class nsIDOMNode; + class nsIDocumentStateListener; +@@ -114,6 +113,7 @@ class CreateElementTransaction; + class DeleteNodeTransaction; + class DeleteTextTransaction; + class EditAggregateTransaction; ++class EditorEventListener; + class EditTransactionBase; + class ErrorResult; + class HTMLEditor; +@@ -1449,7 +1449,7 @@ protected: + nsCOMPtr mRootElement; + // The form field as an event receiver. + nsCOMPtr mEventTarget; +- nsCOMPtr mEventListener; ++ RefPtr mEventListener; + // Strong reference to placeholder for begin/end batch purposes. + RefPtr mPlaceholderTransaction; + // Name of placeholder transaction. Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1437087 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1 =================================================================== --- branches/2018Q1 (revision 462639) +++ branches/2018Q1 (revision 462640) Property changes on: branches/2018Q1 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r462635