Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions WebARKit/WebARKitVideoLuma.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <WebARKitVideoLuma.h>

namespace webarkit {

WebARKitLumaInfo *webarkitVideoLumaInit(int xsize, int ysize, bool simd128) {
WebARKitLumaInfo *vli = new WebARKitLumaInfo;

if (!vli) {
webarkitLOGe("Out of memory!!");
return nullptr;
}
vli->xsize = xsize;
vli->ysize = ysize;
vli->buffSize = xsize * ysize;
vli->simd128 = simd128;
vli->buff = std::make_unique<uint8_t[]>(vli->buffSize);
if (!vli->buff) {
webarkitLOGe("Out of memory!!\n");
delete vli;
return nullptr;
}

return vli;
}

uint8_t *__restrict webarkitVideoLuma(WebARKitLumaInfo *vli,
const uint8_t *__restrict dataPtr) {
//unsigned int p, q;

if (vli->simd128 == true) {
#ifdef __wasm_simd128__
webarkitVideoLumaRGBAtoLuma_Emscripten_simd128(
vli->buff.get(), (unsigned char *__restrict)dataPtr, vli->buffSize);
return vli->buff.get();
#else
webarkitVideoLuma_default(vli->buff.get(), (unsigned char *__restrict)dataPtr, vli->buffSize);
return vli->buff.get();
#endif
} else {
webarkitVideoLuma_default(vli->buff.get(), (unsigned char *__restrict)dataPtr, vli->buffSize);
return vli->buff.get();
}
}

int webarkitVideoLumaFinal(WebARKitLumaInfo **vli_p) {
if (!vli_p)
return -1;
if (!*vli_p)
return 0;

delete *vli_p;
*vli_p = nullptr;

return 0;
}

static void webarkitVideoLuma_default(uint8_t *__restrict dest,
uint8_t *__restrict src, int32_t numPixels) {
unsigned int p, q;
webarkitLOGd("Using webarkitVideoLuma_default for luma conversion!!!");
q = 0;
for (p = 0; p < numPixels; p++) {
dest[p] = (R8_CCIR601 * src[q + 0] + G8_CCIR601 * src[q + 1] +
B8_CCIR601 * src[q + 2]) >>
8;
q += 4;
}
}

#ifdef __wasm_simd128__
static void webarkitVideoLumaRGBAtoLuma_Emscripten_simd128(uint8_t *__restrict dest,
uint8_t *__restrict src,
int32_t numPixels) {

webarkitLOGd("Using webarkitVideoLumaRGBAtoLuma_Emscripten_simd128 for Luma conversion !!!");

v128_t *pin = (v128_t *)src;
int64_t *pout = (int64_t *)dest;
int numPixelsDiv8 = numPixels / 8;

v128_t maskRedBlue = wasm_i32x4_splat(0x00FF00FF);
v128_t scaleRedBlue =
wasm_i32x4_splat((uint32_t)B8_CCIR601 << 16 | R8_CCIR601);
v128_t scaleGreen = wasm_i32x4_splat(G8_CCIR601);
do {
v128_t pixels1 = wasm_v128_load(pin); // Load 16 bytes (4 pixels) from src
v128_t pixels2 = wasm_v128_load(pin + 1);
pin += 2;

v128_t g1 = wasm_u16x8_shr(pixels1, 8);
v128_t g2 = wasm_u16x8_shr(pixels2, 8);

v128_t rb1 = wasm_v128_and(pixels1, maskRedBlue);
v128_t rb2 = wasm_v128_and(pixels2, maskRedBlue);

g1 = wasm_i32x4_dot_i16x8(g1, scaleGreen);
g2 = wasm_i32x4_dot_i16x8(g2, scaleGreen);
rb1 = wasm_i32x4_dot_i16x8(rb1, scaleRedBlue);
rb2 = wasm_i32x4_dot_i16x8(rb2, scaleRedBlue);

v128_t y1 = wasm_i32x4_add(g1, rb1);
v128_t y2 = wasm_i32x4_add(g2, rb2);

y1 = wasm_u32x4_shr(y1, 8);
y2 = wasm_u32x4_shr(y2, 8);

v128_t y = wasm_i16x8_narrow_i32x4(y1, y2);
y = wasm_u8x16_narrow_i16x8(y, y);

*pout = wasm_i64x2_extract_lane(y, 0);

pout++;
numPixelsDiv8--;
} while (numPixelsDiv8);
}
#endif

} // namespace webarkit
47 changes: 47 additions & 0 deletions WebARKit/include/WebARKitVideoLuma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef WEBARKITVIDEOLUMA_H
#define WEBARKITVIDEOLUMA_H

#include <cstdint>
#include <cstdbool>
#include <memory>
#include <WebARKit/WebARKitLog.h>

#ifdef __wasm_simd128__
#include <wasm_simd128.h> // For SIMD operations
#endif

namespace webarkit {

// CCIR 601 recommended values. See
// http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC11 .
const uint8_t R8_CCIR601 = 77;
const uint8_t G8_CCIR601 = 150;
const uint8_t B8_CCIR601 = 29;

struct WebARKitLumaInfo {
int xsize;
int ysize;
int buffSize;
bool simd128;
std::unique_ptr<uint8_t[]> buff;
};

#ifdef __wasm_simd128__
static void webarkitVideoLumaRGBAtoLuma_Emscripten_simd128(uint8_t *__restrict dest,
uint8_t *__restrict src,
int32_t numPixels);
#endif

static void webarkitVideoLuma_default(uint8_t *__restrict dest, uint8_t *__restrict src,
int32_t numPixels);

WebARKitLumaInfo *webarkitVideoLumaInit(int xsize, int ysize, bool simd128);

uint8_t *__restrict webarkitVideoLuma(WebARKitLumaInfo *vli,
const uint8_t *__restrict dataPtr);

int webarkitVideoLumaFinal(WebARKitLumaInfo **vli_p);

} // namespace webarkit

#endif // WEBARKITVIDEOLUMA_H
10 changes: 5 additions & 5 deletions include/AR/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ typedef enum {
#undef ARVIDEO_INPUT_DEFAULT_1394
#undef ARVIDEO_INPUT_DEFAULT_GSTREAMER
#undef ARVIDEO_INPUT_DEFAULT_IMAGE
#undef ARVIDEO_INPUT_DEFAULT_DUMMY
#define ARVIDEO_INPUT_DEFAULT_DUMMY

// Other Linux-only configuration.
#define HAVE_LIBJPEG 1
Expand Down Expand Up @@ -358,7 +358,7 @@ typedef enum {
#undef ARVIDEO_INPUT_WINDOWS_MEDIA_CAPTURE

// Default input module. This is edited by the configure script.
#undef ARVIDEO_INPUT_DEFAULT_DUMMY
#define ARVIDEO_INPUT_DEFAULT_DUMMY
#undef ARVIDEO_INPUT_DEFAULT_IMAGE
#undef ARVIDEO_INPUT_DEFAULT_WINDOWS_MEDIA_FOUNDATION
#undef ARVIDEO_INPUT_DEFAULT_WINDOWS_MEDIA_CAPTURE
Expand Down Expand Up @@ -408,7 +408,7 @@ typedef enum {
#undef ARVIDEO_INPUT_DUMMY
#define ARVIDEO_INPUT_ANDROID
#undef ARVIDEO_INPUT_IMAGE
#undef ARVIDEO_INPUT_DEFAULT_DUMMY
#define ARVIDEO_INPUT_DEFAULT_DUMMY
#define ARVIDEO_INPUT_DEFAULT_ANDROID
#undef ARVIDEO_INPUT_DEFAULT_IMAGE

Expand Down Expand Up @@ -459,7 +459,7 @@ typedef enum {
#undef ARVIDEO_INPUT_DUMMY
#define ARVIDEO_INPUT_IMAGE
#define ARVIDEO_INPUT_DEFAULT_AVFOUNDATION
#undef ARVIDEO_INPUT_DEFAULT_DUMMY
#define ARVIDEO_INPUT_DEFAULT_DUMMY
#undef ARVIDEO_INPUT_DEFAULT_IMAGE
#define HAVE_LIBJPEG 1
#define USE_OPENGL_ES 1
Expand All @@ -476,7 +476,7 @@ typedef enum {
#define ARVIDEO_INPUT_DUMMY
#define ARVIDEO_INPUT_IMAGE
#define ARVIDEO_INPUT_DEFAULT_AVFOUNDATION
#undef ARVIDEO_INPUT_DEFAULT_DUMMY
#define ARVIDEO_INPUT_DEFAULT_DUMMY
#undef ARVIDEO_INPUT_DEFAULT_IMAGE
#define HAVE_LIBJPEG 1
#define HAVE_INTEL_SIMD 1
Expand Down
1 change: 1 addition & 0 deletions include/WebARKit/WebARKitLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ void webarkitLOGw(const std::string &message, const char * format);

void webarkitLOGw(const std::string &message, int format);

void webarkitLOGd(const std::string &message);

#endif // #ifndef WEBARKIT_LOG_H
2 changes: 1 addition & 1 deletion lib/SRC/AR2/featureMap.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ AR2FeatureMapT *ar2GenFeatureMap( AR2ImageT *image,
fp2++;
}
for( j = 1; j < ysize-1; j++ ) {
ARLOGi("\r%4d/%4d.", j+1, ysize); fflush(stdout);
ARLOGd("\r%4d/%4d.", j+1, ysize); fflush(stdout);
*(fp++) = 1.0f;
fp2++;
for( i = 1; i < xsize-1; i++ ) {
Expand Down
13 changes: 13 additions & 0 deletions lib/SRC/ARUtil/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
# define snprintf _snprintf
#endif

#ifdef __EMSCRIPTEN__
#include <emscripten/console.h>
#endif

//
// Global required for logging functions.
//
Expand Down Expand Up @@ -201,7 +205,16 @@ void arLogv(const char *tag, const int logLevel, const char *format, va_list ap)
os_log_with_type(OS_LOG_DEFAULT, type, "%{public}s", buf);
}
#else

#ifdef __EMSCRIPTEN__
if(logLevel == AR_LOG_LEVEL_ERROR)
emscripten_console_error(buf);
else
emscripten_console_warn(buf);
#else
fprintf(stderr, "%s", buf);
#endif

#endif
}
free(buf);
Expand Down
5 changes: 3 additions & 2 deletions lib/SRC/KPM/FreakMatcher/framework/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
# define DEBUG_BLOCK(X)
#endif

#define isnan(x) ((x) != (x))
/*#define isnan(x) ((x) != (x))
#define isinf(x) (!isnan(x) && isnan(x - x))
#define ASSERT_NAN(x) ASSERT(!isnan(x), "NaN")
#define ASSERT_INF(x) ASSERT(!isinf(x), "INF")
#define ASSERT_INF(x) ASSERT(!isinf(x), "INF")
*/
13 changes: 11 additions & 2 deletions lib/SRC/KPM/FreakMatcher/matchers/binary_hierarchical_clustering.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

#include "kmedoids.h"

#include <unordered_map>
#include <map>
#include <queue>

namespace vision {
Expand Down Expand Up @@ -214,7 +214,16 @@ namespace vision {
typedef Node<NUM_BYTES_PER_FEATURE> node_t;
typedef std::unique_ptr<node_t> node_ptr_t;
typedef BinarykMedoids<NUM_BYTES_PER_FEATURE> kmedoids_t;
typedef std::unordered_map<int, std::vector<int> > cluster_map_t;
// std::map (not std::unordered_map): BHC tree construction
// iterates this map to build the topology of clusters. With
// unordered_map, the resulting tree's child ordering varied
// across STL implementations and produced different BHC
// topologies on different platforms, which propagated into
// different inlier sets and homographies. std::map's
// ascending-key iteration makes BHC tree topology
// deterministic. Mirrors the BTreeMap fix on the Rust port
// (see freak/clustering.rs and issue #170).
typedef std::map<int, std::vector<int> > cluster_map_t;

typedef PriorityQueueItem<NUM_BYTES_PER_FEATURE> queue_item_t;
typedef std::priority_queue<queue_item_t> queue_t;
Expand Down
16 changes: 12 additions & 4 deletions lib/SRC/KPM/FreakMatcher/matchers/hough_similarity_voting.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,26 @@
#include <framework/error.h>

#include <vector>
#include <unordered_map>
#include <map>

namespace vision {

/**
* Hough voting for a similarity transformation based on a set of correspondences.
* Hough voting for a similarity transformation based on a set of correspondences.
*/
class HoughSimilarityVoting
{
public:

typedef std::unordered_map<unsigned int, unsigned int> hash_t;

// std::map (not std::unordered_map): the vote-tally is consumed
// by getMaximumNumberOfVotes, which iterates and picks the bin
// with the highest count. unordered_map has implementation-
// defined iteration order (libstdc++ vs MSVC STL) so tied bins
// produced different winners across platforms, making the
// matcher non-deterministic across builds. std::map gives a
// stable ascending-key ordering that resolves ties consistently.
// Mirrors the BTreeMap fix on the Rust port (issue #170).
typedef std::map<unsigned int, unsigned int> hash_t;
typedef std::pair<int /*size*/, int /*index*/> vote_t;
typedef std::vector<vote_t> vote_vector_t;

Expand Down
12 changes: 10 additions & 2 deletions lib/SRC/KPM/FreakMatcher/matchers/visual_database.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

#include <vector>
#include <memory>
#include <unordered_map>
#include <map>

#include "feature_point.h"

Expand All @@ -69,7 +69,15 @@ namespace vision {

typedef Keyframe<96> keyframe_t;
typedef std::shared_ptr<keyframe_t> keyframe_ptr_t;
typedef std::unordered_map<id_t, keyframe_ptr_t> keyframe_map_t;
// std::map (not std::unordered_map): query() iterates this
// collection and breaks ties on inlier-count with a strict
// "first wins" comparison. unordered_map has implementation-
// defined iteration order, so the winning keyframe on
// borderline ties varied across libstdc++ vs MSVC STL builds.
// std::map's ascending-key order makes the tie-breaking
// platform-independent. Mirrors the BTreeMap fix on the Rust
// port (issue #170).
typedef std::map<id_t, keyframe_ptr_t> keyframe_map_t;

typedef BinomialPyramid32f pyramid_t;
typedef DoGScaleInvariantDetector detector_t;
Expand Down
27 changes: 26 additions & 1 deletion lib/SRC/WebARKit/WebARKitLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const char * WARKTerror = "%c🚩[webarkit-error:]";
const char * WARKTerrorStyle = "color: #ffffff; background-color: #ff0101; border-radius: 4px; padding: 2px";
const char * WARKTwarn = "%c⚠️[webarkit-warn:]";
const char * WARKTwarnStyle = "color: #774400; background-color: #ffff99; border-radius: 4px; padding: 2px";
const char * WARKTdebug = "%c🐞[webarkit-debug:]";
const char * WARKTdebugStyle = "color: #000000; background-color: #ffcc00; border-radius: 4px; padding: 2px";

void webarkitLOGi(const std::string &message) {
EM_ASM ({
Expand Down Expand Up @@ -266,4 +268,27 @@ void webarkitLOGw(const std::string &message, int format) {
WARKTwarnStyle,
format
);
}
}

#if defined WEBARKIT_DEBUG

void webarkitLOGd(const std::string &message) {
EM_ASM ({
var message = UTF8ToString($0);
var debugHead = UTF8ToString($1);
var style = UTF8ToString($2);
console.log(debugHead + message, style);
},
message.c_str(),
WARKTdebug,
WARKTdebugStyle
);
}

#else

void webarkitLOGd(const std::string &message) {
// do nothing
}

#endif
Loading