update libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / src / Bcj2.c
diff --git a/deps/libchdr/deps/lzma-22.01/src/Bcj2.c b/deps/libchdr/deps/lzma-22.01/src/Bcj2.c
new file mode 100644 (file)
index 0000000..c1772f2
--- /dev/null
@@ -0,0 +1,257 @@
+/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)\r
+2021-02-09 : Igor Pavlov : Public domain */\r
+\r
+#include "Precomp.h"\r
+\r
+#include "Bcj2.h"\r
+#include "CpuArch.h"\r
+\r
+#define CProb UInt16\r
+\r
+#define kTopValue ((UInt32)1 << 24)\r
+#define kNumModelBits 11\r
+#define kBitModelTotal (1 << kNumModelBits)\r
+#define kNumMoveBits 5\r
+\r
+#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)\r
+#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));\r
+#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));\r
+\r
+void Bcj2Dec_Init(CBcj2Dec *p)\r
+{\r
+  unsigned i;\r
+\r
+  p->state = BCJ2_DEC_STATE_OK;\r
+  p->ip = 0;\r
+  p->temp[3] = 0;\r
+  p->range = 0;\r
+  p->code = 0;\r
+  for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)\r
+    p->probs[i] = kBitModelTotal >> 1;\r
+}\r
+\r
+SRes Bcj2Dec_Decode(CBcj2Dec *p)\r
+{\r
+  if (p->range <= 5)\r
+  {\r
+    p->state = BCJ2_DEC_STATE_OK;\r
+    for (; p->range != 5; p->range++)\r
+    {\r
+      if (p->range == 1 && p->code != 0)\r
+        return SZ_ERROR_DATA;\r
+      \r
+      if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])\r
+      {\r
+        p->state = BCJ2_STREAM_RC;\r
+        return SZ_OK;\r
+      }\r
+\r
+      p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;\r
+    }\r
+    \r
+    if (p->code == 0xFFFFFFFF)\r
+      return SZ_ERROR_DATA;\r
+    \r
+    p->range = 0xFFFFFFFF;\r
+  }\r
+  else if (p->state >= BCJ2_DEC_STATE_ORIG_0)\r
+  {\r
+    while (p->state <= BCJ2_DEC_STATE_ORIG_3)\r
+    {\r
+      Byte *dest = p->dest;\r
+      if (dest == p->destLim)\r
+        return SZ_OK;\r
+      *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];\r
+      p->state++;\r
+      p->dest = dest + 1;\r
+    }\r
+  }\r
+\r
+  /*\r
+  if (BCJ2_IS_32BIT_STREAM(p->state))\r
+  {\r
+    const Byte *cur = p->bufs[p->state];\r
+    if (cur == p->lims[p->state])\r
+      return SZ_OK;\r
+    p->bufs[p->state] = cur + 4;\r
+    \r
+    {\r
+      UInt32 val;\r
+      Byte *dest;\r
+      SizeT rem;\r
+      \r
+      p->ip += 4;\r
+      val = GetBe32(cur) - p->ip;\r
+      dest = p->dest;\r
+      rem = p->destLim - dest;\r
+      if (rem < 4)\r
+      {\r
+        SizeT i;\r
+        SetUi32(p->temp, val);\r
+        for (i = 0; i < rem; i++)\r
+          dest[i] = p->temp[i];\r
+        p->dest = dest + rem;\r
+        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;\r
+        return SZ_OK;\r
+      }\r
+      SetUi32(dest, val);\r
+      p->temp[3] = (Byte)(val >> 24);\r
+      p->dest = dest + 4;\r
+      p->state = BCJ2_DEC_STATE_OK;\r
+    }\r
+  }\r
+  */\r
+\r
+  for (;;)\r
+  {\r
+    if (BCJ2_IS_32BIT_STREAM(p->state))\r
+      p->state = BCJ2_DEC_STATE_OK;\r
+    else\r
+    {\r
+      if (p->range < kTopValue)\r
+      {\r
+        if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])\r
+        {\r
+          p->state = BCJ2_STREAM_RC;\r
+          return SZ_OK;\r
+        }\r
+        p->range <<= 8;\r
+        p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;\r
+      }\r
+\r
+      {\r
+        const Byte *src = p->bufs[BCJ2_STREAM_MAIN];\r
+        const Byte *srcLim;\r
+        Byte *dest;\r
+        SizeT num = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - src);\r
+        \r
+        if (num == 0)\r
+        {\r
+          p->state = BCJ2_STREAM_MAIN;\r
+          return SZ_OK;\r
+        }\r
+        \r
+        dest = p->dest;\r
+        if (num > (SizeT)(p->destLim - dest))\r
+        {\r
+          num = (SizeT)(p->destLim - dest);\r
+          if (num == 0)\r
+          {\r
+            p->state = BCJ2_DEC_STATE_ORIG;\r
+            return SZ_OK;\r
+          }\r
+        }\r
+       \r
+        srcLim = src + num;\r
+\r
+        if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)\r
+          *dest = src[0];\r
+        else for (;;)\r
+        {\r
+          Byte b = *src;\r
+          *dest = b;\r
+          if (b != 0x0F)\r
+          {\r
+            if ((b & 0xFE) == 0xE8)\r
+              break;\r
+            dest++;\r
+            if (++src != srcLim)\r
+              continue;\r
+            break;\r
+          }\r
+          dest++;\r
+          if (++src == srcLim)\r
+            break;\r
+          if ((*src & 0xF0) != 0x80)\r
+            continue;\r
+          *dest = *src;\r
+          break;\r
+        }\r
+        \r
+        num = (SizeT)(src - p->bufs[BCJ2_STREAM_MAIN]);\r
+        \r
+        if (src == srcLim)\r
+        {\r
+          p->temp[3] = src[-1];\r
+          p->bufs[BCJ2_STREAM_MAIN] = src;\r
+          p->ip += (UInt32)num;\r
+          p->dest += num;\r
+          p->state =\r
+            p->bufs[BCJ2_STREAM_MAIN] ==\r
+            p->lims[BCJ2_STREAM_MAIN] ?\r
+              (unsigned)BCJ2_STREAM_MAIN :\r
+              (unsigned)BCJ2_DEC_STATE_ORIG;\r
+          return SZ_OK;\r
+        }\r
+        \r
+        {\r
+          UInt32 bound, ttt;\r
+          CProb *prob;\r
+          Byte b = src[0];\r
+          Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);\r
+          \r
+          p->temp[3] = b;\r
+          p->bufs[BCJ2_STREAM_MAIN] = src + 1;\r
+          num++;\r
+          p->ip += (UInt32)num;\r
+          p->dest += num;\r
+          \r
+          prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));\r
+          \r
+          _IF_BIT_0\r
+          {\r
+            _UPDATE_0\r
+            continue;\r
+          }\r
+          _UPDATE_1\r
+            \r
+        }\r
+      }\r
+    }\r
+\r
+    {\r
+      UInt32 val;\r
+      unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;\r
+      const Byte *cur = p->bufs[cj];\r
+      Byte *dest;\r
+      SizeT rem;\r
+      \r
+      if (cur == p->lims[cj])\r
+      {\r
+        p->state = cj;\r
+        break;\r
+      }\r
+      \r
+      val = GetBe32(cur);\r
+      p->bufs[cj] = cur + 4;\r
+\r
+      p->ip += 4;\r
+      val -= p->ip;\r
+      dest = p->dest;\r
+      rem = (SizeT)(p->destLim - dest);\r
+      \r
+      if (rem < 4)\r
+      {\r
+        p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;\r
+        p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;\r
+        p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;\r
+        p->temp[3] = (Byte)val;\r
+        p->dest = dest + rem;\r
+        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;\r
+        break;\r
+      }\r
+      \r
+      SetUi32(dest, val);\r
+      p->temp[3] = (Byte)(val >> 24);\r
+      p->dest = dest + 4;\r
+    }\r
+  }\r
+\r
+  if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])\r
+  {\r
+    p->range <<= 8;\r
+    p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;\r
+  }\r
+\r
+  return SZ_OK;\r
+}\r