Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/librfxcodec.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/rfxencode_diff_rlgr1.c')
-rw-r--r--src/rfxencode_diff_rlgr1.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/rfxencode_diff_rlgr1.c b/src/rfxencode_diff_rlgr1.c
new file mode 100644
index 0000000..cd09f18
--- /dev/null
+++ b/src/rfxencode_diff_rlgr1.c
@@ -0,0 +1,252 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol client.
+ * RemoteFX Codec Library - RLGR
+ *
+ * Copyright 2011 Vic Lee
+ * Copyright 2016-2017 Jay Sorg <jay.sorg@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * This implementation of RLGR refers to
+ * [MS-RDPRFX] 3.1.8.1.7.3 RLGR1/RLGR3 Pseudocode
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include <config_ac.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rfxcommon.h"
+
+#define PIXELS_IN_TILE 4096
+
+/* Constants used within the RLGR1/RLGR3 algorithm */
+#define KPMAX (80) /* max value for kp or krp */
+#define LSGR (3) /* shift count to convert kp to k */
+#define UP_GR (4) /* increase in kp after a zero run in RL mode */
+#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
+#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
+#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
+
+#define GetNextInput do { \
+ input = *coef; \
+ coef++; \
+ coef_size--; \
+} while (0)
+
+#define CheckWrite do { \
+ while (bit_count >= 8) \
+ { \
+ bit_count -= 8; \
+ *cdata = bits >> bit_count; \
+ cdata++; \
+ } \
+} while (0)
+
+/* output GR code for (mag - 1) */
+#define CodeGR(_krp, _lmag) do { \
+ int lkr = _krp >> LSGR; \
+ /* unary part of GR code */ \
+ int lvk = _lmag >> lkr; \
+ int llvk = lvk; \
+ while (llvk >= 8) \
+ { \
+ bits <<= 8; \
+ bits |= 0xFF; \
+ llvk -= 8; \
+ *cdata = bits >> bit_count; \
+ cdata++; \
+ } \
+ bits <<= llvk; \
+ bits |= (1 << llvk) - 1; \
+ bit_count += llvk; \
+ bits <<= 1; \
+ bit_count++; \
+ CheckWrite; \
+ /* remainder part of GR code, if needed */ \
+ if (lkr) \
+ { \
+ bits <<= lkr; \
+ bits |= _lmag & ((1 << lkr) - 1); \
+ bit_count += lkr; \
+ } \
+ /* update _krp, only if it is not equal to 1 */ \
+ if (lvk == 0) \
+ { \
+ _krp = MAX(0, _krp - 2); \
+ } \
+ else if (lvk > 1) \
+ { \
+ _krp = MIN(KPMAX, _krp + lvk); \
+ } \
+} while (0)
+
+int
+rfx_encode_diff_rlgr1(sint16 *coef, uint8 *cdata, int cdata_size)
+{
+ int k;
+ int kp;
+ int krp;
+
+ int input;
+ int numZeros;
+ int runmax;
+ int mag;
+ int sign;
+ int processed_size;
+ int lmag;
+ int coef_size;
+ int y;
+
+ int bit_count;
+ unsigned int bits;
+ uint8 *cdata_org;
+
+ uint32 twoMs;
+
+ /* the last 64 bytes are diff */
+ for (k = PIXELS_IN_TILE - 1; k > PIXELS_IN_TILE - 64; k--)
+ {
+ coef[k] -= coef[k - 1];
+ }
+
+ /* initialize the parameters */
+ k = 1;
+ kp = 1 << LSGR;
+ krp = 1 << LSGR;
+
+ bit_count = 0;
+ bits = 0;
+ cdata_org = cdata;
+
+ /* process all the input coefficients */
+ coef_size = PIXELS_IN_TILE;
+ while (coef_size > 0)
+ {
+ if (k)
+ {
+
+ /* RUN-LENGTH MODE */
+
+ /* collect the run of zeros in the input stream */
+ numZeros = 0;
+
+ GetNextInput;
+ while (input == 0 && coef_size > 0)
+ {
+ numZeros++;
+ GetNextInput;
+ }
+
+ /* emit output zeros */
+ runmax = 1 << k;
+ while (numZeros >= runmax)
+ {
+
+ bits <<= 1;
+ bit_count++;
+
+ CheckWrite;
+
+ numZeros -= runmax;
+
+ kp = MIN(KPMAX, kp + UP_GR);
+ k = kp >> LSGR;
+
+ runmax = 1 << k;
+ }
+
+ /* output a 1 to terminate runs */
+ bits <<= 1;
+ bits |= 1;
+ bit_count++;
+
+ /* output the remaining run length using k bits */
+ bits <<= k;
+ bits |= numZeros;
+ bit_count += k;
+
+ CheckWrite;
+
+ /* encode the nonzero value using GR coding */
+ if (input < 0)
+ {
+ mag = -input;
+ sign = 1;
+ }
+ else
+ {
+ mag = input;
+ sign = 0;
+ }
+
+ bits <<= 1;
+ bits |= sign;
+ bit_count++;
+
+ lmag = mag ? mag - 1 : 0;
+
+ CodeGR(krp, lmag); /* output GR code for (mag - 1) */
+ CheckWrite;
+
+ kp = MAX(0, kp - DN_GR);
+ k = kp >> LSGR;
+
+ }
+ else
+ {
+
+ /* GOLOMB-RICE MODE */
+
+ /* RLGR1 variant */
+
+ /* convert input to (2*magnitude - sign), encode using GR code */
+ GetNextInput;
+ y = input >> 15;
+ twoMs = (((input ^ y) - y) << 1) + y;
+ CodeGR(krp, twoMs);
+ CheckWrite;
+
+ /* update k, kp */
+ if (twoMs)
+ {
+ kp = MAX(0, kp - DQ_GR);
+ k = kp >> LSGR;
+ }
+ else
+ {
+ kp = MIN(KPMAX, kp + UQ_GR);
+ k = kp >> LSGR;
+ }
+
+ }
+ }
+
+ if (bit_count > 0)
+ {
+ bits <<= 8 - bit_count;
+ *cdata = bits;
+ cdata++;
+ bit_count = 0;
+ }
+
+ processed_size = cdata - cdata_org;
+
+ return processed_size;
+}
+