Commit 5b81ab6c authored by Adrian Bunk's avatar Adrian Bunk

Remove USE_FIXEDPOINT support

This was already non-compiling for some time.

Closes #821
parent d70f77ee
......@@ -62,7 +62,6 @@ option(ENABLE_LIBCURL "Build libcurl based HTTP support." ON)
option(ENABLE_ZLIB "Build with zlib." ON)
option(ENABLE_ZLIB_UNCOMPRESS "Use zlib to uncompress flate streams (not totally safe)." OFF)
option(SPLASH_CMYK "Include support for CMYK rasterization." OFF)
option(USE_FIXEDPOINT "Use fixed point arithmetic in the Splash backend" OFF)
option(USE_FLOAT "Use single precision arithmetic in the Splash backend" OFF)
option(BUILD_SHARED_LIBS "Build poppler as a shared library" ON)
if(WIN32)
......@@ -328,7 +327,6 @@ set(poppler_SRCS
goo/gfile.cc
goo/GooTimer.cc
goo/GooString.cc
goo/FixedPoint.cc
goo/NetPBMWriter.cc
goo/PNGWriter.cc
goo/TiffWriter.cc
......@@ -594,7 +592,6 @@ if(ENABLE_UNSTABLE_API_ABI_HEADERS)
goo/gmem.h
goo/gdir.h
goo/gfile.h
goo/FixedPoint.h
goo/ImgWriter.h
goo/GooCheckedOps.h
goo/GooLikely.h
......@@ -747,10 +744,6 @@ if(NOT ENABLE_SPLASH AND NOT CAIRO_FOUND)
message("Warning: There is no rendering backend enabled")
endif()
if(USE_FIXEDPOINT AND USE_FLOAT)
message("Warning: Single precision and fixed point options should not be enabled at the same time")
endif()
if(NOT ENABLE_LIBJPEG AND HAVE_DCT_DECODER)
message("Warning: Using libjpeg is recommended. The internal DCT decoder is unmaintained.")
endif()
......
......@@ -165,9 +165,6 @@
/* Defines if use cms */
#cmakedefine USE_CMS 1
/* Use fixed point arithmetic in the Splash backend */
#cmakedefine USE_FIXEDPOINT 1
/* Use single precision arithmetic in the Splash backend */
#cmakedefine USE_FLOAT 1
......
//========================================================================
//
// FixedPoint.cc
//
// Fixed point type, with C++ operators.
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================
//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================
#include <config.h>
#ifdef USE_FIXEDPOINT
#include "FixedPoint.h"
#define ln2 ((FixedPoint)0.69314718)
#define ln2 ((FixedPoint)0.69314718)
FixedPoint FixedPoint::sqrt(FixedPoint x) {
FixedPoint y0, y1, z;
if (x.val <= 0) {
y1.val = 0;
} else {
y1.val = x.val == 1 ? 2 : x.val >> 1;
do {
y0.val = y1.val;
z = x / y0;
y1.val = (y0.val + z.val) >> 1;
} while (::abs(y0.val - y1.val) > 1);
}
return y1;
}
FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
FixedPoint t, t2, lnx0, lnx, z0, z;
int d, n, i;
if (y.val <= 0) {
z.val = 0;
} else {
// y * ln(x)
t = (x - 1) / (x + 1);
t2 = t * t;
d = 1;
lnx = 0;
do {
lnx0 = lnx;
lnx += t / d;
t *= t2;
d += 2;
} while (::abs(lnx.val - lnx0.val) > 2);
lnx.val <<= 1;
t = y * lnx;
// exp(y * ln(x))
n = floor(t / ln2);
t -= ln2 * n;
t2 = t;
d = 1;
i = 1;
z = 1;
do {
z0 = z;
z += t2 / d;
t2 *= t;
++i;
d *= i;
} while (::abs(z.val - z0.val) > 2 && d < (1 << fixptShift));
if (n >= 0) {
z.val <<= n;
} else if (n < 0) {
z.val >>= -n;
}
}
return z;
}
int FixedPoint::mul(int x, int y) {
FixPtInt64 z;
z = ((FixPtInt64)x * y) >> fixptShift;
if (z > 0x7fffffffLL) {
return 0x7fffffff;
} else if (z < -0x80000000LL) {
return 0x80000000;
} else {
return (int)z;
}
}
int FixedPoint::div(int x, int y) {
FixPtInt64 z;
z = ((FixPtInt64)x << fixptShift) / y;
if (z > 0x7fffffffLL) {
return 0x7fffffff;
} else if (z < -0x80000000LL) {
return 0x80000000;
} else {
return (int)z;
}
}
bool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
FixPtInt64 z;
z = ((FixPtInt64)x.val << fixptShift) / y.val;
if ((z == 0 && x != 0) ||
z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
return false;
}
result->val = z;
return true;
}
bool FixedPoint::checkDet(FixedPoint m11, FixedPoint m12,
FixedPoint m21, FixedPoint m22,
FixedPoint epsilon) {
FixPtInt64 det, e;
det = (FixPtInt64)m11.val * (FixPtInt64)m22.val
- (FixPtInt64)m12.val * (FixPtInt64)m21.val;
e = (FixPtInt64)epsilon.val << fixptShift;
// NB: this comparison has to be >= not > because epsilon can be
// truncated to zero as a fixed point value.
return det >= e || det <= -e;
}
#endif // USE_FIXEDPOINT
//========================================================================
//
// FixedPoint.h
//
// Fixed point type, with C++ operators.
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================
//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================
#ifndef FIXEDPOINT_H
#define FIXEDPOINT_H
#include "poppler-config.h"
#ifdef USE_FIXEDPOINT
#include <stdio.h>
#include <stdlib.h>
#define fixptShift 16
#define fixptMaskL ((1 << fixptShift) - 1)
#define fixptMaskH (~fixptMaskL)
typedef long long FixPtInt64;
class FixedPoint {
public:
FixedPoint() { val = 0; }
FixedPoint(const FixedPoint &x) { val = x.val; }
FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
FixedPoint(int x) { val = x << fixptShift; }
FixedPoint(long x) { val = x << fixptShift; }
operator float()
{ return (float) val * ((float)1 / (float)(1 << fixptShift)); }
operator double()
{ return (double) val * (1.0 / (double)(1 << fixptShift)); }
operator int()
{ return val >> fixptShift; }
int get16Dot16() { return val; }
FixedPoint operator =(FixedPoint x) { val = x.val; return *this; }
int operator ==(FixedPoint x) { return val == x.val; }
int operator ==(double x) { return *this == (FixedPoint)x; }
int operator ==(int x) { return *this == (FixedPoint)x; }
int operator ==(long x) { return *this == (FixedPoint)x; }
int operator !=(FixedPoint x) { return val != x.val; }
int operator !=(double x) { return *this != (FixedPoint)x; }
int operator !=(int x) { return *this != (FixedPoint)x; }
int operator !=(long x) { return *this != (FixedPoint)x; }
int operator <(FixedPoint x) { return val < x.val; }
int operator <(double x) { return *this < (FixedPoint)x; }
int operator <(int x) { return *this < (FixedPoint)x; }
int operator <(long x) { return *this < (FixedPoint)x; }
int operator <=(FixedPoint x) { return val <= x.val; }
int operator <=(double x) { return *this <= (FixedPoint)x; }
int operator <=(int x) { return *this <= (FixedPoint)x; }
int operator <=(long x) { return *this <= (FixedPoint)x; }
int operator >(FixedPoint x) { return val > x.val; }
int operator >(double x) { return *this > (FixedPoint)x; }
int operator >(int x) { return *this > (FixedPoint)x; }
int operator >(long x) { return *this > (FixedPoint)x; }
int operator >=(FixedPoint x) { return val >= x.val; }
int operator >=(double x) { return *this >= (FixedPoint)x; }
int operator >=(int x) { return *this >= (FixedPoint)x; }
int operator >=(long x) { return *this >= (FixedPoint)x; }
FixedPoint operator -() { return make(-val); }
FixedPoint operator +(FixedPoint x) { return make(val + x.val); }
FixedPoint operator +(double x) { return *this + (FixedPoint)x; }
FixedPoint operator +(int x) { return *this + (FixedPoint)x; }
FixedPoint operator +(long x) { return *this + (FixedPoint)x; }
FixedPoint operator +=(FixedPoint x) { val = val + x.val; return *this; }
FixedPoint operator +=(double x) { return *this += (FixedPoint)x; }
FixedPoint operator +=(int x) { return *this += (FixedPoint)x; }
FixedPoint operator +=(long x) { return *this += (FixedPoint)x; }
FixedPoint operator -(FixedPoint x) { return make(val - x.val); }
FixedPoint operator -(double x) { return *this - (FixedPoint)x; }
FixedPoint operator -(int x) { return *this - (FixedPoint)x; }
FixedPoint operator -(long x) { return *this - (FixedPoint)x; }
FixedPoint operator -=(FixedPoint x) { val = val - x.val; return *this; }
FixedPoint operator -=(double x) { return *this -= (FixedPoint)x; }
FixedPoint operator -=(int x) { return *this -= (FixedPoint)x; }
FixedPoint operator -=(long x) { return *this -= (FixedPoint)x; }
FixedPoint operator *(FixedPoint x) { return make(mul(val, x.val)); }
FixedPoint operator *(double x) { return *this * (FixedPoint)x; }
FixedPoint operator *(int x) { return *this * (FixedPoint)x; }
FixedPoint operator *(long x) { return *this * (FixedPoint)x; }
FixedPoint operator *=(FixedPoint x) { val = mul(val, x.val); return *this; }
FixedPoint operator *=(double x) { return *this *= (FixedPoint)x; }
FixedPoint operator *=(int x) { return *this *= (FixedPoint)x; }
FixedPoint operator *=(long x) { return *this *= (FixedPoint)x; }
FixedPoint operator /(FixedPoint x) { return make(div(val, x.val)); }
FixedPoint operator /(double x) { return *this / (FixedPoint)x; }
FixedPoint operator /(int x) { return *this / (FixedPoint)x; }
FixedPoint operator /(long x) { return *this / (FixedPoint)x; }
FixedPoint operator /=(FixedPoint x) { val = div(val, x.val); return *this; }
FixedPoint operator /=(double x) { return *this /= (FixedPoint)x; }
FixedPoint operator /=(int x) { return *this /= (FixedPoint)x; }
FixedPoint operator /=(long x) { return *this /= (FixedPoint)x; }
static FixedPoint abs(FixedPoint x) { return make(::abs(x.val)); }
static int floor(FixedPoint x) { return x.val >> fixptShift; }
static int ceil(FixedPoint x)
{ return (x.val & fixptMaskL) ? ((x.val >> fixptShift) + 1)
: (x.val >> fixptShift); }
static int round(FixedPoint x)
{ return (x.val + (1 << (fixptShift - 1))) >> fixptShift; }
// Computes (x+y)/2 avoiding overflow and LSbit accuracy issues.
static FixedPoint avg(FixedPoint x, FixedPoint y)
{ return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); }
static FixedPoint sqrt(FixedPoint x);
static FixedPoint pow(FixedPoint x, FixedPoint y);
// Compute *result = x/y; return false if there is an underflow or
// overflow.
static bool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result);
// Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case
// where the multiplications overflow.
static bool checkDet(FixedPoint m11, FixedPoint m12,
FixedPoint m21, FixedPoint m22,
FixedPoint epsilon);
private:
static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; }
static int mul(int x, int y);
static int div(int x, int y);
int val; // fixed point: (n-fixptShift).(fixptShift)
};
#endif // USE_FIXEDPOINT
#endif
......@@ -38,11 +38,6 @@
#define POPPLER_VERSION "${POPPLER_VERSION}"
#endif
/* Use fixedpoint. */
#ifndef USE_FIXEDPOINT
#cmakedefine USE_FIXEDPOINT 1
#endif
/* Use single precision arithmetic in the Splash backend */
#ifndef USE_FLOAT
#cmakedefine USE_FLOAT 1
......
......@@ -2214,11 +2214,7 @@ SplashPath *Splash::flattenPath(SplashPath *path, SplashCoord *matrix,
int i;
fPath = new SplashPath();
#ifdef USE_FIXEDPOINT
flatness2 = flatness;
#else
flatness2 = flatness * flatness;
#endif
i = 0;
while (i < path->length) {
flag = path->flags[i];
......@@ -2283,21 +2279,13 @@ void Splash::flattenCurve(SplashCoord x0, SplashCoord y0,
// line)
transform(matrix, (xl0 + xr3) * 0.5, (yl0 + yr3) * 0.5, &mx, &my);
transform(matrix, xx1, yy1, &tx, &ty);
#ifdef USE_FIXEDPOINT
d1 = splashDist(tx, ty, mx, my);
#else
dx = tx - mx;
dy = ty - my;
d1 = dx*dx + dy*dy;
#endif
transform(matrix, xx2, yy2, &tx, &ty);
#ifdef USE_FIXEDPOINT
d2 = splashDist(tx, ty, mx, my);
#else
dx = tx - mx;
dy = ty - my;
d2 = dx*dx + dy*dy;
#endif
// if the curve is flat enough, or no more subdivisions are
// allowed, add the straight line segment
......@@ -6087,19 +6075,10 @@ SplashPath *pathIn, *dashPath, *pathOut;
++k1) ;
// compute the deltas for segment (i1, j0)
#ifdef USE_FIXEDPOINT
// the 1/d value can be small, which introduces significant
// inaccuracies in fixed point mode
d = splashDist(pathIn->pts[i1].x, pathIn->pts[i1].y,
pathIn->pts[j0].x, pathIn->pts[j0].y);
dx = (pathIn->pts[j0].x - pathIn->pts[i1].x) / d;
dy = (pathIn->pts[j0].y - pathIn->pts[i1].y) / d;
#else
d = (SplashCoord)1 / splashDist(pathIn->pts[i1].x, pathIn->pts[i1].y,
pathIn->pts[j0].x, pathIn->pts[j0].y);
dx = d * (pathIn->pts[j0].x - pathIn->pts[i1].x);
dy = d * (pathIn->pts[j0].y - pathIn->pts[i1].y);
#endif
wdx = (SplashCoord)0.5 * w * dx;
wdy = (SplashCoord)0.5 * w * dy;
......@@ -6188,19 +6167,10 @@ SplashPath *pathIn, *dashPath, *pathOut;
if (!last || closed) {
// compute the deltas for segment (j1, k0)
#ifdef USE_FIXEDPOINT
// the 1/d value can be small, which introduces significant
// inaccuracies in fixed point mode
d = splashDist(pathIn->pts[j1].x, pathIn->pts[j1].y,
pathIn->pts[k0].x, pathIn->pts[k0].y);
dxNext = (pathIn->pts[k0].x - pathIn->pts[j1].x) / d;
dyNext = (pathIn->pts[k0].y - pathIn->pts[j1].y) / d;
#else
d = (SplashCoord)1 / splashDist(pathIn->pts[j1].x, pathIn->pts[j1].y,
pathIn->pts[k0].x, pathIn->pts[k0].y);
dxNext = d * (pathIn->pts[k0].x - pathIn->pts[j1].x);
dyNext = d * (pathIn->pts[k0].y - pathIn->pts[j1].y);
#endif
wdxNext = (SplashCoord)0.5 * w * dxNext;
wdyNext = (SplashCoord)0.5 * w * dyNext;
......
......@@ -65,9 +65,6 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
FT_Face face;
int div;
int x, y;
#ifdef USE_FIXEDPOINT
SplashCoord scale;
#endif
face = fontFileA->face;
if (FT_New_Size(face, &sizeObj)) {
......@@ -91,60 +88,6 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
div = face->bbox.xMax > 20000 ? 65536 : 1;
#ifdef USE_FIXEDPOINT
scale = (SplashCoord)1 / (SplashCoord)face->units_per_EM;
// transform the four corners of the font bounding box -- the min
// and max values form the bounding box of the transformed font
x = (int)(mat[0] * (scale * (face->bbox.xMin / div)) +
mat[2] * (scale * (face->bbox.yMin / div)));
xMin = xMax = x;
y = (int)(mat[1] * (scale * (face->bbox.xMin / div)) +
mat[3] * (scale * (face->bbox.yMin / div)));
yMin = yMax = y;
x = (int)(mat[0] * (scale * (face->bbox.xMin / div)) +
mat[2] * (scale * (face->bbox.yMax / div)));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)(mat[1] * (scale * (face->bbox.xMin / div)) +
mat[3] * (scale * (face->bbox.yMax / div)));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)(mat[0] * (scale * (face->bbox.xMax / div)) +
mat[2] * (scale * (face->bbox.yMin / div)));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)(mat[1] * (scale * (face->bbox.xMax / div)) +
mat[3] * (scale * (face->bbox.yMin / div)));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)(mat[0] * (scale * (face->bbox.xMax / div)) +
mat[2] * (scale * (face->bbox.yMax / div)));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)(mat[1] * (scale * (face->bbox.xMax / div)) +
mat[3] * (scale * (face->bbox.yMax / div)));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
#else // USE_FIXEDPOINT
// transform the four corners of the font bounding box -- the min
// and max values form the bounding box of the transformed font
x = (int)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMin) /
......@@ -195,7 +138,6 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
} else if (y > yMax) {
yMax = y;
}
#endif // USE_FIXEDPOINT
// This is a kludge: some buggy PDF generators embed fonts with
// zero bounding boxes.
if (xMax == xMin) {
......@@ -208,16 +150,6 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
}
// compute the transform matrix
#ifdef USE_FIXEDPOINT
matrix.xx = (FT_Fixed)((mat[0] / size).get16Dot16());
matrix.yx = (FT_Fixed)((mat[1] / size).get16Dot16());
matrix.xy = (FT_Fixed)((mat[2] / size).get16Dot16());
matrix.yy = (FT_Fixed)((mat[3] / size).get16Dot16());
textMatrix.xx = (FT_Fixed)((textMat[0] / (textScale * size)).get16Dot16());
textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)).get16Dot16());
textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)).get16Dot16());
textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)).get16Dot16());
#else
matrix.xx = (FT_Fixed)((mat[0] / size) * 65536);
matrix.yx = (FT_Fixed)((mat[1] / size) * 65536);
matrix.xy = (FT_Fixed)((mat[2] / size) * 65536);
......@@ -226,7 +158,6 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)) * 65536);
textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)) * 65536);
textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)) * 65536);
#endif
isOk = true;
}
......
......@@ -24,17 +24,11 @@
#include "poppler-config.h"
#ifdef USE_FIXEDPOINT
#include "goo/FixedPoint.h"
#else
#include <math.h>
#endif
#include "SplashTypes.h"
static inline SplashCoord splashAbs(SplashCoord x) {
#if defined(USE_FIXEDPOINT)
return FixedPoint::abs(x);
#elif defined(USE_FLOAT)
#if defined(USE_FLOAT)
return fabsf(x);
#else
return fabs(x);
......@@ -42,9 +36,7 @@ static inline SplashCoord splashAbs(SplashCoord x) {
}
static inline int splashFloor(SplashCoord x) {
#if defined(USE_FIXEDPOINT)
return FixedPoint::floor(x);
#elif defined(USE_FLOAT)
#if defined(USE_FLOAT)
return (int)floorf(x);
#elif defined(__GNUC__) && defined(__i386__)
// floor() and (int)() are implemented separately, which results
......@@ -89,9 +81,7 @@ static inline int splashFloor(SplashCoord x) {
}
static inline int splashCeil(SplashCoord x) {
#if defined(USE_FIXEDPOINT)
return FixedPoint::ceil(x);
#elif defined(USE_FLOAT)
#if defined(USE_FLOAT)
return (int)ceilf(x);
#elif defined(__GNUC__) && defined(__i386__)
// ceil() and (int)() are implemented separately, which results
......@@ -135,9 +125,7 @@ static inline int splashCeil(SplashCoord x) {
}
static inline int splashRound(SplashCoord x) {
#if defined(USE_FIXEDPOINT)
return FixedPoint::round(x);
#elif defined(__GNUC__) && defined(__i386__)
#if defined(__GNUC__) && defined(__i386__)
// this could use round-to-nearest mode and avoid the "+0.5",
// but that produces slightly different results (because i+0.5
// sometimes rounds up and sometimes down using the even rule)
......@@ -181,17 +169,11 @@ static inline int splashRound(SplashCoord x) {
}
static inline SplashCoord splashAvg(SplashCoord x, SplashCoord y) {
#ifdef USE_FIXEDPOINT
return FixedPoint::avg(x, y);
#else
return 0.5 * (x + y);
#endif
}
static inline SplashCoord splashSqrt(SplashCoord x) {
#if defined(USE_FIXEDPOINT)
return FixedPoint::sqrt(x);
#elif defined(USE_FLOAT)
#if defined(USE_FLOAT)
return sqrtf(x);
#else
return sqrt(x);
......@@ -199,9 +181,7 @@ static inline SplashCoord splashSqrt(SplashCoord x) {
}
static inline SplashCoord splashPow(SplashCoord x, SplashCoord y) {
#if defined(USE_FIXEDPOINT)
return FixedPoint::pow(x, y);
#elif defined(USE_FLOAT)
#if defined(USE_FLOAT)
return powf(x, y);
#else
return pow(x, y);
......@@ -213,34 +193,13 @@ static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0,