From b3fdeef806268630064c5bd61f1f3a627fb0458c Mon Sep 17 00:00:00 2001 From: tschudin Date: Tue, 30 Jul 2024 22:00:35 +0200 Subject: [PATCH] add signed varint support to BIPF, allows to encode most pencil movements in 4 bytes instead of 10, change clip icon to pencil --- android/tinySSB/app/build.gradle | 3 +- .../tinySSB/app/src/main/assets/web/bipf.js | 105 ++++++++++-------- .../app/src/main/assets/web/img/pencil.png | Bin 0 -> 18614 bytes .../tinySSB/app/src/main/assets/web/sketch.js | 32 ++++-- .../app/src/main/assets/web/tremola.html | 5 +- .../app/src/main/assets/web/tremola.js | 64 ++++++----- 6 files changed, 124 insertions(+), 85 deletions(-) create mode 100644 android/tinySSB/app/src/main/assets/web/img/pencil.png diff --git a/android/tinySSB/app/build.gradle b/android/tinySSB/app/build.gradle index fa7bb93..021680d 100644 --- a/android/tinySSB/app/build.gradle +++ b/android/tinySSB/app/build.gradle @@ -5,7 +5,6 @@ apply plugin: 'kotlin-kapt' android { namespace "tremolavossbol" compileSdk 30 - buildToolsVersion "30.0.3" buildFeatures { viewBinding = true @@ -13,7 +12,7 @@ android { defaultConfig { applicationId "nz.scuttlebutt.tremolavossbol" - minSdkVersion 26 + minSdk 24 targetSdkVersion 30 versionCode 1 versionName "0.1" diff --git a/android/tinySSB/app/src/main/assets/web/bipf.js b/android/tinySSB/app/src/main/assets/web/bipf.js index 4ffeecb..ecda72c 100644 --- a/android/tinySSB/app/src/main/assets/web/bipf.js +++ b/android/tinySSB/app/src/main/assets/web/bipf.js @@ -41,7 +41,13 @@ const BIPF_MATH_POW_5 = Math.pow(2, 5*7) const BIPF_MATH_POW_6 = Math.pow(2, 6*7) const BIPF_MATH_POW_7 = Math.pow(2, 7*7) -function bipf_fvdecode(buf, offset) { +function unzigzag(value) { + let s = value & 0x01; + value >>>= 1; + return s ? -value - 1 : value +} + +function bipf_fvdecode(buf, offset, zigzag) { offset = offset || 0 buf = new Uint8Array(buf) @@ -51,56 +57,56 @@ function bipf_fvdecode(buf, offset) { res += b & BIPF_REST if (b < BIPF_MSB) { bipf_fvdecode.bytes = 1 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 1] res += (b & BIPF_REST) << 7 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 2 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 2] res += (b & BIPF_REST) << 14 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 3 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 3] res += (b & BIPF_REST) << 21 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 4 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 4] res += (b & BIPF_REST) * BIPF_MATH_POW_4 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 5 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 5] res += (b & BIPF_REST) * BIPF_MATH_POW_5 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 6 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 6] res += (b & BIPF_REST) * BIPF_MATH_POW_6 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 7 - return res + return zigzag ? unzigzag(res) : res } b = buf[offset + 7] res += (b & BIPF_REST) * BIPF_MATH_POW_7 if (b < BIPF_MSB) { bipf_fvdecode.bytes = 8 - return res + return zigzag ? unzigzag(res) : res } bipf_fvdecode.bytes = 0 @@ -110,11 +116,13 @@ function bipf_fvdecode(buf, offset) { var BIPF_MSBALL = ~BIPF_REST var BIPF_INT31 = Math.pow(2, 31) -function bipf_fvencode(num, out, offset) { +function bipf_fvencode(num, out, offset, zigzag) { if (Number.MAX_SAFE_INTEGER && num > Number.MAX_SAFE_INTEGER) { bipf_fvencode.bytes = 0 throw new RangeError('Could not encode varint') } + if (zigzag) + num = num >= 0 ? 2*num : (2 * -num) - 1 // zig-zag encoding of sign // out = out || [] out = new Uint8Array(out) offset = offset || 0 @@ -145,21 +153,21 @@ var BIFP_N7 = Math.pow(2, 49) var BIFP_N8 = Math.pow(2, 56) var BIFP_N9 = Math.pow(2, 63) -function bipf_fvencodingLength (value) { - if (value >= 0) - return ( - value < BIFP_N1 ? 1 - : value < BIFP_N2 ? 2 - : value < BIFP_N3 ? 3 - : value < BIFP_N4 ? 4 - : value < BIFP_N5 ? 5 - : value < BIFP_N6 ? 6 - : value < BIFP_N7 ? 7 - : value < BIFP_N8 ? 8 - : value < BIFP_N9 ? 9 - : 10 - ) - return -1 // FIXME: handle negative numbers +function bipf_fvencodingLength (value, zigzag) { + if (zigzag) + value = value >= 0 ? 2*value : (2 * -value) - 1 // zig-zag encoding of sign + return ( + value < BIFP_N1 ? 1 + : value < BIFP_N2 ? 2 + : value < BIFP_N3 ? 3 + : value < BIFP_N4 ? 4 + : value < BIFP_N5 ? 5 + : value < BIFP_N6 ? 6 + : value < BIFP_N7 ? 7 + : value < BIFP_N8 ? 8 + : value < BIFP_N9 ? 9 + : 10 + ) } // --- encode @@ -177,9 +185,12 @@ const BIPF_encoders = [ return b.length }, function Integer(i, buffer, start) { - let dv = new DataView(buffer); - dv.setInt32(start, i, true); - return 4 + // let dv = new DataView(buffer); + // dv.setInt32(start, i, true); + // return 4 + bipf_fvencode(i, buffer, start, true); + return bipf_fvencode.bytes; + }, function Double(d, buffer, start) { let dv = new DataView(buffer); @@ -216,20 +227,20 @@ const BIPF_encodingLengthers = [ return b.length }, function Integer(i) { - // return bipf_fvencodingLength(i) - return 4 + // return 4 + return bipf_fvencodingLength(i, true); }, function Double(d) { return 8 }, function Array(a) { var bytes = 0 - for (var i = 0; i < a.length; i++) bytes += bipf_encodingLength(a[i]) + for (var i = 0; i < a.length; i++) bytes += bipf_encodingLength(a[i], false) return bytes }, function Object(o) { var bytes = 0 - for (var k in o) bytes += bipf_encodingLength(k) + bipf_encodingLength(o[k]) + for (var k in o) bytes += bipf_encodingLength(k) + bipf_encodingLength(o[k], false) return bytes }, function boolnull(b, buffer, start) { @@ -258,7 +269,7 @@ function bipf_encodingLength(value) { if (type === void 0) throw new Error('unknown type: ' + JSON.stringify(value)) if (type === BIPF_ALREADY_BIPF) return value.length const len = BIPF_encodingLengthers[type](value) - return bipf_fvencodingLength(len << BIPF_TAG_SIZE) + len + return bipf_fvencodingLength(len << BIPF_TAG_SIZE, false) + len } function bipf_encode(value, buffer, start, _len) { @@ -273,7 +284,7 @@ function bipf_encode(value, buffer, start, _len) { // if(!buffer) // buffer = Buffer.allocUnsafe(len) //throw new Error('buffer must be provided') - bipf_fvencode((len << BIPF_TAG_SIZE) | type, buffer, start) + bipf_fvencode((len << BIPF_TAG_SIZE) | type, buffer, start, false) const bytes = bipf_fvencode.bytes return BIPF_encoders[type](value, buffer, start + bytes) + bytes } @@ -294,22 +305,22 @@ function bipf_isIdempotent(buffer) { } function bipf_getEncodedLength(buffer, start) { - return bipf_fvdecode(buffer, start) >> BIPF_TAG_SIZE + return bipf_fvdecode(buffer, start, false) >> BIPF_TAG_SIZE } function bipf_getEncodedType(buffer, start) { - return bipf_fvdecode(buffer, start) & BIPF_TAG_MASK + return bipf_fvdecode(buffer, start, false) & BIPF_TAG_MASK } function bipf_allocAndEncode(value) { - const len = bipf_encodingLength(value) + const len = bipf_encodingLength(value, false) const buffer = Buffer.allocUnsafe(len) bipf_encode(value, buffer, 0) return buffer } function bipf_allocAndEncodeIdempotent(value) { - const len = bipf_encodingLength(value) + const len = bipf_encodingLength(value, false) const buffer = Buffer.allocUnsafe(len) bipf_encodeIdempotent(value, buffer, 0) return buffer @@ -327,8 +338,9 @@ function bipf_decodeBuffer(buffer, start, length) { } function bipf_decodeInteger(buf, start, length) { - let dv = new DataView(buf); - return dv.getInt32(start, true); //TODO: encode in minimum bytes + // let dv = new DataView(buf); + // return dv.getInt32(start, true); //TODO: encode in minimum bytes + return bipf_fvdecode(buf, start, true); } function bipf_decodeDouble(buffer, start, length) { @@ -339,7 +351,7 @@ function bipf_decodeDouble(buffer, start, length) { function bipf_decodeArray(buffer, start, length) { const a = [] for (let c = 0; c < length; ) { - const tag = bipf_fvdecode(buffer, start + c) + const tag = bipf_fvdecode(buffer, start + c, false) const type = tag & BIPF_TAG_MASK if (type === 7) throw new Error('reserved type') const len = tag >> BIPF_TAG_SIZE @@ -354,7 +366,7 @@ function bipf_decodeArray(buffer, start, length) { function bipf_decodeObject(buffer, start, length) { const o = {} for (let c = 0; c < length; ) { - const tag = bipf_fvdecode(buffer, start + c) + const tag = bipf_fvdecode(buffer, start + c, false) // JavaScript only allows string-valued and Symbol keys for objects if (tag & BIPF_TAG_MASK) throw new Error('required type:string') const len = tag >> BIPF_TAG_SIZE @@ -362,7 +374,7 @@ function bipf_decodeObject(buffer, start, length) { const key = bipf_decodeString(buffer, start + c, len) c += len - const tag2 = bipf_fvdecode(buffer, start + c) + const tag2 = bipf_fvdecode(buffer, start + c, false) const type2 = tag2 & BIPF_TAG_MASK if (type2 === 7) throw new Error('reserved type:value') const len2 = tag2 >> BIPF_TAG_SIZE @@ -404,7 +416,7 @@ function bipf_decodeType(type, buffer, start, len) { function bipf_decode(buffer, start) { start = start | 0 - const tag = bipf_fvdecode(buffer, start) + const tag = bipf_fvdecode(buffer, start, false) const type = tag & BIPF_TAG_MASK const len = tag >> BIPF_TAG_SIZE const bytes = bipf_fvdecode.bytes @@ -444,7 +456,7 @@ const isObject = (object) => { } function testEncodeDecode(value) { - const buf = new ArrayBuffer(bipf_encodingLength(value)) + const buf = new ArrayBuffer(bipf_encodingLength(value, false)) const len = bipf_encode(value, buf, 0) console.log('in:', JSON.stringify(value), '--> encoded:', buf.slice(0, len)) //''+jsonString to get 'undefined' string. @@ -491,9 +503,11 @@ pkg = { } testEncodeDecode(100) +testEncodeDecode(63) testEncodeDecode(0) testEncodeDecode(1) testEncodeDecode(-1) +testEncodeDecode(-63) testEncodeDecode(-100) testEncodeDecode(123.456) testEncodeDecode(2147483647) @@ -514,7 +528,6 @@ testEncodeDecode({ foo: true }) // testEncodeDecode([-1, { foo: true }, Buffer.from('deadbeef', 'hex')]) testEncodeDecode(pkg) testEncodeDecode({ 1: true }) - */ // eof diff --git a/android/tinySSB/app/src/main/assets/web/img/pencil.png b/android/tinySSB/app/src/main/assets/web/img/pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..6f74cff2204540cdbc6869942b32cec71299f5c2 GIT binary patch literal 18614 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 literal 0 HcmV?d00001 diff --git a/android/tinySSB/app/src/main/assets/web/sketch.js b/android/tinySSB/app/src/main/assets/web/sketch.js index 1c69613..10b31b5 100644 --- a/android/tinySSB/app/src/main/assets/web/sketch.js +++ b/android/tinySSB/app/src/main/assets/web/sketch.js @@ -33,7 +33,10 @@ function chat_openSketch() { canvas.style.left = '0'; canvas.width = window.innerWidth; // Full screen width canvas.height = window.innerHeight; // Full screen height - + /* on API 26, the canvas is not showing. Perhaps + https://stackoverflow.com/questions/24586530/android-canvas-drawing-not-visible#24586531 + canvas.drawARGB(0, 225, 225, 255); + */ canvas.style.backgroundColor = '#ffffff'; document.body.appendChild(canvas); @@ -63,13 +66,16 @@ function chat_openSketch() { // Create a close button and style it let closeButton = document.createElement('button'); closeButton.id = 'btn:closeSketch'; - closeButton.innerHTML = 'Cancel'; + // closeButton.innerHTML = 'Cancel'; + closeButton.style['background-image'] = "url('img/cancel.svg')" closeButton.style.position = 'fixed'; closeButton.style.top = '10px'; closeButton.style.right = '10px'; + closeButton.style.width= '40px'; + closeButton.style.height = '40px'; closeButton.style.padding = '10px'; closeButton.style.backgroundColor = '#ff0000'; - closeButton.style.color = '#ffffff'; + // closeButton.style.color = '#ffffff'; closeButton.style.border = 'none'; closeButton.style.borderRadius = '5px'; closeButton.style.cursor = 'pointer'; @@ -79,13 +85,16 @@ function chat_openSketch() { // Do the same with a submit button let submitButton = document.createElement('button'); submitButton.id = 'btn:submitSketch'; - submitButton.innerHTML = 'Submit'; + // submitButton.innerHTML = 'Submit'; + submitButton.style['background-image'] = "url('img/checked.svg')" submitButton.style.position = 'fixed'; submitButton.style.top = '10px'; - submitButton.style.right = '100px'; + submitButton.style.right = '55px'; + submitButton.style.width= '40px'; + submitButton.style.height = '40px'; submitButton.style.padding = '10px'; submitButton.style.backgroundColor = '#008000'; - submitButton.style.color = '#ffffff'; + // submitButton.style.color = '#ffffff'; submitButton.style.border = 'none'; submitButton.style.borderRadius = '5px'; submitButton.style.cursor = 'pointer'; @@ -132,7 +141,7 @@ function chat_openSketch() { document.body.appendChild(colorChoiceButton); //Array of colors we want to include - var sketch_colors = ['#000000', '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff']; + var sketch_colors = ['#000000', '#ee0000', '#00aa00', '#4040ff', '#ffee00', '#ff00ff']; // Add color buttons to the color palette Array.from(Array(sketch_colors.length).keys()).forEach(function(ndx) { @@ -231,12 +240,16 @@ function chat_openSketch() { [sketch.lastX, sketch.lastY] = [Math.round(e.touches[0].clientX - rect.left), Math.round(e.touches[0].clientY - rect.top)]; sketch.svg.push(['p',sketch.lastX,sketch.lastY]) + sketch.start = Date.now() } //Function when users move their finger to continue drawing function draw(e) { if (!sketch.isDrawing) return; + let t = Date.now() + if (t - sketch.start < 35) return; + sketch.start = t; e.preventDefault(); let rect = e.target.getBoundingClientRect(); let ctx_ = sketch.ctx; @@ -384,8 +397,12 @@ function chat_closeSketch() { if (undoButton) { undoButton.parentNode.removeChild(undoButton); } + + sketch.svg = [] + sketch.currSize = 0; } +/* function sketch_reduceResolution(base64String, reductionFactor) { return new Promise((resolve, reject) => { const img = new Image(); @@ -411,6 +428,7 @@ function sketch_reduceResolution(base64String, reductionFactor) { }; }); } +*/ // returns the size of the base64 string that represents the sketch async function sketch_get_current_size() { diff --git a/android/tinySSB/app/src/main/assets/web/tremola.html b/android/tinySSB/app/src/main/assets/web/tremola.html index f5a41f3..0a07c9e 100644 --- a/android/tinySSB/app/src/main/assets/web/tremola.html +++ b/android/tinySSB/app/src/main/assets/web/tremola.html @@ -360,7 +360,7 @@

MIT License for tinySSB (previously known as tinyTremola and VoSSBoL) -

Copyright (c) 2021-23 Computer Networks Group, University of Basel +

Copyright (c) 2021-24 Computer Networks Group, University of Basel

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -548,7 +548,8 @@

- + +
diff --git a/android/tinySSB/app/src/main/assets/web/tremola.js b/android/tinySSB/app/src/main/assets/web/tremola.js index f15aa83..ceb8274 100644 --- a/android/tinySSB/app/src/main/assets/web/tremola.js +++ b/android/tinySSB/app/src/main/assets/web/tremola.js @@ -383,34 +383,42 @@ function load_post_item(p) { // { 'key', 'from', 'when', 'body', 'to' (if group var ui8 = new Uint8Array(buf); for (var i = 0; i < binStr.length; i++) ui8[i] = binStr.charCodeAt(i); - let img = bipf_decode(buf, 0); - // console.log('got svg', JSON.stringify(img)); - // img[0] -- version of this svg encoding, currently 1, ignored - if (Number.isInteger(img[0])) - img = img.slice(1) - var svg = ` { - if (e[0] == 'c') { - colNdx = e[1]; - } else if (e[0] == 'w') { - widNdx = e[1]; - } else if (e[0] == 'p') { - svg += `` - } - }) - svg += '' - // console.log('svg:', svg) - box += ` { + if (e[0] == 'c') { + colNdx = e[1]; + } else if (e[0] == 'w') { + widNdx = e[1]; + } else if (e[0] == 'p') { + svg += `` + } + }) + svg += ''; + // console.log('svg:', svg) + src = `data:image/svg+xml;base64,${btoa(svg)}`; + } catch (error) { + console.error(error); + src = "data:null"; + } + box += `