Skip to content

Commit

Permalink
Add NanaZipCodecsBrotliRead and NanaZipCodecsBrotliWrite.
Browse files Browse the repository at this point in the history
  • Loading branch information
MouriNaruto committed Nov 1, 2024
1 parent 5d067cc commit b35769e
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 105 deletions.
152 changes: 152 additions & 0 deletions NanaZip.Codecs/NanaZip.Codecs.Wrappers.ZSTDMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,155 @@
*/

#include "NanaZip.Codecs.Wrappers.ZSTDMT.h"

typedef struct _NANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT
{
PVOID Buffer;
SIZE_T Size;
SIZE_T Allocated;
} NANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT, *PNANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT;

static int NanaZipCodecsCommonRead(
PNANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT Context,
PNANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT Input)
{
const UINT32 BlockSize = static_cast<UINT32>(1) << 31;

HRESULT hr = S_OK;
SIZE_T UnprocessedSize = Input->Size;
SIZE_T ProcessedSize = 0;
PVOID CurrentBuffer = Input->Buffer;

while (UnprocessedSize)
{
UINT32 CurrentSize =
UnprocessedSize < BlockSize
? static_cast<UINT32>(UnprocessedSize)
: BlockSize;
UINT32 CurrentProcessedSize = 0;
hr = Context->InputStream->Read(
CurrentBuffer,
CurrentSize,
&CurrentProcessedSize);
ProcessedSize += CurrentProcessedSize;
CurrentBuffer = static_cast<PVOID>(
static_cast<PBYTE>(CurrentBuffer) + CurrentProcessedSize);
UnprocessedSize -= CurrentProcessedSize;
if (S_OK != hr)
{
break;
}
if (CurrentProcessedSize == 0)
{
hr = S_OK;
break;
}
}

// catch errors
if (E_ABORT == hr)
{
return -2;
}
else if (E_OUTOFMEMORY == hr)
{
return -3;
}

// some other error -> read_fail
if (S_OK != hr)
{
return -1;
}

Input->Size = ProcessedSize;
*Context->ProcessedInputSize += ProcessedSize;

return 0;
}

static int NanaZipCodecsCommonWrite(
PNANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT Context,
PNANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT Output)
{
UINT32 Todo = static_cast<UINT32>(Output->Size);
UINT32 Done = 0;

while (Todo)
{
UINT32 Block = 0;

HRESULT hr = Context->OutputStream->Write(
reinterpret_cast<PBYTE>(Output->Buffer) + Done,
Todo,
&Block);

// catch errors
if (E_ABORT == hr)
{
return -2;
}
else if (E_OUTOFMEMORY == hr)
{
return -3;
}

Done += Block;

if (SEVENZIP_ERROR_WRITING_WAS_CUT == hr)
{
break;
}

// some other error -> write_fail
if (S_OK != hr)
{
return -1;
}

if (!Block)
{
return -1;
}

Todo -= Block;
}

*Context->ProcessedOutputSize += Done;

// we need no lock here, cause only one thread can write
if (Context->Progress)
{
Context->Progress->SetRatioInfo(
Context->ProcessedInputSize,
Context->ProcessedOutputSize);
}

return 0;
}

EXTERN_C int NanaZipCodecsBrotliRead(
void* Context,
BROTLIMT_Buffer* Input)
{
NANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT ConvertedInput;
ConvertedInput.Buffer = Input->buf;
ConvertedInput.Size = Input->size;
ConvertedInput.Allocated = Input->allocated;
return ::NanaZipCodecsCommonRead(
reinterpret_cast<PNANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT>(Context),
&ConvertedInput);
}

EXTERN_C int NanaZipCodecsBrotliWrite(
void* Context,
BROTLIMT_Buffer* Output)
{
NANAZIP_CODECS_ZSTDMT_BUFFER_CONTEXT ConvertedOutput;
ConvertedOutput.Buffer = Output->buf;
ConvertedOutput.Size = Output->size;
ConvertedOutput.Allocated = Output->allocated;
return ::NanaZipCodecsCommonWrite(
reinterpret_cast<PNANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT>(Context),
&ConvertedOutput);
}
25 changes: 25 additions & 0 deletions NanaZip.Codecs/NanaZip.Codecs.Wrappers.ZSTDMT.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,31 @@
#ifndef NANAZIP_CODECS_WRAPPERS_ZSTDMT
#define NANAZIP_CODECS_WRAPPERS_ZSTDMT

#ifdef ZIP7_INC_ICODER_H
#include <Windows.h>
#else
#include <NanaZip.Specification.SevenZip.h>
#endif

#include <stdint.h>

#include <brotli-mt.h>

typedef struct _NANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT
{
ISequentialInStream* InputStream;
ISequentialOutStream* OutputStream;
ICompressProgressInfo* Progress;
PUINT64 ProcessedInputSize;
PUINT64 ProcessedOutputSize;
} NANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT, *PNANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT;

EXTERN_C int NanaZipCodecsBrotliRead(
void* RawContext,
BROTLIMT_Buffer* Input);

EXTERN_C int NanaZipCodecsBrotliWrite(
void* Context,
BROTLIMT_Buffer* Output);

#endif // !NANAZIP_CODECS_WRAPPERS_ZSTDMT
3 changes: 3 additions & 0 deletions NanaZip.Codecs/NanaZip.Codecs.def
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ EXPORTS

GetHashers

NanaZipCodecsBrotliRead
NanaZipCodecsBrotliWrite

LZ4_decompress_safe

BROTLIMT_compressCCtx
Expand Down
1 change: 1 addition & 0 deletions NanaZip.Codecs/NanaZip.Codecs.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
MAINTAINER: MouriNaruto ([email protected])
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\NanaZip.Specification\NanaZip.Specification.props" />
<PropertyGroup>
<IncludePath>$(MSBuildThisFileDirectory)BLAKE3\;$(IncludePath)</IncludePath>
<IncludePath>$(MSBuildThisFileDirectory)Brotli\include\;$(IncludePath)</IncludePath>
Expand Down
88 changes: 12 additions & 76 deletions NanaZip.Core/Extensions/ZSCodecs/BrotliDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,6 @@
#include "../../SevenZip/CPP/7zip/Compress/StdAfx.h"
#include "BrotliDecoder.h"

int BrotliRead(void *arg, BROTLIMT_Buffer * in)
{
struct BrotliStream *x = (struct BrotliStream*)arg;
size_t size = in->size;

HRESULT res = ReadStream(x->inStream, in->buf, &size);

/* catch errors */
switch (res) {
case E_ABORT:
return -2;
case E_OUTOFMEMORY:
return -3;
}

/* some other error -> read_fail */
if (res != S_OK)
return -1;

in->size = size;
*x->processedIn += size;

return 0;
}

int BrotliWrite(void *arg, BROTLIMT_Buffer * out)
{
struct BrotliStream *x = (struct BrotliStream*)arg;
UInt32 todo = (UInt32)out->size;
UInt32 done = 0;

while (todo != 0)
{
UInt32 block;
HRESULT res = x->outStream->Write((char*)out->buf + done, todo, &block);

/* catch errors */
switch (res) {
case E_ABORT:
return -2;
case E_OUTOFMEMORY:
return -3;
}

done += block;
if (res == k_My_HRESULT_WritingWasCut)
break;
/* some other error -> write_fail */
if (res != S_OK)
return -1;

if (block == 0)
return -1;
todo -= block;
}

*x->processedOut += done;
/* we need no lock here, cause only one thread can write... */
if (x->progress)
x->progress->SetRatioInfo(x->processedIn, x->processedOut);

return 0;
}

namespace NCompress {
namespace NBROTLI {

Expand Down Expand Up @@ -128,21 +64,21 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
size_t result;
HRESULT res = S_OK;

struct BrotliStream Rd;
Rd.inStream = inStream;
Rd.processedIn = &_processedIn;
NANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT ReadContext = { 0 };
ReadContext.InputStream = inStream;
ReadContext.ProcessedInputSize = &_processedIn;

struct BrotliStream Wr;
Wr.progress = progress;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
NANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT WriteContext = { 0 };
WriteContext.Progress = progress;
WriteContext.OutputStream = outStream;
WriteContext.ProcessedInputSize = &_processedIn;
WriteContext.ProcessedOutputSize = &_processedOut;

/* 1) setup read/write functions */
rdwr.fn_read = ::BrotliRead;
rdwr.fn_write = ::BrotliWrite;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
rdwr.fn_read = ::NanaZipCodecsBrotliRead;
rdwr.fn_write = ::NanaZipCodecsBrotliWrite;
rdwr.arg_read = reinterpret_cast<void*>(&ReadContext);
rdwr.arg_write = reinterpret_cast<void*>(&WriteContext);

/* 2) create decompression context */
BROTLIMT_DCtx *ctx = BROTLIMT_createDCtx(_numThreads, _inputSize);
Expand Down
11 changes: 1 addition & 10 deletions NanaZip.Core/Extensions/ZSCodecs/BrotliDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,7 @@
#include "../../SevenZip/CPP/7zip/Common/RegisterCodec.h"
#include "../../SevenZip/CPP/7zip/Common/ProgressMt.h"

struct BrotliStream {
ISequentialInStream *inStream;
ISequentialOutStream *outStream;
ICompressProgressInfo *progress;
UInt64 *processedIn;
UInt64 *processedOut;
};

extern int BrotliRead(void *Stream, BROTLIMT_Buffer * in);
extern int BrotliWrite(void *Stream, BROTLIMT_Buffer * in);
#include <NanaZip.Codecs.Wrappers.ZSTDMT.h>

namespace NCompress {
namespace NBROTLI {
Expand Down
35 changes: 16 additions & 19 deletions NanaZip.Core/Extensions/ZSCodecs/BrotliEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,27 +112,24 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
_processedIn = 0;
_processedOut = 0;

struct BrotliStream Rd;
Rd.inStream = inStream;
Rd.outStream = outStream;
Rd.processedIn = &_processedIn;
Rd.processedOut = &_processedOut;

struct BrotliStream Wr;
// if (_processedIn == 0)
Wr.progress = progress;
// else
// Wr.progress = 0;
Wr.inStream = inStream;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
NANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT ReadContext = { 0 };
ReadContext.InputStream = inStream;
ReadContext.OutputStream = outStream;
ReadContext.ProcessedInputSize = &_processedIn;
ReadContext.ProcessedOutputSize = &_processedOut;

NANAZIP_CODECS_ZSTDMT_STREAM_CONTEXT WriteContext = { 0 };
WriteContext.Progress = progress;
WriteContext.InputStream = inStream;
WriteContext.OutputStream = outStream;
WriteContext.ProcessedInputSize = &_processedIn;
WriteContext.ProcessedOutputSize = &_processedOut;

/* 1) setup read/write functions */
rdwr.fn_read = ::BrotliRead;
rdwr.fn_write = ::BrotliWrite;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
rdwr.fn_read = ::NanaZipCodecsBrotliRead;
rdwr.fn_write = ::NanaZipCodecsBrotliWrite;
rdwr.arg_read = reinterpret_cast<void*>(&ReadContext);
rdwr.arg_write = reinterpret_cast<void*>(&WriteContext);

/* 2) create compression context, if needed */
if (!_ctx)
Expand Down
2 changes: 2 additions & 0 deletions NanaZip.Specification/NanaZip.Specification.SevenZip.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include <Windows.h>

#define SEVENZIP_ERROR_WRITING_WAS_CUT ((HRESULT)0x20000010)

// 7-Zip Interface GUID Format: 23170F69-40C1-278A-0000-00yy00xx0000

const UINT32 SevenZipGuidData1 = 0x23170F69;
Expand Down

0 comments on commit b35769e

Please sign in to comment.