update libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / include / MtDec.h
diff --git a/deps/libchdr/deps/lzma-22.01/include/MtDec.h b/deps/libchdr/deps/lzma-22.01/include/MtDec.h
new file mode 100644 (file)
index 0000000..7a30b6a
--- /dev/null
@@ -0,0 +1,202 @@
+/* MtDec.h -- Multi-thread Decoder\r
+2020-03-05 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __MT_DEC_H\r
+#define __MT_DEC_H\r
+\r
+#include "7zTypes.h"\r
+\r
+#ifndef _7ZIP_ST\r
+#include "Threads.h"\r
+#endif\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#ifndef _7ZIP_ST\r
+\r
+#ifndef _7ZIP_ST\r
+  #define MTDEC__THREADS_MAX 32\r
+#else\r
+  #define MTDEC__THREADS_MAX 1\r
+#endif\r
+\r
+\r
+typedef struct\r
+{\r
+  ICompressProgress *progress;\r
+  SRes res;\r
+  UInt64 totalInSize;\r
+  UInt64 totalOutSize;\r
+  CCriticalSection cs;\r
+} CMtProgress;\r
+\r
+void MtProgress_Init(CMtProgress *p, ICompressProgress *progress);\r
+SRes MtProgress_Progress_ST(CMtProgress *p);\r
+SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);\r
+SRes MtProgress_GetError(CMtProgress *p);\r
+void MtProgress_SetError(CMtProgress *p, SRes res);\r
+\r
+struct _CMtDec;\r
+\r
+typedef struct\r
+{\r
+  struct _CMtDec *mtDec;\r
+  unsigned index;\r
+  void *inBuf;\r
+\r
+  size_t inDataSize_Start; // size of input data in start block\r
+  UInt64 inDataSize;       // total size of input data in all blocks\r
+\r
+  CThread thread;\r
+  CAutoResetEvent canRead;\r
+  CAutoResetEvent canWrite;\r
+  void  *allocaPtr;\r
+} CMtDecThread;\r
+\r
+void MtDecThread_FreeInBufs(CMtDecThread *t);\r
+\r
+\r
+typedef enum\r
+{\r
+  MTDEC_PARSE_CONTINUE, // continue this block with more input data\r
+  MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread\r
+  MTDEC_PARSE_NEW,      // new block\r
+  MTDEC_PARSE_END       // end of block threading. But we still can return to threading after Write(&needContinue)\r
+} EMtDecParseState;\r
+\r
+typedef struct\r
+{\r
+  // in\r
+  int startCall;\r
+  const Byte *src;\r
+  size_t srcSize;\r
+      // in  : (srcSize == 0) is allowed\r
+      // out : it's allowed to return less that actually was used ?\r
+  int srcFinished;\r
+\r
+  // out\r
+  EMtDecParseState state;\r
+  BoolInt canCreateNewThread;\r
+  UInt64 outPos; // check it (size_t)\r
+} CMtDecCallbackInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+  void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);\r
+  \r
+  // PreCode() and Code():\r
+  // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks\r
+  SRes (*PreCode)(void *p, unsigned coderIndex);\r
+  SRes (*Code)(void *p, unsigned coderIndex,\r
+      const Byte *src, size_t srcSize, int srcFinished,\r
+      UInt64 *inCodePos, UInt64 *outCodePos, int *stop);\r
+  // stop - means stop another Code calls\r
+\r
+\r
+  /* Write() must be called, if Parse() was called\r
+      set (needWrite) if\r
+      {\r
+         && (was not interrupted by progress)\r
+         && (was not interrupted in previous block)\r
+      }\r
+\r
+    out:\r
+      if (*needContinue), decoder still need to continue decoding with new iteration,\r
+         even after MTDEC_PARSE_END\r
+      if (*canRecode), we didn't flush current block data, so we still can decode current block later.\r
+  */\r
+  SRes (*Write)(void *p, unsigned coderIndex,\r
+      BoolInt needWriteToStream,\r
+      const Byte *src, size_t srcSize, BoolInt isCross,\r
+      // int srcFinished,\r
+      BoolInt *needContinue,\r
+      BoolInt *canRecode);\r
+\r
+} IMtDecCallback2;\r
+\r
+\r
+\r
+typedef struct _CMtDec\r
+{\r
+  /* input variables */\r
+  \r
+  size_t inBufSize;        /* size of input block */\r
+  unsigned numThreadsMax;\r
+  // size_t inBlockMax;\r
+  unsigned numThreadsMax_2;\r
+\r
+  ISeqInStream *inStream;\r
+  // const Byte *inData;\r
+  // size_t inDataSize;\r
+\r
+  ICompressProgress *progress;\r
+  ISzAllocPtr alloc;\r
+\r
+  IMtDecCallback2 *mtCallback;\r
+  void *mtCallbackObject;\r
+\r
+  \r
+  /* internal variables */\r
+  \r
+  size_t allocatedBufsSize;\r
+\r
+  BoolInt exitThread;\r
+  WRes exitThreadWRes;\r
+\r
+  UInt64 blockIndex;\r
+  BoolInt isAllocError;\r
+  BoolInt overflow;\r
+  SRes threadingErrorSRes;\r
+\r
+  BoolInt needContinue;\r
+\r
+  // CAutoResetEvent finishedEvent;\r
+\r
+  SRes readRes;\r
+  SRes codeRes;\r
+\r
+  BoolInt wasInterrupted;\r
+\r
+  unsigned numStartedThreads_Limit;\r
+  unsigned numStartedThreads;\r
+\r
+  Byte *crossBlock;\r
+  size_t crossStart;\r
+  size_t crossEnd;\r
+  UInt64 readProcessed;\r
+  BoolInt readWasFinished;\r
+  UInt64 inProcessed;\r
+\r
+  unsigned filledThreadStart;\r
+  unsigned numFilledThreads;\r
+\r
+  #ifndef _7ZIP_ST\r
+  BoolInt needInterrupt;\r
+  UInt64 interruptIndex;\r
+  CMtProgress mtProgress;\r
+  CMtDecThread threads[MTDEC__THREADS_MAX];\r
+  #endif\r
+} CMtDec;\r
+\r
+\r
+void MtDec_Construct(CMtDec *p);\r
+void MtDec_Destruct(CMtDec *p);\r
+\r
+/*\r
+MtDec_Code() returns:\r
+  SZ_OK - in most cases\r
+  MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function\r
+*/\r
+  \r
+SRes MtDec_Code(CMtDec *p);\r
+Byte *MtDec_GetCrossBuff(CMtDec *p);\r
+\r
+int MtDec_PrepareRead(CMtDec *p);\r
+const Byte *MtDec_Read(CMtDec *p, size_t *inLim);\r
+\r
+#endif\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r