Fix printf issue in apriltags, dmtx and lsd.

* The root cause for this issue is "define double float". printf functions promote
float to double, which is #define'd as float causing the implicit conversion error.
* Replaced all double with float, and DBL_MIN and FLT_MIN etc... and added explicit
cast to double in printf functions.
This commit is contained in:
iabdalkader 2019-09-06 15:48:31 +02:00
parent fa2ffaa655
commit 7eaeefacb1
3 changed files with 791 additions and 811 deletions

File diff suppressed because it is too large Load Diff

View File

@ -21,18 +21,11 @@
#define perror(str)
#define fprintf(stream, format, ...)
#define fputc(character, stream)
#define snprintf(s, c, format, ...) 0
#define free(ptr) ({ umm_free(ptr); })
#define malloc(size) ({ void *_r = umm_malloc(size); if(!_r) fb_alloc_fail(); _r; })
#define realloc(ptr, size) ({ void *_r = umm_realloc((ptr), (size)); if(!_r) fb_alloc_fail(); _r; })
#define calloc(num, item_size) ({ void *_r = umm_calloc((num), (item_size)); if(!_r) fb_alloc_fail(); _r; })
#define assert(expression)
#define double float
#undef DBL_MIN
#define DBL_MIN FLT_MIN
#undef DBL_MAX
#define DBL_MAX FLT_MAX
#define sqrt(x) fast_sqrtf(x)
#define sqrtf(x) fast_sqrtf(x)
#define floor(x) fast_floorf(x)
@ -258,7 +251,7 @@ typedef enum {
DmtxFlipY = 0x01 << 1
} DmtxFlip;
typedef double DmtxMatrix3[3][3];
typedef float DmtxMatrix3[3][3];
/**
* @struct DmtxPixelLoc
@ -274,8 +267,8 @@ typedef struct DmtxPixelLoc_struct {
* @brief DmtxVector2
*/
typedef struct DmtxVector2_struct {
double X;
double Y;
float X;
float Y;
} DmtxVector2;
/**
@ -283,8 +276,8 @@ typedef struct DmtxVector2_struct {
* @brief DmtxRay2
*/
typedef struct DmtxRay2_struct {
double tMin;
double tMax;
float tMin;
float tMax;
DmtxVector2 p;
DmtxVector2 v;
} DmtxRay2;
@ -348,7 +341,7 @@ typedef struct DmtxBestLine_struct {
int stepPos;
int stepNeg;
int distSq;
double devn;
float devn;
DmtxPixelLoc locBeg;
DmtxPixelLoc locPos;
DmtxPixelLoc locNeg;
@ -459,7 +452,7 @@ typedef struct DmtxDecode_struct {
int edgeMin;
int edgeMax;
int scanGap;
double squareDevn;
float squareDevn;
int sizeIdxExpected;
int edgeThresh;
@ -510,35 +503,35 @@ extern int dmtxImageGetByteOffset(DmtxImage *img, int x, int y);
extern DmtxPassFail dmtxImageGetPixelValue(DmtxImage *img, int x, int y, int channel, /*@out@*/ int *value);
extern DmtxPassFail dmtxImageSetPixelValue(DmtxImage *img, int x, int y, int channel, int value);
extern DmtxBoolean dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y);
extern DmtxBoolean dmtxImageContainsFloat(DmtxImage *img, double x, double y);
extern DmtxBoolean dmtxImageContainsFloat(DmtxImage *img, float x, float y);
/* dmtxvector2.c */
extern DmtxVector2 *dmtxVector2AddTo(DmtxVector2 *v1, const DmtxVector2 *v2);
extern DmtxVector2 *dmtxVector2Add(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2);
extern DmtxVector2 *dmtxVector2SubFrom(DmtxVector2 *v1, const DmtxVector2 *v2);
extern DmtxVector2 *dmtxVector2Sub(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2);
extern DmtxVector2 *dmtxVector2ScaleBy(DmtxVector2 *v, double s);
extern DmtxVector2 *dmtxVector2Scale(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v, double s);
extern double dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2);
extern double dmtxVector2Norm(DmtxVector2 *v);
extern double dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2);
extern double dmtxVector2Mag(const DmtxVector2 *v);
extern double dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q);
extern double dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q);
extern DmtxVector2 *dmtxVector2ScaleBy(DmtxVector2 *v, float s);
extern DmtxVector2 *dmtxVector2Scale(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v, float s);
extern float dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2);
extern float dmtxVector2Norm(DmtxVector2 *v);
extern float dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2);
extern float dmtxVector2Mag(const DmtxVector2 *v);
extern float dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q);
extern float dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q);
extern DmtxPassFail dmtxRay2Intersect(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1);
extern DmtxPassFail dmtxPointAlongRay2(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *r, double t);
extern DmtxPassFail dmtxPointAlongRay2(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *r, float t);
/* dmtxmatrix3.c */
extern void dmtxMatrix3Copy(/*@out@*/ DmtxMatrix3 m0, DmtxMatrix3 m1);
extern void dmtxMatrix3Identity(/*@out@*/ DmtxMatrix3 m);
extern void dmtxMatrix3Translate(/*@out@*/ DmtxMatrix3 m, double tx, double ty);
extern void dmtxMatrix3Rotate(/*@out@*/ DmtxMatrix3 m, double angle);
extern void dmtxMatrix3Scale(/*@out@*/ DmtxMatrix3 m, double sx, double sy);
extern void dmtxMatrix3Shear(/*@out@*/ DmtxMatrix3 m, double shx, double shy);
extern void dmtxMatrix3LineSkewTop(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
extern void dmtxMatrix3LineSkewTopInv(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
extern void dmtxMatrix3LineSkewSide(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
extern void dmtxMatrix3LineSkewSideInv(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
extern void dmtxMatrix3Translate(/*@out@*/ DmtxMatrix3 m, float tx, float ty);
extern void dmtxMatrix3Rotate(/*@out@*/ DmtxMatrix3 m, float angle);
extern void dmtxMatrix3Scale(/*@out@*/ DmtxMatrix3 m, float sx, float sy);
extern void dmtxMatrix3Shear(/*@out@*/ DmtxMatrix3 m, float shx, float shy);
extern void dmtxMatrix3LineSkewTop(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
extern void dmtxMatrix3LineSkewTopInv(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
extern void dmtxMatrix3LineSkewSide(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
extern void dmtxMatrix3LineSkewSideInv(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
extern void dmtxMatrix3Multiply(/*@out@*/ DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1);
extern void dmtxMatrix3MultiplyBy(DmtxMatrix3 m0, DmtxMatrix3 m1);
extern int dmtxMatrix3VMultiply(/*@out@*/ DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m);
@ -681,7 +674,7 @@ typedef struct C40TextState_struct {
} C40TextState;
/* dmtxregion.c */
static double RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle);
static float RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, float angle);
static DmtxPointFlow MatrixRegionSeekEdge(DmtxDecode *dec, DmtxPixelLoc loc0);
static DmtxPassFail MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow flowBegin);
static long DistanceSquared(DmtxPixelLoc a, DmtxPixelLoc b);
@ -1099,8 +1092,8 @@ dmtxDecodeGetPixelValue(DmtxDecode *dec, int x, int y, int channel, int *value)
/* Remove spherical lens distortion */
/* int width, height;
double radiusPow2, radiusPow4;
double factor;
float radiusPow2, radiusPow4;
float factor;
DmtxVector2 pointShifted;
DmtxVector2 correctedPoint;
@ -1322,7 +1315,7 @@ dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, i
int widthDigits, heightDigits;
int count, channelCount;
int rgb[3];
double shade;
float shade;
unsigned char *pnm, *output, *cache;
width = dmtxDecodeGetProp(dec, DmtxPropWidth);
@ -1379,7 +1372,7 @@ dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, i
else
dmtxDecodeGetPixelValue(dec, col, row, 0, &rgb[i]);
rgb[i] += (int)(shade * (double)(255 - rgb[i]) + 0.5);
rgb[i] += (int)(shade * (float)(255 - rgb[i]) + 0.5);
if(rgb[i] > 255)
rgb[i] = 255;
}
@ -1564,7 +1557,7 @@ PopulateArrayFromMatrix(DmtxDecode *dec, DmtxRegion *reg, DmtxMessage *msg)
colTmp = (xRegionCount * mapWidth) + mapCol;
idx = (rowTmp * xRegionTotal * mapWidth) + colTmp;
if(tally[mapRow][mapCol]/(double)weightFactor >= 0.5)
if(tally[mapRow][mapCol]/(float)weightFactor >= 0.5)
msg->array[idx] = DmtxModuleOnRGB;
else
msg->array[idx] = DmtxModuleOff;
@ -2442,7 +2435,7 @@ MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
}
err = FindTravelLimits(dec, reg, &line1x);
if(line1x.distSq < 100 || line1x.devn * 10 >= sqrt((double)line1x.distSq)) {
if(line1x.distSq < 100 || line1x.devn * 10 >= sqrt((float)line1x.distSq)) {
TrailClear(dec, reg, 0x40);
return DmtxFail;
}
@ -2459,7 +2452,7 @@ MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
if(line2p.mag > line2n.mag) {
line2x = line2p;
err = FindTravelLimits(dec, reg, &line2x);
if(line2x.distSq < 100 || line2x.devn * 10 >= sqrt((double)line2x.distSq))
if(line2x.distSq < 100 || line2x.devn * 10 >= sqrt((float)line2x.distSq))
return DmtxFail;
cross = ((line1x.locPos.X - line1x.locNeg.X) * (line2x.locPos.Y - line2x.locNeg.Y)) -
@ -2496,7 +2489,7 @@ MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
else {
line2x = line2n;
err = FindTravelLimits(dec, reg, &line2x);
if(line2x.distSq < 100 || line2x.devn / sqrt((double)line2x.distSq) >= 0.1)
if(line2x.distSq < 100 || line2x.devn / sqrt((float)line2x.distSq) >= 0.1)
return DmtxFail;
cross = ((line1x.locNeg.X - line1x.locPos.X) * (line2x.locNeg.Y - line2x.locPos.Y)) -
@ -2561,14 +2554,14 @@ extern DmtxPassFail
dmtxRegionUpdateCorners(DmtxDecode *dec, DmtxRegion *reg, DmtxVector2 p00,
DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01)
{
double xMax, yMax;
double tx, ty, phi, shx, scx, scy, skx, sky;
double dimOT, dimOR, dimTX, dimRX, ratio;
float xMax, yMax;
float tx, ty, phi, shx, scx, scy, skx, sky;
float dimOT, dimOR, dimTX, dimRX, ratio;
DmtxVector2 vOT, vOR, vTX, vRX, vTmp;
DmtxMatrix3 m, mtxy, mphi, mshx, mscx, mscy, mscxy, msky, mskx;
xMax = (double)(dmtxDecodeGetProp(dec, DmtxPropWidth) - 1);
yMax = (double)(dmtxDecodeGetProp(dec, DmtxPropHeight) - 1);
xMax = (float)(dmtxDecodeGetProp(dec, DmtxPropWidth) - 1);
yMax = (float)(dmtxDecodeGetProp(dec, DmtxPropHeight) - 1);
if(p00.X < 0.0 || p00.Y < 0.0 || p00.X > xMax || p00.Y > yMax ||
p01.X < 0.0 || p01.Y < 0.0 || p01.X > xMax || p01.Y > yMax ||
@ -2663,15 +2656,15 @@ dmtxRegionUpdateCorners(DmtxDecode *dec, DmtxRegion *reg, DmtxVector2 p00,
extern DmtxPassFail
dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
{
double radians;
float radians;
DmtxRay2 rLeft, rBottom, rTop, rRight;
DmtxVector2 p00, p10, p11, p01;
assert(reg->leftKnown != 0 && reg->bottomKnown != 0);
/* Build ray representing left edge */
rLeft.p.X = (double)reg->leftLoc.X;
rLeft.p.Y = (double)reg->leftLoc.Y;
rLeft.p.X = (float)reg->leftLoc.X;
rLeft.p.Y = (float)reg->leftLoc.Y;
radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);
rLeft.v.X = cos(radians);
rLeft.v.Y = sin(radians);
@ -2679,8 +2672,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
rLeft.tMax = dmtxVector2Norm(&rLeft.v);
/* Build ray representing bottom edge */
rBottom.p.X = (double)reg->bottomLoc.X;
rBottom.p.Y = (double)reg->bottomLoc.Y;
rBottom.p.X = (float)reg->bottomLoc.X;
rBottom.p.Y = (float)reg->bottomLoc.Y;
radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);
rBottom.v.X = cos(radians);
rBottom.v.Y = sin(radians);
@ -2689,8 +2682,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
/* Build ray representing top edge */
if(reg->topKnown != 0) {
rTop.p.X = (double)reg->topLoc.X;
rTop.p.Y = (double)reg->topLoc.Y;
rTop.p.X = (float)reg->topLoc.X;
rTop.p.Y = (float)reg->topLoc.Y;
radians = reg->topAngle * (M_PI/DMTX_HOUGH_RES);
rTop.v.X = cos(radians);
rTop.v.Y = sin(radians);
@ -2698,8 +2691,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
rTop.tMax = dmtxVector2Norm(&rTop.v);
}
else {
rTop.p.X = (double)reg->locT.X;
rTop.p.Y = (double)reg->locT.Y;
rTop.p.X = (float)reg->locT.X;
rTop.p.Y = (float)reg->locT.Y;
radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);
rTop.v.X = cos(radians);
rTop.v.Y = sin(radians);
@ -2709,8 +2702,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
/* Build ray representing right edge */
if(reg->rightKnown != 0) {
rRight.p.X = (double)reg->rightLoc.X;
rRight.p.Y = (double)reg->rightLoc.Y;
rRight.p.X = (float)reg->rightLoc.X;
rRight.p.Y = (float)reg->rightLoc.Y;
radians = reg->rightAngle * (M_PI/DMTX_HOUGH_RES);
rRight.v.X = cos(radians);
rRight.v.Y = sin(radians);
@ -2718,8 +2711,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
rRight.tMax = dmtxVector2Norm(&rRight.v);
}
else {
rRight.p.X = (double)reg->locR.X;
rRight.p.Y = (double)reg->locR.Y;
rRight.p.X = (float)reg->locR.X;
rRight.p.Y = (float)reg->locR.Y;
radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);
rRight.v.X = cos(radians);
rRight.v.Y = sin(radians);
@ -2750,8 +2743,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
*
*
*/
static double
RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle)
static float
RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, float angle)
{
DmtxVector2 vA, vB;
DmtxMatrix3 m;
@ -2782,8 +2775,8 @@ ReadModuleColor(DmtxDecode *dec, DmtxRegion *reg, int symbolRow, int symbolCol,
int i;
int symbolRows, symbolCols;
int color, colorTmp;
double sampleX[] = { 0.5, 0.4, 0.5, 0.6, 0.5 };
double sampleY[] = { 0.5, 0.5, 0.4, 0.5, 0.6 };
float sampleX[] = { 0.5, 0.4, 0.5, 0.6, 0.5 };
float sampleY[] = { 0.5, 0.5, 0.4, 0.5, 0.6 };
DmtxVector2 p;
symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);
@ -5506,11 +5499,11 @@ dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y)
* \return DmtxTrue | DmtxFalse
*/
extern DmtxBoolean
dmtxImageContainsFloat(DmtxImage *img, double x, double y)
dmtxImageContainsFloat(DmtxImage *img, float x, float y)
{
assert(img != NULL);
if(x >= 0.0 && x < (double)img->width && y >= 0.0 && y < (double)img->height)
if(x >= 0.0 && x < (float)img->width && y >= 0.0 && y < (float)img->height)
return DmtxTrue;
return DmtxFalse;
@ -5769,7 +5762,7 @@ dmtxVector2Sub(DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2)
*
*/
extern DmtxVector2 *
dmtxVector2ScaleBy(DmtxVector2 *v, double s)
dmtxVector2ScaleBy(DmtxVector2 *v, float s)
{
v->X *= s;
v->Y *= s;
@ -5782,7 +5775,7 @@ dmtxVector2ScaleBy(DmtxVector2 *v, double s)
*
*/
extern DmtxVector2 *
dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, double s)
dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, float s)
{
*vOut = *v;
@ -5793,7 +5786,7 @@ dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, double s)
*
*
*/
extern double
extern float
dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
{
return (v1->X * v2->Y) - (v1->Y * v2->X);
@ -5803,10 +5796,10 @@ dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
*
*
*/
extern double
extern float
dmtxVector2Norm(DmtxVector2 *v)
{
double mag;
float mag;
mag = dmtxVector2Mag(v);
@ -5822,7 +5815,7 @@ dmtxVector2Norm(DmtxVector2 *v)
*
*
*/
extern double
extern float
dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
{
return (v1->X * v2->X) + (v1->Y * v2->Y);
@ -5832,7 +5825,7 @@ dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
*
*
*/
extern double
extern float
dmtxVector2Mag(const DmtxVector2 *v)
{
return sqrt(v->X * v->X + v->Y * v->Y);
@ -5842,7 +5835,7 @@ dmtxVector2Mag(const DmtxVector2 *v)
*
*
*/
extern double
extern float
dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q)
{
DmtxVector2 vSubTmp;
@ -5857,7 +5850,7 @@ dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q)
*
*
*/
extern double
extern float
dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q)
{
DmtxVector2 vSubTmp;
@ -5879,7 +5872,7 @@ dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q)
extern DmtxPassFail
dmtxRay2Intersect(DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
{
double numer, denom;
float numer, denom;
DmtxVector2 w;
denom = dmtxVector2Cross(&(p1->v), &(p0->v));
@ -5897,7 +5890,7 @@ dmtxRay2Intersect(DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
*
*/
extern DmtxPassFail
dmtxPointAlongRay2(DmtxVector2 *point, const DmtxRay2 *r, double t)
dmtxPointAlongRay2(DmtxVector2 *point, const DmtxRay2 *r, float t)
{
DmtxVector2 vTmp;
@ -5988,7 +5981,7 @@ dmtxMatrix3Identity(DmtxMatrix3 m)
* (0,0) (1,0) (0,0) (1,0)
*
*/
void dmtxMatrix3Translate(DmtxMatrix3 m, double tx, double ty)
void dmtxMatrix3Translate(DmtxMatrix3 m, float tx, float ty)
{
dmtxMatrix3Identity(m);
m[2][0] = tx;
@ -6015,9 +6008,9 @@ void dmtxMatrix3Translate(DmtxMatrix3 m, double tx, double ty)
*
*/
extern void
dmtxMatrix3Rotate(DmtxMatrix3 m, double angle)
dmtxMatrix3Rotate(DmtxMatrix3 m, float angle)
{
double sinAngle, cosAngle;
float sinAngle, cosAngle;
sinAngle = sin(angle);
cosAngle = cos(angle);
@ -6051,7 +6044,7 @@ dmtxMatrix3Rotate(DmtxMatrix3 m, double angle)
*
*/
extern void
dmtxMatrix3Scale(DmtxMatrix3 m, double sx, double sy)
dmtxMatrix3Scale(DmtxMatrix3 m, float sx, float sy)
{
dmtxMatrix3Identity(m);
m[0][0] = sx;
@ -6070,7 +6063,7 @@ dmtxMatrix3Scale(DmtxMatrix3 m, double sx, double sy)
* | 0 0 1 |
*/
extern void
dmtxMatrix3Shear(DmtxMatrix3 m, double shx, double shy)
dmtxMatrix3Shear(DmtxMatrix3 m, float shx, float shy)
{
dmtxMatrix3Identity(m);
m[1][0] = shx;
@ -6104,7 +6097,7 @@ dmtxMatrix3Shear(DmtxMatrix3 m, double shx, double shy)
*
*/
extern void
dmtxMatrix3LineSkewTop(DmtxMatrix3 m, double b0, double b1, double sz)
dmtxMatrix3LineSkewTop(DmtxMatrix3 m, float b0, float b1, float sz)
{
assert(b0 >= DmtxAlmostZero);
@ -6123,7 +6116,7 @@ dmtxMatrix3LineSkewTop(DmtxMatrix3 m, double b0, double b1, double sz)
* \return void
*/
extern void
dmtxMatrix3LineSkewTopInv(DmtxMatrix3 m, double b0, double b1, double sz)
dmtxMatrix3LineSkewTopInv(DmtxMatrix3 m, float b0, float b1, float sz)
{
assert(b1 >= DmtxAlmostZero);
@ -6142,7 +6135,7 @@ dmtxMatrix3LineSkewTopInv(DmtxMatrix3 m, double b0, double b1, double sz)
* \return void
*/
extern void
dmtxMatrix3LineSkewSide(DmtxMatrix3 m, double b0, double b1, double sz)
dmtxMatrix3LineSkewSide(DmtxMatrix3 m, float b0, float b1, float sz)
{
assert(b0 >= DmtxAlmostZero);
@ -6161,7 +6154,7 @@ dmtxMatrix3LineSkewSide(DmtxMatrix3 m, double b0, double b1, double sz)
* \return void
*/
extern void
dmtxMatrix3LineSkewSideInv(DmtxMatrix3 m, double b0, double b1, double sz)
dmtxMatrix3LineSkewSideInv(DmtxMatrix3 m, float b0, float b1, float sz)
{
assert(b1 >= DmtxAlmostZero);
@ -6182,7 +6175,7 @@ extern void
dmtxMatrix3Multiply(DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1)
{
int i, j, k;
double val;
float val;
for(i = 0; i < 3; i++) {
for(j = 0; j < 3; j++) {
@ -6220,7 +6213,7 @@ dmtxMatrix3MultiplyBy(DmtxMatrix3 m0, DmtxMatrix3 m1)
extern int
dmtxMatrix3VMultiply(DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m)
{
double w;
float w;
w = vIn->X*m[0][2] + vIn->Y*m[1][2] + m[2][2];
if(fabs(w) <= DmtxAlmostZero) {

View File

@ -26,13 +26,6 @@
#define malloc(size) ({ void *_r = umm_malloc(size); if(!_r) fb_alloc_fail(); _r; })
#define realloc(ptr, size) ({ void *_r = umm_realloc((ptr), (size)); if(!_r) fb_alloc_fail(); _r; })
#define calloc(num, item_size) ({ void *_r = umm_calloc((num), (item_size)); if(!_r) fb_alloc_fail(); _r; })
#define double float
#undef DBL_MIN
#define DBL_MIN FLT_MIN
#undef DBL_MAX
#define DBL_MAX FLT_MAX
#undef DBL_EPSILON
#define DBL_EPSILON FLT_EPSILON
#define sqrt(x) fast_sqrtf(x)
#define floor(x) fast_floorf(x)
#define ceil(x) fast_ceilf(x)
@ -174,7 +167,7 @@
'reg_img' image, when asked for.
Suggested value: NULL
@return A double array of size 7 x n_out, containing the list
@return A float array of size 7 x n_out, containing the list
of line segments detected. The array contains first
7 values of line segment number 1, then the 7 values
of line segment number 2, and so on, and it finish
@ -189,10 +182,10 @@
line segment number 'n+1' are obtained with
'out[7*n+0]' to 'out[7*n+6]'.
*/
double * LineSegmentDetection( int * n_out,
float * LineSegmentDetection( int * n_out,
unsigned char * img, int X, int Y,
double scale, double sigma_scale, double quant,
double ang_th, double log_eps, double density_th,
float scale, float sigma_scale, float quant,
float ang_th, float log_eps, float density_th,
int n_bins,
int ** reg_img, int * reg_x, int * reg_y );
@ -242,7 +235,7 @@ double * LineSegmentDetection( int * n_out,
'reg_img' image, when asked for.
Suggested value: NULL
@return A double array of size 7 x n_out, containing the list
@return A float array of size 7 x n_out, containing the list
of line segments detected. The array contains first
7 values of line segment number 1, then the 7 values
of line segment number 2, and so on, and it finish
@ -257,8 +250,8 @@ double * LineSegmentDetection( int * n_out,
line segment number 'n+1' are obtained with
'out[7*n+0]' to 'out[7*n+6]'.
*/
double * lsd_scale_region( int * n_out,
unsigned char * img, int X, int Y, double scale,
float * lsd_scale_region( int * n_out,
unsigned char * img, int X, int Y, float scale,
int ** reg_img, int * reg_x, int * reg_y );
/*----------------------------------------------------------------------------*/
@ -283,7 +276,7 @@ double * lsd_scale_region( int * n_out,
is applied.
Suggested value: 0.8
@return A double array of size 7 x n_out, containing the list
@return A float array of size 7 x n_out, containing the list
of line segments detected. The array contains first
7 values of line segment number 1, then the 7 values
of line segment number 2, and so on, and it finish
@ -298,7 +291,7 @@ double * lsd_scale_region( int * n_out,
line segment number 'n+1' are obtained with
'out[7*n+0]' to 'out[7*n+6]'.
*/
double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale);
float * lsd_scale(int * n_out, unsigned char * img, int X, int Y, float scale);
/*----------------------------------------------------------------------------*/
/** LSD Simple Interface
@ -314,7 +307,7 @@ double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
@param Y Y size of the image: the number of rows.
@return A double array of size 7 x n_out, containing the list
@return A float array of size 7 x n_out, containing the list
of line segments detected. The array contains first
7 values of line segment number 1, then the 7 values
of line segment number 2, and so on, and it finish
@ -329,7 +322,7 @@ double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
line segment number 'n+1' are obtained with
'out[7*n+0]' to 'out[7*n+6]'.
*/
double * lsd(int * n_out, unsigned char * img, int X, int Y);
float * lsd(int * n_out, unsigned char * img, int X, int Y);
/*----------------------------------------------------------------------------*/
@ -510,9 +503,9 @@ struct lsd_point {int16_t x,y;};
should be related to the cumulated rounding error in the chain of
computation. Here, as a simplification, a fixed factor is used.
*/
static int double_equal(double a, double b)
static int double_equal(float a, float b)
{
double abs_diff,aa,bb,abs_max;
float abs_diff,aa,bb,abs_max;
/* trivial case */
if( a == b ) return TRUE;
@ -522,21 +515,21 @@ static int double_equal(double a, double b)
bb = fabs(b);
abs_max = aa > bb ? aa : bb;
/* DBL_MIN is the smallest normalized number, thus, the smallest
number whose relative error is bounded by DBL_EPSILON. For
smaller numbers, the same quantization steps as for DBL_MIN
/* FLT_MIN is the smallest normalized number, thus, the smallest
number whose relative error is bounded by FLT_EPSILON. For
smaller numbers, the same quantization steps as for FLT_MIN
are used. Then, for smaller numbers, a meaningful "relative"
error should be computed by dividing the difference by DBL_MIN. */
if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
error should be computed by dividing the difference by FLT_MIN. */
if( abs_max < FLT_MIN ) abs_max = FLT_MIN;
/* equal if relative error <= factor x eps */
return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * FLT_EPSILON);
}
/*----------------------------------------------------------------------------*/
/** Computes Euclidean distance between point (x1,y1) and point (x2,y2).
*/
static double dist(double x1, double y1, double x2, double y2)
static float dist(float x1, float y1, float x2, float y2)
{
return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
}
@ -572,7 +565,7 @@ typedef struct ntuple_list_s
unsigned int size;
unsigned int max_size;
unsigned int dim;
double * values;
float * values;
} * ntuple_list;
/*----------------------------------------------------------------------------*/
@ -607,7 +600,7 @@ static ntuple_list new_ntuple_list(unsigned int dim)
n_tuple->dim = dim;
/* get memory for tuples */
n_tuple->values = (double *) malloc( dim*n_tuple->max_size * sizeof(double) );
n_tuple->values = (float *) malloc( dim*n_tuple->max_size * sizeof(float) );
if( n_tuple->values == NULL ) error("not enough memory.");
return n_tuple;
@ -626,16 +619,16 @@ static void enlarge_ntuple_list(ntuple_list n_tuple)
n_tuple->max_size *= 2;
/* realloc memory */
n_tuple->values = (double *) realloc( (void *) n_tuple->values,
n_tuple->dim * n_tuple->max_size * sizeof(double) );
n_tuple->values = (float *) realloc( (void *) n_tuple->values,
n_tuple->dim * n_tuple->max_size * sizeof(float) );
if( n_tuple->values == NULL ) error("not enough memory.");
}
/*----------------------------------------------------------------------------*/
/** Add a 7-tuple to an n-tuple list.
*/
static void add_7tuple( ntuple_list out, double v1, double v2, double v3,
double v4, double v5, double v6, double v7 )
static void add_7tuple( ntuple_list out, float v1, float v2, float v3,
float v4, float v5, float v6, float v7 )
{
/* check parameters */
if( out == NULL ) error("add_7tuple: invalid n-tuple input.");
@ -827,7 +820,7 @@ static image_int new_image_int_ini( unsigned int xsize, unsigned int ysize,
}
/*----------------------------------------------------------------------------*/
/** double image data type
/** float image data type
The pixel value at (x,y) is accessed by:
@ -837,7 +830,7 @@ static image_int new_image_int_ini( unsigned int xsize, unsigned int ysize,
*/
typedef struct image_double_s
{
double * data;
float * data;
unsigned int xsize,ysize;
} * image_double;
@ -865,7 +858,7 @@ static image_double new_image_double(unsigned int xsize, unsigned int ysize)
/* get memory */
image = (image_double) malloc( sizeof(struct image_double_s) );
if( image == NULL ) error("not enough memory.");
image->data = (double *) calloc( (size_t) (xsize*ysize), sizeof(double) );
image->data = (float *) calloc( (size_t) (xsize*ysize), sizeof(float) );
if( image->data == NULL ) error("not enough memory.");
/* set image size */
@ -880,7 +873,7 @@ static image_double new_image_double(unsigned int xsize, unsigned int ysize)
with the data pointed by 'data'.
*/
static image_double new_image_double_ptr( unsigned int xsize,
unsigned int ysize, double * data )
unsigned int ysize, float * data )
{
image_double image;
@ -914,10 +907,10 @@ static image_double new_image_double_ptr( unsigned int xsize,
in the middle point between values 'kernel->values[0]'
and 'kernel->values[1]'.
*/
static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
static void gaussian_kernel(ntuple_list kernel, float sigma, float mean)
{
double sum = 0.0;
double val;
float sum = 0.0;
float val;
unsigned int i;
/* check parameters */
@ -930,7 +923,7 @@ static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
kernel->size = 1;
for(i=0;i<kernel->dim;i++)
{
val = ( (double) i - mean ) / sigma;
val = ( (float) i - mean ) / sigma;
kernel->values[i] = exp( -0.5 * val * val );
sum += kernel->values[i];
}
@ -977,14 +970,14 @@ static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
in the x axis, and then the combined Gaussian kernel and sampling
in the y axis.
*/
static image_double gaussian_sampler( image_double in, double scale,
double sigma_scale )
static image_double gaussian_sampler( image_double in, float scale,
float sigma_scale )
{
image_double aux,out;
ntuple_list kernel;
unsigned int N,M,h,n,x,y,i;
int xc,yc,j,double_x_size,double_y_size;
double sigma,xx,yy,sum,prec;
float sigma,xx,yy,sum,prec;
/* check parameters */
if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
@ -994,8 +987,8 @@ static image_double gaussian_sampler( image_double in, double scale,
error("gaussian_sampler: 'sigma_scale' must be positive.");
/* compute new image size and get memory for images */
if( in->xsize * scale > (double) UINT_MAX ||
in->ysize * scale > (double) UINT_MAX )
if( in->xsize * scale > (float) UINT_MAX ||
in->ysize * scale > (float) UINT_MAX )
error("gaussian_sampler: the output image size exceeds the handled size.");
N = (unsigned int) ceil( in->xsize * scale );
M = (unsigned int) ceil( in->ysize * scale );
@ -1017,7 +1010,7 @@ static image_double gaussian_sampler( image_double in, double scale,
n = 1+2*h; /* kernel size */
kernel = new_ntuple_list(n);
/* auxiliary double image size variables */
/* auxiliary float image size variables */
double_x_size = (int) (2 * in->xsize);
double_y_size = (int) (2 * in->ysize);
@ -1029,11 +1022,11 @@ static image_double gaussian_sampler( image_double in, double scale,
xx is the corresponding x-value in the original size image.
xc is the integer value, the pixel coordinate of xx.
*/
xx = (double) x / scale;
xx = (float) x / scale;
/* coordinate (0.0,0.0) is in the center of pixel (0,0),
so the pixel with xc=0 get the values of xx from -0.5 to 0.5 */
xc = (int) floor( xx + 0.5 );
gaussian_kernel( kernel, sigma, (double) h + xx - (double) xc );
gaussian_kernel( kernel, sigma, (float) h + xx - (float) xc );
/* the kernel must be computed for each x because the fine
offset xx-xc is different in each case */
@ -1063,11 +1056,11 @@ static image_double gaussian_sampler( image_double in, double scale,
yy is the corresponding x-value in the original size image.
yc is the integer value, the pixel coordinate of xx.
*/
yy = (double) y / scale;
yy = (float) y / scale;
/* coordinate (0.0,0.0) is in the center of pixel (0,0),
so the pixel with yc=0 get the values of yy from -0.5 to 0.5 */
yc = (int) floor( yy + 0.5 );
gaussian_kernel( kernel, sigma, (double) h + yy - (double) yc );
gaussian_kernel( kernel, sigma, (float) h + yy - (float) yc );
/* the kernel must be computed for each y because the fine
offset yy-yc is different in each case */
@ -1118,13 +1111,13 @@ static image_double gaussian_sampler( image_double in, double scale,
- a pointer 'mem_p' to the memory used by 'list_p' to be able to
free the memory when it is not used anymore.
*/
static image_int ll_angle( image_char in, double threshold,
static image_int ll_angle( image_char in, float threshold,
struct coorlist ** list_p, void ** mem_p,
image_int * modgrad, unsigned int n_bins )
{
image_int g;
unsigned int n,p,x,y,adr,i;
double com1,com2,gx,gy,norm,norm2;
float com1,com2,gx,gy,norm,norm2;
/* the rest of the variables are used for pseudo-ordering
the gradient magnitude values */
int list_count = 0;
@ -1133,7 +1126,7 @@ static image_int ll_angle( image_char in, double threshold,
struct coorlist ** range_l_e; /* array of pointers to end of bin list */
struct coorlist * start;
struct coorlist * end;
double max_grad = 0.0;
float max_grad = 0.0;
/* check parameters */
if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
@ -1215,7 +1208,7 @@ static image_int ll_angle( image_char in, double threshold,
norm = (*modgrad)->data[y*p+x];
/* store the point in the right bin according to its norm */
i = (unsigned int) (norm * (double) n_bins / max_grad);
i = (unsigned int) (norm * (float) n_bins / max_grad);
if( i >= n_bins ) i = n_bins-1;
if( range_l_e[i] == NULL )
range_l_s[i] = range_l_e[i] = list+list_count++;
@ -1259,10 +1252,10 @@ static image_int ll_angle( image_char in, double threshold,
/*----------------------------------------------------------------------------*/
/** Is point (x,y) aligned to angle theta, up to precision 'prec'?
*/
static int isaligned( int x, int y, image_int angles, double theta,
double prec )
static int isaligned( int x, int y, image_int angles, float theta,
float prec )
{
double a;
float a;
/* check parameters */
if( angles == NULL || angles->data == NULL )
@ -1297,7 +1290,7 @@ static int isaligned( int x, int y, image_int angles, double theta,
/*----------------------------------------------------------------------------*/
/** Absolute value angle difference.
*/
static double angle_diff(double a, double b)
static float angle_diff(float a, float b)
{
a -= b;
while( a <= -M_PI ) a += M_2__PI;
@ -1309,7 +1302,7 @@ static double angle_diff(double a, double b)
/*----------------------------------------------------------------------------*/
/** Signed angle difference.
*/
static double angle_diff_signed(double a, double b)
static float angle_diff_signed(float a, float b)
{
a -= b;
while( a <= -M_PI ) a += M_2__PI;
@ -1346,19 +1339,19 @@ static double angle_diff_signed(double a, double b)
q5 = 83.8676043424,
q6 = 2.50662827511.
*/
static double log_gamma_lanczos(double x)
static float log_gamma_lanczos(float x)
{
static double q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
static float q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
8687.24529705, 1168.92649479, 83.8676043424,
2.50662827511 };
double a = (x+0.5) * log(x+5.5) - (x+5.5);
double b = 0.0;
float a = (x+0.5) * log(x+5.5) - (x+5.5);
float b = 0.0;
int n;
for(n=0;n<7;n++)
{
a -= log( x + (double) n );
b += q[n] * pow( x, (double) n );
a -= log( x + (float) n );
b += q[n] * pow( x, (float) n );
}
return a + log(b);
}
@ -1380,7 +1373,7 @@ static double log_gamma_lanczos(double x)
@f]
This formula is a good approximation when x > 15.
*/
static double log_gamma_windschitl(double x)
static float log_gamma_windschitl(float x)
{
return 0.918938533204673 + (x-0.5)*log(x) - x
+ 0.5*x*log( x*sinh(1/x) + 1/(810.0*pow(x,6.0)) );
@ -1440,11 +1433,11 @@ static double log_gamma_windschitl(double x)
of the terms are neglected based on a bound to the error obtained
(an error of 10% in the result is accepted).
*/
static double nfa(int n, int k, double p, double logNT)
static float nfa(int n, int k, float p, float logNT)
{
// static double inv[TABSIZE]; /* table to keep computed inverse values */
double tolerance = 0.1; /* an error of 10% in the result is accepted */
double log1term,term,bin_term,mult_term,bin_tail,err,p_term;
// static float inv[TABSIZE]; /* table to keep computed inverse values */
float tolerance = 0.1; /* an error of 10% in the result is accepted */
float log1term,term,bin_term,mult_term,bin_tail,err,p_term;
int i;
/* check parameters */
@ -1453,7 +1446,7 @@ static double nfa(int n, int k, double p, double logNT)
/* trivial cases */
if( n==0 || k==0 ) return -logNT;
if( n==k ) return -logNT - (double) n * log10(p);
if( n==k ) return -logNT - (float) n * log10(p);
/* probability term */
p_term = p / (1.0-p);
@ -1466,15 +1459,15 @@ static double nfa(int n, int k, double p, double logNT)
bincoef(n,k) = gamma(n+1) / ( gamma(k+1) * gamma(n-k+1) ).
We use this to compute the first term. Actually the log of it.
*/
log1term = log_gamma( (double) n + 1.0 ) - log_gamma( (double) k + 1.0 )
- log_gamma( (double) (n-k) + 1.0 )
+ (double) k * log(p) + (double) (n-k) * log(1.0-p);
log1term = log_gamma( (float) n + 1.0 ) - log_gamma( (float) k + 1.0 )
- log_gamma( (float) (n-k) + 1.0 )
+ (float) k * log(p) + (float) (n-k) * log(1.0-p);
term = exp(log1term);
/* in some cases no more computations are needed */
if( double_equal(term,0.0) ) /* the first term is almost zero */
{
if( (double) k > (double) n * p ) /* at begin or end of the tail? */
if( (float) k > (float) n * p ) /* at begin or end of the tail? */
return -log1term / M_LN10 - logNT; /* end: use just the first term */
else
return -logNT; /* begin: the tail is roughly 1 */
@ -1497,10 +1490,10 @@ static double nfa(int n, int k, double p, double logNT)
because divisions are expensive.
p/(1-p) is computed only once and stored in 'p_term'.
*/
// bin_term = (double) (n-i+1) * ( i<TABSIZE ?
// ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (double) i ) ) :
// 1.0 / (double) i );
bin_term = (double) (n-i+1) * ( 1.0 / (double) i );
// bin_term = (float) (n-i+1) * ( i<TABSIZE ?
// ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (float) i ) ) :
// 1.0 / (float) i );
bin_term = (float) (n-i+1) * ( 1.0 / (float) i );
mult_term = bin_term * p_term;
term *= mult_term;
@ -1511,7 +1504,7 @@ static double nfa(int n, int k, double p, double logNT)
Then, the error on the binomial tail when truncated at
the i term can be bounded by a geometric series of form
term_i * sum mult_term_i^j. */
err = term * ( ( 1.0 - pow( mult_term, (double) (n-i+1) ) ) /
err = term * ( ( 1.0 - pow( mult_term, (float) (n-i+1) ) ) /
(1.0-mult_term) - 1.0 );
/* One wants an error at most of tolerance*final_result, or:
@ -1538,13 +1531,13 @@ static double nfa(int n, int k, double p, double logNT)
*/
struct rect
{
double x1,y1,x2,y2; /* first and second point of the line segment */
double width; /* rectangle width */
double x,y; /* center of the rectangle */
double theta; /* angle */
double dx,dy; /* (dx,dy) is vector oriented as the line segment */
double prec; /* tolerance angle */
double p; /* probability of a point with angle within 'prec' */
float x1,y1,x2,y2; /* first and second point of the line segment */
float width; /* rectangle width */
float x,y; /* center of the rectangle */
float theta; /* angle */
float dx,dy; /* (dx,dy) is vector oriented as the line segment */
float prec; /* tolerance angle */
float p; /* probability of a point with angle within 'prec' */
};
/*----------------------------------------------------------------------------*/
@ -1628,9 +1621,9 @@ static void rect_copy(struct rect * in, struct rect * out)
*/
typedef struct
{
double vx[4]; /* rectangle's corner X coordinates in circular order */
double vy[4]; /* rectangle's corner Y coordinates in circular order */
double ys,ye; /* start and end Y values of current 'column' */
float vx[4]; /* rectangle's corner X coordinates in circular order */
float vy[4]; /* rectangle's corner Y coordinates in circular order */
float ys,ye; /* start and end Y values of current 'column' */
int x,y; /* coordinates of currently explored pixel */
} rect_iter;
@ -1644,7 +1637,7 @@ typedef struct
- x1 <= x
- x <= x2
*/
static double inter_low(double x, double x1, double y1, double x2, double y2)
static float inter_low(float x, float x1, float y1, float x2, float y2)
{
/* check parameters */
// if( x1 > x2 || x < x1 || x > x2 )
@ -1654,7 +1647,7 @@ static double inter_low(double x, double x1, double y1, double x2, double y2)
if( double_equal(x1,x2) && y1<y2 ) return y1;
if( double_equal(x1,x2) && y1>y2 ) return y2;
// return y1 + (x-x1) * (y2-y1) / (x2-x1);
double result = y1 + (x-x1) * (y2-y1) / (x2-x1);
float result = y1 + (x-x1) * (y2-y1) / (x2-x1);
if (isnan(result) || isinf(result)) return (y1<y2) ? y1 : ((y1>y2) ? y2 : 0);
return result;
}
@ -1669,7 +1662,7 @@ static double inter_low(double x, double x1, double y1, double x2, double y2)
- x1 <= x
- x <= x2
*/
static double inter_hi(double x, double x1, double y1, double x2, double y2)
static float inter_hi(float x, float x1, float y1, float x2, float y2)
{
/* check parameters */
// if( x1 > x2 || x < x1 || x > x2 )
@ -1679,7 +1672,7 @@ static double inter_hi(double x, double x1, double y1, double x2, double y2)
if( double_equal(x1,x2) && y1<y2 ) return y2;
if( double_equal(x1,x2) && y1>y2 ) return y1;
// return y1 + (x-x1) * (y2-y1) / (x2-x1);
double result = y1 + (x-x1) * (y2-y1) / (x2-x1);
float result = y1 + (x-x1) * (y2-y1) / (x2-x1);
if (isnan(result) || isinf(result)) return (y1<y2) ? y2 : ((y1>y2) ? y1 : 0);
return result;
}
@ -1706,7 +1699,7 @@ static int ri_end(rect_iter * i)
/* if the current x value is larger than the largest
x value in the rectangle (vx[2]), we know the full
exploration of the rectangle is finished. */
return (double)(i->x) > i->vx[2];
return (float)(i->x) > i->vx[2];
}
/*----------------------------------------------------------------------------*/
@ -1726,7 +1719,7 @@ static void ri_inc(rect_iter * i)
/* if the end of the current 'column' is reached,
and it is not the end of exploration,
advance to the next 'column' */
while( (double) (i->y) > i->ye && !ri_end(i) )
while( (float) (i->y) > i->ye && !ri_end(i) )
{
/* increase x, next 'column' */
i->x++;
@ -1749,10 +1742,10 @@ static void ri_inc(rect_iter * i)
or last 'columns') then we pick the lower value of the side
by using 'inter_low'.
*/
if( (double) i->x < i->vx[3] )
i->ys = inter_low((double)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
if( (float) i->x < i->vx[3] )
i->ys = inter_low((float)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
else
i->ys = inter_low((double)i->x,i->vx[3],i->vy[3],i->vx[2],i->vy[2]);
i->ys = inter_low((float)i->x,i->vx[3],i->vy[3],i->vx[2],i->vy[2]);
/* update upper y limit (end) for the new 'column'.
@ -1769,10 +1762,10 @@ static void ri_inc(rect_iter * i)
or last 'columns') then we pick the lower value of the side
by using 'inter_low'.
*/
if( (double)i->x < i->vx[1] )
i->ye = inter_hi((double)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
if( (float)i->x < i->vx[1] )
i->ye = inter_hi((float)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
else
i->ye = inter_hi((double)i->x,i->vx[1],i->vy[1],i->vx[2],i->vy[2]);
i->ye = inter_hi((float)i->x,i->vx[1],i->vy[1],i->vx[2],i->vy[2]);
/* new y */
i->y = (int) ceil(i->ys);
@ -1786,7 +1779,7 @@ static void ri_inc(rect_iter * i)
*/
static rect_iter * ri_ini(struct rect * r)
{
double vx[4],vy[4];
float vx[4],vy[4];
int n,offset;
rect_iter * i;
@ -1844,7 +1837,7 @@ static rect_iter * ri_ini(struct rect * r)
*/
i->x = (int) ceil(i->vx[0]) - 1;
i->y = (int) ceil(i->vy[0]);
i->ys = i->ye = -DBL_MAX;
i->ys = i->ye = -FLT_MAX;
/* advance to the first pixel */
ri_inc(i);
@ -1855,7 +1848,7 @@ static rect_iter * ri_ini(struct rect * r)
/*----------------------------------------------------------------------------*/
/** Compute a rectangle's NFA value.
*/
static double rect_nfa(struct rect * rec, image_int angles, double logNT)
static float rect_nfa(struct rect * rec, image_int angles, float logNT)
{
rect_iter * i;
int pts = 0;
@ -1941,13 +1934,13 @@ static double rect_nfa(struct rect * rec, image_int angles, double logNT)
When |Ixx| > |Iyy| we use the first, otherwise the second (just to
get better numeric precision).
*/
static double get_theta( struct lsd_point * reg, int reg_size, double x, double y,
image_int modgrad, double reg_angle, double prec )
static float get_theta( struct lsd_point * reg, int reg_size, float x, float y,
image_int modgrad, float reg_angle, float prec )
{
double lambda,theta,weight;
double Ixx = 0.0;
double Iyy = 0.0;
double Ixy = 0.0;
float lambda,theta,weight;
float Ixx = 0.0;
float Iyy = 0.0;
float Ixy = 0.0;
int i;
/* check parameters */
@ -1961,9 +1954,9 @@ static double get_theta( struct lsd_point * reg, int reg_size, double x, double
for(i=0; i<reg_size; i++)
{
weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
Ixx += ( (double) reg[i].y - y ) * ( (double) reg[i].y - y ) * weight;
Iyy += ( (double) reg[i].x - x ) * ( (double) reg[i].x - x ) * weight;
Ixy -= ( (double) reg[i].x - x ) * ( (double) reg[i].y - y ) * weight;
Ixx += ( (float) reg[i].y - y ) * ( (float) reg[i].y - y ) * weight;
Iyy += ( (float) reg[i].x - x ) * ( (float) reg[i].x - x ) * weight;
Ixy -= ( (float) reg[i].x - x ) * ( (float) reg[i].y - y ) * weight;
}
if( double_equal(Ixx,0.0) && double_equal(Iyy,0.0) && double_equal(Ixy,0.0) )
error("get_theta: null inertia matrix.");
@ -1985,10 +1978,10 @@ static double get_theta( struct lsd_point * reg, int reg_size, double x, double
/** Computes a rectangle that covers a region of points.
*/
static void region2rect( struct lsd_point * reg, int reg_size,
image_int modgrad, double reg_angle,
double prec, double p, struct rect * rec )
image_int modgrad, float reg_angle,
float prec, float p, struct rect * rec )
{
double x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
float x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
int i;
/* check parameters */
@ -2012,8 +2005,8 @@ static void region2rect( struct lsd_point * reg, int reg_size,
for(i=0; i<reg_size; i++)
{
weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
x += (double) reg[i].x * weight;
y += (double) reg[i].y * weight;
x += (float) reg[i].x * weight;
y += (float) reg[i].y * weight;
sum += weight;
}
if( sum <= 0.0 ) error("region2rect: weights sum equal to zero.");
@ -2040,8 +2033,8 @@ static void region2rect( struct lsd_point * reg, int reg_size,
l_min = l_max = w_min = w_max = 0.0;
for(i=0; i<reg_size; i++)
{
l = ( (double) reg[i].x - x) * dx + ( (double) reg[i].y - y) * dy;
w = -( (double) reg[i].x - x) * dy + ( (double) reg[i].y - y) * dx;
l = ( (float) reg[i].x - x) * dx + ( (float) reg[i].y - y) * dy;
w = -( (float) reg[i].x - x) * dy + ( (float) reg[i].y - y) * dx;
if( l > l_max ) l_max = l;
if( l < l_min ) l_min = l;
@ -2078,10 +2071,10 @@ static void region2rect( struct lsd_point * reg, int reg_size,
tolerance 'prec', starting at point (x,y).
*/
static void region_grow( int x, int y, image_int angles, struct lsd_point * reg,
int * reg_size, double * reg_angle, image_char used,
double prec )
int * reg_size, float * reg_angle, image_char used,
float prec )
{
double sumdx,sumdy;
float sumdx,sumdy;
int xx,yy,i;
/* check parameters */
@ -2131,13 +2124,13 @@ static void region_grow( int x, int y, image_int angles, struct lsd_point * reg,
/** Try some rectangles variations to improve NFA value. Only if the
rectangle is not meaningful (i.e., log_nfa <= log_eps).
*/
static double rect_improve( struct rect * rec, image_int angles,
double logNT, double log_eps )
static float rect_improve( struct rect * rec, image_int angles,
float logNT, float log_eps )
{
struct rect r;
double log_nfa,log_nfa_new;
double delta = 0.5;
double delta_2 = delta / 2.0;
float log_nfa,log_nfa_new;
float delta = 0.5;
float delta_2 = delta / 2.0;
int n;
log_nfa = rect_nfa(rec,angles,logNT);
@ -2245,12 +2238,12 @@ static double rect_improve( struct rect * rec, image_int angles,
density of region points or to discard the region if too small.
*/
static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
image_int modgrad, double reg_angle,
double prec, double p, struct rect * rec,
image_int modgrad, float reg_angle,
float prec, float p, struct rect * rec,
image_char used, image_int angles,
double density_th )
float density_th )
{
double density,rad1,rad2,rad,xc,yc;
float density,rad1,rad2,rad,xc,yc;
int i;
/* check parameters */
@ -2265,15 +2258,15 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
error("reduce_region_radius: invalid image 'angles'.");
/* compute region points density */
density = (double) *reg_size /
density = (float) *reg_size /
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
/* if the density criterion is satisfied there is nothing to do */
if( density >= density_th ) return TRUE;
/* compute region's radius */
xc = (double) reg[0].x;
yc = (double) reg[0].y;
xc = (float) reg[0].x;
yc = (float) reg[0].y;
rad1 = dist( xc, yc, rec->x1, rec->y1 );
rad2 = dist( xc, yc, rec->x2, rec->y2 );
rad = rad1 > rad2 ? rad1 : rad2;
@ -2285,7 +2278,7 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
/* remove points from the region and update 'used' map */
for(i=0; i<*reg_size; i++)
if( dist( xc, yc, (double) reg[i].x, (double) reg[i].y ) > rad )
if( dist( xc, yc, (float) reg[i].x, (float) reg[i].y ) > rad )
{
/* point not kept, mark it as NOTUSED */
used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
@ -2304,7 +2297,7 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
/* re-compute region points density */
density = (double) *reg_size /
density = (float) *reg_size /
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
}
@ -2323,10 +2316,10 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
'reduce_region_radius' is called to try to satisfy this condition.
*/
static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
double reg_angle, double prec, double p, struct rect * rec,
image_char used, image_int angles, double density_th )
float reg_angle, float prec, float p, struct rect * rec,
image_char used, image_int angles, float density_th )
{
double angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
float angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
int i,n;
/* check parameters */
@ -2340,7 +2333,7 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
error("refine: invalid image 'angles'.");
/* compute region points density */
density = (double) *reg_size /
density = (float) *reg_size /
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
/* if the density criterion is satisfied there is nothing to do */
@ -2349,15 +2342,15 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
/*------ First try: reduce angle tolerance ------*/
/* compute the new mean angle and tolerance */
xc = (double) reg[0].x;
yc = (double) reg[0].y;
xc = (float) reg[0].x;
yc = (float) reg[0].y;
ang_c = degToRad(angles->data[ reg[0].x + reg[0].y * angles->xsize ]);
sum = s_sum = 0.0;
n = 0;
for(i=0; i<*reg_size; i++)
{
used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
if( dist( xc, yc, (double) reg[i].x, (double) reg[i].y ) < rec->width )
if( dist( xc, yc, (float) reg[i].x, (float) reg[i].y ) < rec->width )
{
angle = degToRad(angles->data[ reg[i].x + reg[i].y * angles->xsize ]);
ang_d = angle_diff_signed(angle,ang_c);
@ -2366,8 +2359,8 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
++n;
}
}
mean_angle = sum / (double) n;
tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (double) n
mean_angle = sum / (float) n;
tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (float) n
+ mean_angle*mean_angle ); /* 2 * standard deviation */
/* find a new region from the same starting point and new angle tolerance */
@ -2380,7 +2373,7 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
/* re-compute region points density */
density = (double) *reg_size /
density = (float) *reg_size /
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
/*------ Second try: reduce region radius ------*/
@ -2400,16 +2393,16 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
/*----------------------------------------------------------------------------*/
/** LSD full interface.
*/
double * LineSegmentDetection( int * n_out,
float * LineSegmentDetection( int * n_out,
unsigned char * img, int X, int Y,
double scale, double sigma_scale, double quant,
double ang_th, double log_eps, double density_th,
float scale, float sigma_scale, float quant,
float ang_th, float log_eps, float density_th,
int n_bins,
int ** reg_img, int * reg_x, int * reg_y )
{
image_char image;
ntuple_list out = new_ntuple_list(7);
double * return_value;
float * return_value;
image_int scaled_image,angles,modgrad;
image_char used;
image_int region = NULL;
@ -2419,7 +2412,7 @@ double * LineSegmentDetection( int * n_out,
struct lsd_point * reg;
int reg_size,min_reg_size,i;
unsigned int xsize,ysize;
double rho,reg_angle,prec,p,log_nfa,logNT;
float rho,reg_angle,prec,p,log_nfa,logNT;
int ls_count = 0; /* line segments are numbered 1,2,3,... */
@ -2469,7 +2462,7 @@ double * LineSegmentDetection( int * n_out,
whose logarithm value is
log10(11) + 5/2 * (log10(X) + log10(Y)).
*/
logNT = 5.0 * ( log10( (double) xsize ) + log10( (double) ysize ) ) / 2.0
logNT = 5.0 * ( log10( (float) xsize ) + log10( (float) ysize ) ) / 2.0
+ log10(11.0);
min_reg_size = (int) (-logNT/log10(p)); /* minimal number of points in region
that can give a meaningful event */
@ -2487,7 +2480,7 @@ double * LineSegmentDetection( int * n_out,
for(; list_p != NULL; list_p = list_p->next )
if( used->data[ list_p->x + list_p->y * used->xsize ] == NOTUSED &&
degToRad(angles->data[ list_p->x + list_p->y * angles->xsize ]) != NOTDEF )
/* there is no risk of double comparison problems here
/* there is no risk of float comparison problems here
because we are only interested in the exact NOTDEF value */
{
/* find the region of connected point and ~equal angle */
@ -2587,18 +2580,18 @@ double * LineSegmentDetection( int * n_out,
/*----------------------------------------------------------------------------*/
/** LSD Simple Interface with Scale and Region output.
*/
double * lsd_scale_region( int * n_out,
unsigned char * img, int X, int Y, double scale,
float * lsd_scale_region( int * n_out,
unsigned char * img, int X, int Y, float scale,
int ** reg_img, int * reg_x, int * reg_y )
{
/* LSD parameters */
double sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
float sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
sigma = sigma_scale/scale. */
double quant = 2.0; /* Bound to the quantization error on the
float quant = 2.0; /* Bound to the quantization error on the
gradient norm. */
double ang_th = 22.5; /* Gradient angle tolerance in degrees. */
double log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
double density_th = 0.7; /* Minimal density of region points in rectangle. */
float ang_th = 22.5; /* Gradient angle tolerance in degrees. */
float log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
float density_th = 0.7; /* Minimal density of region points in rectangle. */
int n_bins = 1024; /* Number of bins in pseudo-ordering of gradient
modulus. */
@ -2610,7 +2603,7 @@ double * lsd_scale_region( int * n_out,
/*----------------------------------------------------------------------------*/
/** LSD Simple Interface with Scale.
*/
double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
float * lsd_scale(int * n_out, unsigned char * img, int X, int Y, float scale)
{
return lsd_scale_region(n_out,img,X,Y,scale,NULL,NULL,NULL);
}
@ -2618,10 +2611,10 @@ double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
/*----------------------------------------------------------------------------*/
/** LSD Simple Interface.
*/
double * lsd(int * n_out, unsigned char * img, int X, int Y)
float * lsd(int * n_out, unsigned char * img, int X, int Y)
{
/* LSD parameters */
double scale = 0.8; /* Scale the image by Gaussian filter to 'scale'. */
float scale = 0.8; /* Scale the image by Gaussian filter to 'scale'. */
return lsd_scale(n_out,img,X,Y,scale);
}
@ -2672,7 +2665,7 @@ void imlib_lsd_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, u
}
int n_ls;
double *ls = LineSegmentDetection(&n_ls, grayscale_image_tmp, roi->w, roi->h, 0.8, 0.6, 2.0, 22.5, 0.0, 0.7, 1024, NULL, NULL, NULL);
float *ls = LineSegmentDetection(&n_ls, grayscale_image_tmp, roi->w, roi->h, 0.8, 0.6, 2.0, 22.5, 0.0, 0.7, 1024, NULL, NULL, NULL);
list_init(out, sizeof(find_lines_list_lnk_data_t));
for (int i = 0, j = n_ls; i < j; i++) {