mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +00:00
Move the LZW compression functions out of cache1d.cpp into their own object, klzw.cpp.
This eliminates the hackiness of libcache1d.so (now libkzlw.so) and CACHE1D_COMPRESS_ONLY. git-svn-id: https://svn.eduke32.com/eduke32@7140 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
de5d358d32
commit
fd175086a3
7 changed files with 411 additions and 362 deletions
|
@ -165,6 +165,7 @@ engine_objs := \
|
||||||
rev.cpp \
|
rev.cpp \
|
||||||
baselayer.cpp \
|
baselayer.cpp \
|
||||||
cache1d.cpp \
|
cache1d.cpp \
|
||||||
|
klzw.cpp \
|
||||||
common.cpp \
|
common.cpp \
|
||||||
compat.cpp \
|
compat.cpp \
|
||||||
crc32.cpp \
|
crc32.cpp \
|
||||||
|
@ -211,6 +212,7 @@ engine_tools_objs := \
|
||||||
pragmas.cpp \
|
pragmas.cpp \
|
||||||
kplib.cpp \
|
kplib.cpp \
|
||||||
cache1d.cpp \
|
cache1d.cpp \
|
||||||
|
klzw.cpp \
|
||||||
crc32.cpp \
|
crc32.cpp \
|
||||||
colmatch.cpp \
|
colmatch.cpp \
|
||||||
lz4.cpp \
|
lz4.cpp \
|
||||||
|
@ -890,9 +892,9 @@ $(ebacktrace_dll): platform/Windows/src/backtrace.c
|
||||||
$(COMPILE_STATUS)
|
$(COMPILE_STATUS)
|
||||||
$(RECIPE_IF) $(CC) $(CONLYFLAGS) -O2 -ggdb -shared -Wall -Wextra -static-libgcc -I$(engine_inc) -o $@ $^ -lbfd -liberty -limagehlp $(RECIPE_RESULT_COMPILE)
|
$(RECIPE_IF) $(CC) $(CONLYFLAGS) -O2 -ggdb -shared -Wall -Wextra -static-libgcc -I$(engine_inc) -o $@ $^ -lbfd -liberty -limagehlp $(RECIPE_RESULT_COMPILE)
|
||||||
|
|
||||||
libcache1d$(DLLSUFFIX): $(engine_src)/cache1d.cpp
|
libklzw$(DLLSUFFIX): $(engine_src)/klzw.cpp
|
||||||
$(COMPILE_STATUS)
|
$(COMPILE_STATUS)
|
||||||
$(RECIPE_IF) $(COMPILER_C) -DCACHE1D_COMPRESS_ONLY -shared -fPIC $< -o $@ $(RECIPE_RESULT_COMPILE)
|
$(RECIPE_IF) $(COMPILER_C) -shared -fPIC $< -o $@ $(RECIPE_RESULT_COMPILE)
|
||||||
|
|
||||||
# to debug the tools link phase, make a copy of this rule explicitly replacing % with the name of a tool, such as kextract
|
# to debug the tools link phase, make a copy of this rule explicitly replacing % with the name of a tool, such as kextract
|
||||||
%$(EXESUFFIX): $(tools_obj)/%.$o $(foreach i,tools $(tools_deps),$(call expandobjs,$i))
|
%$(EXESUFFIX): $(tools_obj)/%.$o $(foreach i,tools $(tools_deps),$(call expandobjs,$i))
|
||||||
|
|
|
@ -225,6 +225,7 @@
|
||||||
<ClCompile Include="..\..\source\build\src\hash.cpp" />
|
<ClCompile Include="..\..\source\build\src\hash.cpp" />
|
||||||
<ClCompile Include="..\..\source\build\src\hightile.cpp" />
|
<ClCompile Include="..\..\source\build\src\hightile.cpp" />
|
||||||
<ClCompile Include="..\..\source\build\src\jwzgles.c" />
|
<ClCompile Include="..\..\source\build\src\jwzgles.c" />
|
||||||
|
<ClCompile Include="..\..\source\build\src\klzw.cpp" />
|
||||||
<ClCompile Include="..\..\source\build\src\kplib.cpp" />
|
<ClCompile Include="..\..\source\build\src\kplib.cpp" />
|
||||||
<ClCompile Include="..\..\source\build\src\lunatic.cpp">
|
<ClCompile Include="..\..\source\build\src\lunatic.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
@ -334,6 +335,7 @@
|
||||||
<ClInclude Include="..\..\source\build\include\hightile.h" />
|
<ClInclude Include="..\..\source\build\include\hightile.h" />
|
||||||
<ClInclude Include="..\..\source\build\include\jwzgles.h" />
|
<ClInclude Include="..\..\source\build\include\jwzgles.h" />
|
||||||
<ClInclude Include="..\..\source\build\include\jwzglesI.h" />
|
<ClInclude Include="..\..\source\build\include\jwzglesI.h" />
|
||||||
|
<ClInclude Include="..\..\source\build\include\klzw.h" />
|
||||||
<ClInclude Include="..\..\source\build\include\kplib.h" />
|
<ClInclude Include="..\..\source\build\include\kplib.h" />
|
||||||
<ClInclude Include="..\..\source\build\include\libdivide.h" />
|
<ClInclude Include="..\..\source\build\include\libdivide.h" />
|
||||||
<ClInclude Include="..\..\source\build\include\lz4.h" />
|
<ClInclude Include="..\..\source\build\include\lz4.h" />
|
||||||
|
|
|
@ -77,6 +77,9 @@
|
||||||
<ClCompile Include="..\..\source\build\src\jwzgles.c">
|
<ClCompile Include="..\..\source\build\src\jwzgles.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\source\build\src\klzw.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\source\build\src\kplib.cpp">
|
<ClCompile Include="..\..\source\build\src\kplib.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -274,6 +277,9 @@
|
||||||
<ClInclude Include="..\..\source\build\include\jwzglesI.h">
|
<ClInclude Include="..\..\source\build\include\jwzglesI.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\source\build\include\klzw.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\source\build\include\kplib.h">
|
<ClInclude Include="..\..\source\build\include\kplib.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -149,6 +149,7 @@ ENGINE_OBJS= \
|
||||||
$(ENGINE_OBJ)\animvpx.$o \
|
$(ENGINE_OBJ)\animvpx.$o \
|
||||||
$(ENGINE_OBJ)\baselayer.$o \
|
$(ENGINE_OBJ)\baselayer.$o \
|
||||||
$(ENGINE_OBJ)\cache1d.$o \
|
$(ENGINE_OBJ)\cache1d.$o \
|
||||||
|
$(ENGINE_OBJ)\klzw.$o \
|
||||||
$(ENGINE_OBJ)\common.$o \
|
$(ENGINE_OBJ)\common.$o \
|
||||||
$(ENGINE_OBJ)\compat.$o \
|
$(ENGINE_OBJ)\compat.$o \
|
||||||
$(ENGINE_OBJ)\crc32.$o \
|
$(ENGINE_OBJ)\crc32.$o \
|
||||||
|
|
30
source/build/include/klzw.h
Normal file
30
source/build/include/klzw.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||||
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||||||
|
// See the included license file "BUILDLIC.TXT" for license info.
|
||||||
|
//
|
||||||
|
// This file has been modified from Ken Silverman's original release
|
||||||
|
// by Jonathon Fowler (jf@jonof.id.au)
|
||||||
|
// by the EDuke32 team (development@voidpoint.com)
|
||||||
|
|
||||||
|
#ifndef klzw_h_
|
||||||
|
#define klzw_h_
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// These two follow the argument order of the C functions "read" and "write":
|
||||||
|
// handle, buffer, length.
|
||||||
|
typedef int32_t (*klzw_readfunc)(intptr_t, void *, int32_t);
|
||||||
|
typedef void (*klzw_writefunc)(intptr_t, void const *, int32_t);
|
||||||
|
|
||||||
|
int32_t klzw_read_compressed(void *buffer, bsize_t dasizeof, bsize_t count, intptr_t f, klzw_readfunc readfunc);
|
||||||
|
void klzw_write_compressed(const void *buffer, bsize_t dasizeof, bsize_t count, intptr_t f, klzw_writefunc writefunc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // klzw_h_
|
|
@ -8,14 +8,6 @@
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
#ifdef CACHE1D_COMPRESS_ONLY
|
|
||||||
// Standalone libcache1d.so containing only the compression/decompression
|
|
||||||
// functions.
|
|
||||||
# define C1D_STATIC
|
|
||||||
#else
|
|
||||||
// cache1d.o for EDuke32
|
|
||||||
# define C1D_STATIC static
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// for FILENAME_CASE_CHECK
|
// for FILENAME_CASE_CHECK
|
||||||
# define NEED_SHELLAPI_H
|
# define NEED_SHELLAPI_H
|
||||||
|
@ -25,6 +17,7 @@
|
||||||
#include "pragmas.h"
|
#include "pragmas.h"
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
#include "lz4.h"
|
#include "lz4.h"
|
||||||
|
#include "klzw.h"
|
||||||
|
|
||||||
#ifdef WITHKPLIB
|
#ifdef WITHKPLIB
|
||||||
#include "kplib.h"
|
#include "kplib.h"
|
||||||
|
@ -1595,22 +1588,6 @@ failure:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // #ifdef CACHE1D_COMPRESS_ONLY / else
|
|
||||||
|
|
||||||
|
|
||||||
//Internal LZW variables
|
|
||||||
#define LZWSIZE 16384 //Watch out for shorts!
|
|
||||||
#define LZWSIZEPAD (LZWSIZE+(LZWSIZE>>4))
|
|
||||||
|
|
||||||
// lzwrawbuf LZWSIZE+1 (formerly): see (*) below
|
|
||||||
// XXX: lzwrawbuf size increased again :-/
|
|
||||||
static char lzwtmpbuf[LZWSIZEPAD], lzwrawbuf[LZWSIZEPAD], lzwcompbuf[LZWSIZEPAD];
|
|
||||||
static int16_t lzwbuf2[LZWSIZEPAD], lzwbuf3[LZWSIZEPAD];
|
|
||||||
|
|
||||||
static int32_t lzwcompress(const char *lzwinbuf, int32_t uncompleng, char *lzwoutbuf);
|
|
||||||
static int32_t lzwuncompress(const char *lzwinbuf, int32_t compleng, char *lzwoutbuf);
|
|
||||||
|
|
||||||
#ifndef CACHE1D_COMPRESS_ONLY
|
|
||||||
static int32_t kdfread_func(intptr_t fil, void *outbuf, int32_t length)
|
static int32_t kdfread_func(intptr_t fil, void *outbuf, int32_t length)
|
||||||
{
|
{
|
||||||
return kread((int32_t)fil, outbuf, length);
|
return kread((int32_t)fil, outbuf, length);
|
||||||
|
@ -1620,89 +1597,11 @@ static void dfwrite_func(intptr_t fp, const void *inbuf, int32_t length)
|
||||||
{
|
{
|
||||||
Bfwrite(inbuf, length, 1, (BFILE *)fp);
|
Bfwrite(inbuf, length, 1, (BFILE *)fp);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
# define kdfread_func NULL
|
|
||||||
# define dfwrite_func NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// These two follow the argument order of the C functions "read" and "write":
|
|
||||||
// handle, buffer, length.
|
|
||||||
C1D_STATIC int32_t (*c1d_readfunc)(intptr_t, void *, int32_t) = kdfread_func;
|
|
||||||
C1D_STATIC void (*c1d_writefunc)(intptr_t, const void *, int32_t) = dfwrite_func;
|
|
||||||
|
|
||||||
|
|
||||||
////////// COMPRESSED READ //////////
|
|
||||||
|
|
||||||
static uint32_t decompress_part(intptr_t f, uint32_t *kgoalptr)
|
|
||||||
{
|
|
||||||
int16_t leng;
|
|
||||||
|
|
||||||
// Read compressed length first.
|
|
||||||
if (c1d_readfunc(f, &leng, 2) != 2)
|
|
||||||
return 1;
|
|
||||||
leng = B_LITTLE16(leng);
|
|
||||||
|
|
||||||
if (c1d_readfunc(f,lzwcompbuf, leng) != leng)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
*kgoalptr = lzwuncompress(lzwcompbuf, leng, lzwrawbuf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from 'f' into 'buffer'.
|
|
||||||
C1D_STATIC int32_t c1d_read_compressed(void *buffer, bsize_t dasizeof, bsize_t count, intptr_t f)
|
|
||||||
{
|
|
||||||
char *ptr = (char *)buffer;
|
|
||||||
|
|
||||||
if (dasizeof > LZWSIZE)
|
|
||||||
{
|
|
||||||
count *= dasizeof;
|
|
||||||
dasizeof = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t kgoal;
|
|
||||||
|
|
||||||
if (decompress_part(f, &kgoal))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
Bmemcpy(ptr, lzwrawbuf, (int32_t)dasizeof);
|
|
||||||
|
|
||||||
uint32_t k = (int32_t)dasizeof;
|
|
||||||
|
|
||||||
for (uint32_t i=1; i<count; i++)
|
|
||||||
{
|
|
||||||
if (k >= kgoal)
|
|
||||||
{
|
|
||||||
k = decompress_part(f, &kgoal);
|
|
||||||
if (k) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t j = 0;
|
|
||||||
|
|
||||||
if (dasizeof >= 4)
|
|
||||||
{
|
|
||||||
for (; j<dasizeof-4; j+=4)
|
|
||||||
{
|
|
||||||
ptr[j+dasizeof] = ((ptr[j]+lzwrawbuf[j+k])&255);
|
|
||||||
ptr[j+1+dasizeof] = ((ptr[j+1]+lzwrawbuf[j+1+k])&255);
|
|
||||||
ptr[j+2+dasizeof] = ((ptr[j+2]+lzwrawbuf[j+2+k])&255);
|
|
||||||
ptr[j+3+dasizeof] = ((ptr[j+3]+lzwrawbuf[j+3+k])&255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; j<dasizeof; j++)
|
|
||||||
ptr[j+dasizeof] = ((ptr[j]+lzwrawbuf[j+k])&255);
|
|
||||||
|
|
||||||
k += dasizeof;
|
|
||||||
ptr += dasizeof;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t kdfread(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
int32_t kdfread(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
||||||
{
|
{
|
||||||
return c1d_read_compressed(buffer, dasizeof, count, (intptr_t)fil);
|
return klzw_read_compressed(buffer, dasizeof, count, (intptr_t)fil, kdfread_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LZ4_COMPRESSION_ACCELERATION_VALUE can be tuned for performance/space trade-off
|
// LZ4_COMPRESSION_ACCELERATION_VALUE can be tuned for performance/space trade-off
|
||||||
|
@ -1712,13 +1611,12 @@ int32_t kdfread(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
||||||
static char compressedDataStackBuf[131072];
|
static char compressedDataStackBuf[131072];
|
||||||
int32_t lz4CompressionLevel = LZ4_COMPRESSION_ACCELERATION_VALUE;
|
int32_t lz4CompressionLevel = LZ4_COMPRESSION_ACCELERATION_VALUE;
|
||||||
|
|
||||||
|
|
||||||
int32_t kdfread_LZ4(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
int32_t kdfread_LZ4(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
||||||
{
|
{
|
||||||
int32_t leng;
|
int32_t leng;
|
||||||
|
|
||||||
// read compressed data length
|
// read compressed data length
|
||||||
if (c1d_readfunc(fil, &leng, 4) != 4)
|
if (kread(fil, &leng, sizeof(leng)) != sizeof(leng))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
leng = B_LITTLE32(leng);
|
leng = B_LITTLE32(leng);
|
||||||
|
@ -1728,7 +1626,7 @@ int32_t kdfread_LZ4(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
||||||
if (leng > ARRAY_SSIZE(compressedDataStackBuf))
|
if (leng > ARRAY_SSIZE(compressedDataStackBuf))
|
||||||
pCompressedData = (char *)Xaligned_alloc(16, leng);
|
pCompressedData = (char *)Xaligned_alloc(16, leng);
|
||||||
|
|
||||||
if (c1d_readfunc(fil, pCompressedData, leng) != leng)
|
if (kread(fil, pCompressedData, leng) != leng)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int32_t decompressedLength = LZ4_decompress_safe(pCompressedData, (char*) buffer, leng, dasizeof*count);
|
int32_t decompressedLength = LZ4_decompress_safe(pCompressedData, (char*) buffer, leng, dasizeof*count);
|
||||||
|
@ -1740,68 +1638,9 @@ int32_t kdfread_LZ4(void *buffer, bsize_t dasizeof, bsize_t count, int32_t fil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////// COMPRESSED WRITE //////////
|
|
||||||
|
|
||||||
static uint32_t compress_part(uint32_t k, intptr_t f)
|
|
||||||
{
|
|
||||||
const int16_t leng = (int16_t)lzwcompress(lzwrawbuf, k, lzwcompbuf);
|
|
||||||
const int16_t swleng = B_LITTLE16(leng);
|
|
||||||
|
|
||||||
c1d_writefunc(f, &swleng, 2);
|
|
||||||
c1d_writefunc(f, lzwcompbuf, leng);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write from 'buffer' to 'f'.
|
|
||||||
C1D_STATIC void c1d_write_compressed(const void *buffer, bsize_t dasizeof, bsize_t count, intptr_t f)
|
|
||||||
{
|
|
||||||
char const *ptr = (char const *)buffer;
|
|
||||||
|
|
||||||
if (dasizeof > LZWSIZE)
|
|
||||||
{
|
|
||||||
count *= dasizeof;
|
|
||||||
dasizeof = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bmemcpy(lzwrawbuf, ptr, (int32_t)dasizeof);
|
|
||||||
|
|
||||||
uint32_t k = dasizeof;
|
|
||||||
if (k > LZWSIZE-dasizeof)
|
|
||||||
k = compress_part(k, f);
|
|
||||||
|
|
||||||
for (uint32_t i=1; i<count; i++)
|
|
||||||
{
|
|
||||||
uint32_t j = 0;
|
|
||||||
|
|
||||||
if (dasizeof >= 4)
|
|
||||||
{
|
|
||||||
for (; j<dasizeof-4; j+=4)
|
|
||||||
{
|
|
||||||
lzwrawbuf[j+k] = ((ptr[j+dasizeof]-ptr[j])&255);
|
|
||||||
lzwrawbuf[j+1+k] = ((ptr[j+1+dasizeof]-ptr[j+1])&255);
|
|
||||||
lzwrawbuf[j+2+k] = ((ptr[j+2+dasizeof]-ptr[j+2])&255);
|
|
||||||
lzwrawbuf[j+3+k] = ((ptr[j+3+dasizeof]-ptr[j+3])&255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; j<dasizeof; j++)
|
|
||||||
lzwrawbuf[j+k] = ((ptr[j+dasizeof]-ptr[j])&255);
|
|
||||||
|
|
||||||
k += dasizeof;
|
|
||||||
if (k > LZWSIZE-dasizeof)
|
|
||||||
k = compress_part(k, f);
|
|
||||||
|
|
||||||
ptr += dasizeof;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k > 0)
|
|
||||||
compress_part(k, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dfwrite(const void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil)
|
void dfwrite(const void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil)
|
||||||
{
|
{
|
||||||
c1d_write_compressed(buffer, dasizeof, count, (intptr_t)fil);
|
klzw_write_compressed(buffer, dasizeof, count, (intptr_t)fil, dfwrite_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dfwrite_LZ4(const void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil)
|
void dfwrite_LZ4(const void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil)
|
||||||
|
@ -1815,201 +1654,9 @@ void dfwrite_LZ4(const void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil
|
||||||
int32_t const leng = LZ4_compress_fast((const char*) buffer, pCompressedData, dasizeof*count, maxCompressedSize, lz4CompressionLevel);
|
int32_t const leng = LZ4_compress_fast((const char*) buffer, pCompressedData, dasizeof*count, maxCompressedSize, lz4CompressionLevel);
|
||||||
int32_t const swleng = B_LITTLE32(leng);
|
int32_t const swleng = B_LITTLE32(leng);
|
||||||
|
|
||||||
c1d_writefunc((intptr_t) fil, &swleng, 4);
|
Bfwrite(&swleng, sizeof(swleng), 1, fil);
|
||||||
c1d_writefunc((intptr_t) fil, pCompressedData, leng);
|
Bfwrite(pCompressedData, leng, 1, fil);
|
||||||
|
|
||||||
if (pCompressedData != compressedDataStackBuf)
|
if (pCompressedData != compressedDataStackBuf)
|
||||||
Baligned_free(pCompressedData);
|
Baligned_free(pCompressedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////// CORE COMPRESSION FUNCTIONS //////////
|
|
||||||
|
|
||||||
static int32_t lzwcompress(const char *lzwinbuf, int32_t uncompleng, char *lzwoutbuf)
|
|
||||||
{
|
|
||||||
int32_t i, addr, addrcnt, *intptr;
|
|
||||||
int32_t bytecnt1, bitcnt, numbits, oneupnumbits;
|
|
||||||
int16_t *shortptr;
|
|
||||||
|
|
||||||
int16_t *const lzwcodehead = lzwbuf2;
|
|
||||||
int16_t *const lzwcodenext = lzwbuf3;
|
|
||||||
|
|
||||||
for (i=255; i>=4; i-=4)
|
|
||||||
{
|
|
||||||
lzwtmpbuf[i] = i, lzwcodenext[i] = (i+1)&255;
|
|
||||||
lzwtmpbuf[i-1] = i-1, lzwcodenext[i-1] = (i) &255;
|
|
||||||
lzwtmpbuf[i-2] = i-2, lzwcodenext[i-2] = (i-1)&255;
|
|
||||||
lzwtmpbuf[i-3] = i-3, lzwcodenext[i-3] = (i-2)&255;
|
|
||||||
lzwcodehead[i] = lzwcodehead[i-1] = lzwcodehead[i-2] = lzwcodehead[i-3] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i>=0; i--)
|
|
||||||
{
|
|
||||||
lzwtmpbuf[i] = i;
|
|
||||||
lzwcodenext[i] = (i+1)&255;
|
|
||||||
lzwcodehead[i] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bmemset(lzwoutbuf, 0, 4+uncompleng+1);
|
|
||||||
// clearbuf(lzwoutbuf,((uncompleng+15)+3)>>2,0L);
|
|
||||||
|
|
||||||
addrcnt = 256; bytecnt1 = 0; bitcnt = (4<<3);
|
|
||||||
numbits = 8; oneupnumbits = (1<<8);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
addr = lzwinbuf[bytecnt1];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int32_t newaddr;
|
|
||||||
|
|
||||||
if (++bytecnt1 == uncompleng)
|
|
||||||
break; // (*) see XXX below
|
|
||||||
|
|
||||||
if (lzwcodehead[addr] < 0)
|
|
||||||
{
|
|
||||||
lzwcodehead[addr] = addrcnt;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newaddr = lzwcodehead[addr];
|
|
||||||
while (lzwtmpbuf[newaddr] != lzwinbuf[bytecnt1])
|
|
||||||
{
|
|
||||||
if (lzwcodenext[newaddr] < 0)
|
|
||||||
{
|
|
||||||
lzwcodenext[newaddr] = addrcnt;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
newaddr = lzwcodenext[newaddr];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lzwcodenext[newaddr] == addrcnt)
|
|
||||||
break;
|
|
||||||
addr = newaddr;
|
|
||||||
}
|
|
||||||
while (addr >= 0);
|
|
||||||
|
|
||||||
lzwtmpbuf[addrcnt] = lzwinbuf[bytecnt1]; // XXX: potential oob access of lzwinbuf via (*) above
|
|
||||||
lzwcodehead[addrcnt] = -1;
|
|
||||||
lzwcodenext[addrcnt] = -1;
|
|
||||||
|
|
||||||
intptr = (int32_t *)&lzwoutbuf[bitcnt>>3];
|
|
||||||
intptr[0] |= B_LITTLE32(addr<<(bitcnt&7));
|
|
||||||
bitcnt += numbits;
|
|
||||||
if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1)))
|
|
||||||
bitcnt--;
|
|
||||||
|
|
||||||
addrcnt++;
|
|
||||||
if (addrcnt > oneupnumbits)
|
|
||||||
{ numbits++; oneupnumbits <<= 1; }
|
|
||||||
}
|
|
||||||
while ((bytecnt1 < uncompleng) && (bitcnt < (uncompleng<<3)));
|
|
||||||
|
|
||||||
intptr = (int32_t *)&lzwoutbuf[bitcnt>>3];
|
|
||||||
intptr[0] |= B_LITTLE32(addr<<(bitcnt&7));
|
|
||||||
bitcnt += numbits;
|
|
||||||
if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1)))
|
|
||||||
bitcnt--;
|
|
||||||
|
|
||||||
shortptr = (int16_t *)lzwoutbuf;
|
|
||||||
shortptr[0] = B_LITTLE16((int16_t)uncompleng);
|
|
||||||
|
|
||||||
if (((bitcnt+7)>>3) < uncompleng)
|
|
||||||
{
|
|
||||||
shortptr[1] = B_LITTLE16((int16_t)addrcnt);
|
|
||||||
return (bitcnt+7)>>3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Failed compressing, mark this in the stream.
|
|
||||||
shortptr[1] = 0;
|
|
||||||
|
|
||||||
for (i=0; i<uncompleng-4; i+=4)
|
|
||||||
{
|
|
||||||
lzwoutbuf[i+4] = lzwinbuf[i];
|
|
||||||
lzwoutbuf[i+5] = lzwinbuf[i+1];
|
|
||||||
lzwoutbuf[i+6] = lzwinbuf[i+2];
|
|
||||||
lzwoutbuf[i+7] = lzwinbuf[i+3];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i<uncompleng; i++)
|
|
||||||
lzwoutbuf[i+4] = lzwinbuf[i];
|
|
||||||
|
|
||||||
return uncompleng+4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t lzwuncompress(const char *lzwinbuf, int32_t compleng, char *lzwoutbuf)
|
|
||||||
{
|
|
||||||
int32_t currstr, numbits, oneupnumbits;
|
|
||||||
int32_t i, bitcnt, outbytecnt;
|
|
||||||
|
|
||||||
const int16_t *const shortptr = (const int16_t *)lzwinbuf;
|
|
||||||
const int32_t strtot = B_LITTLE16(shortptr[1]);
|
|
||||||
const int32_t uncompleng = B_LITTLE16(shortptr[0]);
|
|
||||||
|
|
||||||
if (strtot == 0)
|
|
||||||
{
|
|
||||||
if (lzwoutbuf==lzwrawbuf && lzwinbuf==lzwcompbuf)
|
|
||||||
{
|
|
||||||
Bassert((compleng-4)+3+0u < sizeof(lzwrawbuf));
|
|
||||||
Bassert((compleng-4)+3+0u < sizeof(lzwcompbuf)-4);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bmemcpy(lzwoutbuf, lzwinbuf+4, (compleng-4)+3);
|
|
||||||
return uncompleng;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=255; i>=4; i-=4)
|
|
||||||
{
|
|
||||||
lzwbuf2[i] = lzwbuf3[i] = i;
|
|
||||||
lzwbuf2[i-1] = lzwbuf3[i-1] = i-1;
|
|
||||||
lzwbuf2[i-2] = lzwbuf3[i-2] = i-2;
|
|
||||||
lzwbuf2[i-3] = lzwbuf3[i-3] = i-3;
|
|
||||||
}
|
|
||||||
|
|
||||||
lzwbuf2[i] = lzwbuf3[i] = i;
|
|
||||||
lzwbuf2[i-1] = lzwbuf3[i-1] = i-1;
|
|
||||||
lzwbuf2[i-2] = lzwbuf3[i-2] = i-2;
|
|
||||||
|
|
||||||
currstr = 256; bitcnt = (4<<3); outbytecnt = 0;
|
|
||||||
numbits = 8; oneupnumbits = (1<<8);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const int32_t *const intptr = (const int32_t *)&lzwinbuf[bitcnt>>3];
|
|
||||||
|
|
||||||
int32_t dat = ((B_LITTLE32(intptr[0])>>(bitcnt&7)) & (oneupnumbits-1));
|
|
||||||
int32_t leng;
|
|
||||||
|
|
||||||
bitcnt += numbits;
|
|
||||||
if ((dat&((oneupnumbits>>1)-1)) > ((currstr-1)&((oneupnumbits>>1)-1)))
|
|
||||||
{ dat &= ((oneupnumbits>>1)-1); bitcnt--; }
|
|
||||||
|
|
||||||
lzwbuf3[currstr] = dat;
|
|
||||||
|
|
||||||
for (leng=0; dat>=256; leng++,dat=lzwbuf3[dat])
|
|
||||||
lzwtmpbuf[leng] = lzwbuf2[dat];
|
|
||||||
|
|
||||||
lzwoutbuf[outbytecnt++] = dat;
|
|
||||||
|
|
||||||
for (i=leng-1; i>=4; i-=4, outbytecnt+=4)
|
|
||||||
{
|
|
||||||
lzwoutbuf[outbytecnt] = lzwtmpbuf[i];
|
|
||||||
lzwoutbuf[outbytecnt+1] = lzwtmpbuf[i-1];
|
|
||||||
lzwoutbuf[outbytecnt+2] = lzwtmpbuf[i-2];
|
|
||||||
lzwoutbuf[outbytecnt+3] = lzwtmpbuf[i-3];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i>=0; i--)
|
|
||||||
lzwoutbuf[outbytecnt++] = lzwtmpbuf[i];
|
|
||||||
|
|
||||||
lzwbuf2[currstr-1] = dat; lzwbuf2[currstr] = dat;
|
|
||||||
currstr++;
|
|
||||||
if (currstr > oneupnumbits)
|
|
||||||
{ numbits++; oneupnumbits <<= 1; }
|
|
||||||
}
|
|
||||||
while (currstr < strtot);
|
|
||||||
|
|
||||||
return uncompleng;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* vim:ts=4:sw=4:
|
|
||||||
*/
|
|
||||||
|
|
361
source/build/src/klzw.cpp
Normal file
361
source/build/src/klzw.cpp
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||||
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||||||
|
// See the included license file "BUILDLIC.TXT" for license info.
|
||||||
|
//
|
||||||
|
// This file has been modified from Ken Silverman's original release
|
||||||
|
// by Jonathon Fowler (jf@jonof.id.au)
|
||||||
|
// by the EDuke32 team (development@voidpoint.com)
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
|
#include "klzw.h"
|
||||||
|
|
||||||
|
//Internal LZW variables
|
||||||
|
#define LZWSIZE 16384 //Watch out for shorts!
|
||||||
|
#define LZWSIZEPAD (LZWSIZE+(LZWSIZE>>4))
|
||||||
|
|
||||||
|
// lzwrawbuf LZWSIZE+1 (formerly): see (*) below
|
||||||
|
// XXX: lzwrawbuf size increased again :-/
|
||||||
|
static char lzwtmpbuf[LZWSIZEPAD], lzwrawbuf[LZWSIZEPAD], lzwcompbuf[LZWSIZEPAD];
|
||||||
|
static int16_t lzwbuf2[LZWSIZEPAD], lzwbuf3[LZWSIZEPAD];
|
||||||
|
|
||||||
|
|
||||||
|
////////// CORE COMPRESSION FUNCTIONS //////////
|
||||||
|
|
||||||
|
static int32_t lzwcompress(const char *lzwinbuf, int32_t uncompleng, char *lzwoutbuf)
|
||||||
|
{
|
||||||
|
int32_t i, addr, addrcnt, *intptr;
|
||||||
|
int32_t bytecnt1, bitcnt, numbits, oneupnumbits;
|
||||||
|
int16_t *shortptr;
|
||||||
|
|
||||||
|
int16_t *const lzwcodehead = lzwbuf2;
|
||||||
|
int16_t *const lzwcodenext = lzwbuf3;
|
||||||
|
|
||||||
|
for (i=255; i>=4; i-=4)
|
||||||
|
{
|
||||||
|
lzwtmpbuf[i] = i, lzwcodenext[i] = (i+1)&255;
|
||||||
|
lzwtmpbuf[i-1] = i-1, lzwcodenext[i-1] = (i) &255;
|
||||||
|
lzwtmpbuf[i-2] = i-2, lzwcodenext[i-2] = (i-1)&255;
|
||||||
|
lzwtmpbuf[i-3] = i-3, lzwcodenext[i-3] = (i-2)&255;
|
||||||
|
lzwcodehead[i] = lzwcodehead[i-1] = lzwcodehead[i-2] = lzwcodehead[i-3] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i>=0; i--)
|
||||||
|
{
|
||||||
|
lzwtmpbuf[i] = i;
|
||||||
|
lzwcodenext[i] = (i+1)&255;
|
||||||
|
lzwcodehead[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bmemset(lzwoutbuf, 0, 4+uncompleng+1);
|
||||||
|
// clearbuf(lzwoutbuf,((uncompleng+15)+3)>>2,0L);
|
||||||
|
|
||||||
|
addrcnt = 256; bytecnt1 = 0; bitcnt = (4<<3);
|
||||||
|
numbits = 8; oneupnumbits = (1<<8);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
addr = lzwinbuf[bytecnt1];
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int32_t newaddr;
|
||||||
|
|
||||||
|
if (++bytecnt1 == uncompleng)
|
||||||
|
break; // (*) see XXX below
|
||||||
|
|
||||||
|
if (lzwcodehead[addr] < 0)
|
||||||
|
{
|
||||||
|
lzwcodehead[addr] = addrcnt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
newaddr = lzwcodehead[addr];
|
||||||
|
while (lzwtmpbuf[newaddr] != lzwinbuf[bytecnt1])
|
||||||
|
{
|
||||||
|
if (lzwcodenext[newaddr] < 0)
|
||||||
|
{
|
||||||
|
lzwcodenext[newaddr] = addrcnt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newaddr = lzwcodenext[newaddr];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lzwcodenext[newaddr] == addrcnt)
|
||||||
|
break;
|
||||||
|
addr = newaddr;
|
||||||
|
}
|
||||||
|
while (addr >= 0);
|
||||||
|
|
||||||
|
lzwtmpbuf[addrcnt] = lzwinbuf[bytecnt1]; // XXX: potential oob access of lzwinbuf via (*) above
|
||||||
|
lzwcodehead[addrcnt] = -1;
|
||||||
|
lzwcodenext[addrcnt] = -1;
|
||||||
|
|
||||||
|
intptr = (int32_t *)&lzwoutbuf[bitcnt>>3];
|
||||||
|
intptr[0] |= B_LITTLE32(addr<<(bitcnt&7));
|
||||||
|
bitcnt += numbits;
|
||||||
|
if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1)))
|
||||||
|
bitcnt--;
|
||||||
|
|
||||||
|
addrcnt++;
|
||||||
|
if (addrcnt > oneupnumbits)
|
||||||
|
{ numbits++; oneupnumbits <<= 1; }
|
||||||
|
}
|
||||||
|
while ((bytecnt1 < uncompleng) && (bitcnt < (uncompleng<<3)));
|
||||||
|
|
||||||
|
intptr = (int32_t *)&lzwoutbuf[bitcnt>>3];
|
||||||
|
intptr[0] |= B_LITTLE32(addr<<(bitcnt&7));
|
||||||
|
bitcnt += numbits;
|
||||||
|
if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1)))
|
||||||
|
bitcnt--;
|
||||||
|
|
||||||
|
shortptr = (int16_t *)lzwoutbuf;
|
||||||
|
shortptr[0] = B_LITTLE16((int16_t)uncompleng);
|
||||||
|
|
||||||
|
if (((bitcnt+7)>>3) < uncompleng)
|
||||||
|
{
|
||||||
|
shortptr[1] = B_LITTLE16((int16_t)addrcnt);
|
||||||
|
return (bitcnt+7)>>3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed compressing, mark this in the stream.
|
||||||
|
shortptr[1] = 0;
|
||||||
|
|
||||||
|
for (i=0; i<uncompleng-4; i+=4)
|
||||||
|
{
|
||||||
|
lzwoutbuf[i+4] = lzwinbuf[i];
|
||||||
|
lzwoutbuf[i+5] = lzwinbuf[i+1];
|
||||||
|
lzwoutbuf[i+6] = lzwinbuf[i+2];
|
||||||
|
lzwoutbuf[i+7] = lzwinbuf[i+3];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i<uncompleng; i++)
|
||||||
|
lzwoutbuf[i+4] = lzwinbuf[i];
|
||||||
|
|
||||||
|
return uncompleng+4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t lzwuncompress(const char *lzwinbuf, int32_t compleng, char *lzwoutbuf)
|
||||||
|
{
|
||||||
|
int32_t currstr, numbits, oneupnumbits;
|
||||||
|
int32_t i, bitcnt, outbytecnt;
|
||||||
|
|
||||||
|
const int16_t *const shortptr = (const int16_t *)lzwinbuf;
|
||||||
|
const int32_t strtot = B_LITTLE16(shortptr[1]);
|
||||||
|
const int32_t uncompleng = B_LITTLE16(shortptr[0]);
|
||||||
|
|
||||||
|
if (strtot == 0)
|
||||||
|
{
|
||||||
|
if (lzwoutbuf==lzwrawbuf && lzwinbuf==lzwcompbuf)
|
||||||
|
{
|
||||||
|
Bassert((compleng-4)+3+0u < sizeof(lzwrawbuf));
|
||||||
|
Bassert((compleng-4)+3+0u < sizeof(lzwcompbuf)-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bmemcpy(lzwoutbuf, lzwinbuf+4, (compleng-4)+3);
|
||||||
|
return uncompleng;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=255; i>=4; i-=4)
|
||||||
|
{
|
||||||
|
lzwbuf2[i] = lzwbuf3[i] = i;
|
||||||
|
lzwbuf2[i-1] = lzwbuf3[i-1] = i-1;
|
||||||
|
lzwbuf2[i-2] = lzwbuf3[i-2] = i-2;
|
||||||
|
lzwbuf2[i-3] = lzwbuf3[i-3] = i-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
lzwbuf2[i] = lzwbuf3[i] = i;
|
||||||
|
lzwbuf2[i-1] = lzwbuf3[i-1] = i-1;
|
||||||
|
lzwbuf2[i-2] = lzwbuf3[i-2] = i-2;
|
||||||
|
|
||||||
|
currstr = 256; bitcnt = (4<<3); outbytecnt = 0;
|
||||||
|
numbits = 8; oneupnumbits = (1<<8);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const int32_t *const intptr = (const int32_t *)&lzwinbuf[bitcnt>>3];
|
||||||
|
|
||||||
|
int32_t dat = ((B_LITTLE32(intptr[0])>>(bitcnt&7)) & (oneupnumbits-1));
|
||||||
|
int32_t leng;
|
||||||
|
|
||||||
|
bitcnt += numbits;
|
||||||
|
if ((dat&((oneupnumbits>>1)-1)) > ((currstr-1)&((oneupnumbits>>1)-1)))
|
||||||
|
{ dat &= ((oneupnumbits>>1)-1); bitcnt--; }
|
||||||
|
|
||||||
|
lzwbuf3[currstr] = dat;
|
||||||
|
|
||||||
|
for (leng=0; dat>=256; leng++,dat=lzwbuf3[dat])
|
||||||
|
lzwtmpbuf[leng] = lzwbuf2[dat];
|
||||||
|
|
||||||
|
lzwoutbuf[outbytecnt++] = dat;
|
||||||
|
|
||||||
|
for (i=leng-1; i>=4; i-=4, outbytecnt+=4)
|
||||||
|
{
|
||||||
|
lzwoutbuf[outbytecnt] = lzwtmpbuf[i];
|
||||||
|
lzwoutbuf[outbytecnt+1] = lzwtmpbuf[i-1];
|
||||||
|
lzwoutbuf[outbytecnt+2] = lzwtmpbuf[i-2];
|
||||||
|
lzwoutbuf[outbytecnt+3] = lzwtmpbuf[i-3];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i>=0; i--)
|
||||||
|
lzwoutbuf[outbytecnt++] = lzwtmpbuf[i];
|
||||||
|
|
||||||
|
lzwbuf2[currstr-1] = dat; lzwbuf2[currstr] = dat;
|
||||||
|
currstr++;
|
||||||
|
if (currstr > oneupnumbits)
|
||||||
|
{ numbits++; oneupnumbits <<= 1; }
|
||||||
|
}
|
||||||
|
while (currstr < strtot);
|
||||||
|
|
||||||
|
return uncompleng;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////// COMPRESSED READ //////////
|
||||||
|
|
||||||
|
struct decompress_info
|
||||||
|
{
|
||||||
|
klzw_readfunc readfunc;
|
||||||
|
intptr_t f;
|
||||||
|
uint32_t kgoal;
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t decompress_part(struct decompress_info * x)
|
||||||
|
{
|
||||||
|
intptr_t const f = x->f;
|
||||||
|
auto readfunc = x->readfunc;
|
||||||
|
|
||||||
|
// Read compressed length first.
|
||||||
|
int16_t leng;
|
||||||
|
if (readfunc(f, &leng, sizeof(leng)) != sizeof(leng))
|
||||||
|
return 1;
|
||||||
|
leng = B_LITTLE16(leng);
|
||||||
|
|
||||||
|
if (readfunc(f, lzwcompbuf, leng) != leng)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
x->kgoal = lzwuncompress(lzwcompbuf, leng, lzwrawbuf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from 'f' into 'buffer'.
|
||||||
|
int32_t klzw_read_compressed(void *buffer, bsize_t dasizeof, bsize_t count, intptr_t f, klzw_readfunc readfunc)
|
||||||
|
{
|
||||||
|
char *ptr = (char *)buffer;
|
||||||
|
|
||||||
|
if (dasizeof > LZWSIZE)
|
||||||
|
{
|
||||||
|
count *= dasizeof;
|
||||||
|
dasizeof = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct decompress_info x;
|
||||||
|
x.readfunc = readfunc;
|
||||||
|
x.f = f;
|
||||||
|
|
||||||
|
if (decompress_part(&x))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
Bmemcpy(ptr, lzwrawbuf, (int32_t)dasizeof);
|
||||||
|
|
||||||
|
uint32_t k = (int32_t)dasizeof;
|
||||||
|
|
||||||
|
for (uint32_t i=1; i<count; i++)
|
||||||
|
{
|
||||||
|
if (k >= x.kgoal)
|
||||||
|
{
|
||||||
|
k = decompress_part(&x);
|
||||||
|
if (k) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t j = 0;
|
||||||
|
|
||||||
|
if (dasizeof >= 4)
|
||||||
|
{
|
||||||
|
for (; j<dasizeof-4; j+=4)
|
||||||
|
{
|
||||||
|
ptr[j+dasizeof] = ((ptr[j]+lzwrawbuf[j+k])&255);
|
||||||
|
ptr[j+1+dasizeof] = ((ptr[j+1]+lzwrawbuf[j+1+k])&255);
|
||||||
|
ptr[j+2+dasizeof] = ((ptr[j+2]+lzwrawbuf[j+2+k])&255);
|
||||||
|
ptr[j+3+dasizeof] = ((ptr[j+3]+lzwrawbuf[j+3+k])&255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; j<dasizeof; j++)
|
||||||
|
ptr[j+dasizeof] = ((ptr[j]+lzwrawbuf[j+k])&255);
|
||||||
|
|
||||||
|
k += dasizeof;
|
||||||
|
ptr += dasizeof;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////// COMPRESSED WRITE //////////
|
||||||
|
|
||||||
|
struct compress_info
|
||||||
|
{
|
||||||
|
klzw_writefunc writefunc;
|
||||||
|
intptr_t f;
|
||||||
|
uint32_t k;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void compress_part(struct compress_info * x)
|
||||||
|
{
|
||||||
|
const int16_t leng = (int16_t)lzwcompress(lzwrawbuf, x->k, lzwcompbuf);
|
||||||
|
const int16_t swleng = B_LITTLE16(leng);
|
||||||
|
|
||||||
|
intptr_t const f = x->f;
|
||||||
|
auto writefunc = x->writefunc;
|
||||||
|
|
||||||
|
x->k = 0;
|
||||||
|
|
||||||
|
writefunc(f, &swleng, sizeof(swleng));
|
||||||
|
writefunc(f, lzwcompbuf, leng);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write from 'buffer' to 'f'.
|
||||||
|
void klzw_write_compressed(const void *buffer, bsize_t dasizeof, bsize_t count, intptr_t f, klzw_writefunc writefunc)
|
||||||
|
{
|
||||||
|
char const *ptr = (char const *)buffer;
|
||||||
|
|
||||||
|
if (dasizeof > LZWSIZE)
|
||||||
|
{
|
||||||
|
count *= dasizeof;
|
||||||
|
dasizeof = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bmemcpy(lzwrawbuf, ptr, (int32_t)dasizeof);
|
||||||
|
|
||||||
|
struct compress_info x;
|
||||||
|
x.writefunc = writefunc;
|
||||||
|
x.f = f;
|
||||||
|
|
||||||
|
if ((x.k = dasizeof) > LZWSIZE-dasizeof)
|
||||||
|
compress_part(&x);
|
||||||
|
|
||||||
|
for (uint32_t i=1; i<count; i++)
|
||||||
|
{
|
||||||
|
uint32_t j = 0;
|
||||||
|
|
||||||
|
if (dasizeof >= 4)
|
||||||
|
{
|
||||||
|
for (; j<dasizeof-4; j+=4)
|
||||||
|
{
|
||||||
|
lzwrawbuf[j+x.k] = ((ptr[j+dasizeof]-ptr[j])&255);
|
||||||
|
lzwrawbuf[j+1+x.k] = ((ptr[j+1+dasizeof]-ptr[j+1])&255);
|
||||||
|
lzwrawbuf[j+2+x.k] = ((ptr[j+2+dasizeof]-ptr[j+2])&255);
|
||||||
|
lzwrawbuf[j+3+x.k] = ((ptr[j+3+dasizeof]-ptr[j+3])&255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; j<dasizeof; j++)
|
||||||
|
lzwrawbuf[j+x.k] = ((ptr[j+dasizeof]-ptr[j])&255);
|
||||||
|
|
||||||
|
if ((x.k += dasizeof) > LZWSIZE-dasizeof)
|
||||||
|
compress_part(&x);
|
||||||
|
|
||||||
|
ptr += dasizeof;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x.k > 0)
|
||||||
|
compress_part(&x);
|
||||||
|
}
|
Loading…
Reference in a new issue