Rizin
unix-like reverse engineering framework and cli tools
lzssd.c File Reference
#include <system.h>
#include <lzss.h>

Go to the source code of this file.

Macros

#define ENSURE_BYTES
 
#define WRITE_BYTE
 

Functions

int lzss_decompress (struct mspack_system *system, struct mspack_file *input, struct mspack_file *output, int input_buffer_size, int mode)
 

Macro Definition Documentation

◆ ENSURE_BYTES

#define ENSURE_BYTES
Value:
do { \
if (i_ptr >= i_end) { \
read = system->read(input, &inbuf[0], \
input_buffer_size); \
if (read <= 0) { \
system->free(window); \
return (read < 0) ? MSPACK_ERR_READ \
} \
i_ptr = &inbuf[0]; i_end = &inbuf[read]; \
} \
} while (0)
#define MSPACK_ERR_OK
Definition: mspack.h:485
#define MSPACK_ERR_READ
Definition: mspack.h:491
unsigned char inbuf[SIZE]
Definition: gun.c:161
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

Definition at line 17 of file lzssd.c.

◆ WRITE_BYTE

#define WRITE_BYTE
Value:
do { \
if (system->write(output, &window[pos], 1) != 1) { \
system->free(window); \
return MSPACK_ERR_WRITE; \
} \
} while (0)
#define MSPACK_ERR_WRITE
Definition: mspack.h:493
int pos
Definition: main.c:11
diff_output_t output
Definition: zipcmp.c:237

Definition at line 30 of file lzssd.c.

Function Documentation

◆ lzss_decompress()

int lzss_decompress ( struct mspack_system system,
struct mspack_file input,
struct mspack_file output,
int  input_buffer_size,
int  mode 
)

Decompresses an LZSS stream.

Input bytes will be read in as necessary using the system->read() function with the input file handle given. This will continue until system->read() returns 0 bytes, or an error. Errors will be passed out of the function as MSPACK_ERR_READ errors. Input streams should convey an "end of input stream" by refusing to supply all the bytes that LZSS asks for when they reach the end of the stream, rather than return an error code.

Output bytes will be passed to the system->write() function, using the output file handle given. More than one call may be made to system->write().

As EXPAND.EXE (SZDD/KWAJ), Microsoft Help and QBasic have slightly different encodings for the control byte and matches, a "mode" parameter is allowed, to choose the encoding.

Parameters
systeman mspack_system structure used to read from the input stream and write to the output stream, also to allocate and free memory.
inputan input stream with the LZSS data.
outputan output stream to write the decoded data to.
input_buffer_sizethe number of bytes to use as an input bitstream buffer.
modeone of LZSS_MODE_EXPAND, LZSS_MODE_MSHELP or LZSS_MODE_QBASIC
Returns
an error code, or MSPACK_ERR_OK if successful

Definition at line 37 of file lzssd.c.

42 {
43  unsigned char *window, *inbuf, *i_ptr, *i_end;
44  unsigned int pos, i, c, invert, mpos, len;
45  int read;
46 
47  /* check parameters */
48  if (!system || input_buffer_size < 1 || (mode != LZSS_MODE_EXPAND &&
50  {
51  return MSPACK_ERR_ARGS;
52  }
53 
54  /* allocate memory */
55  window = (unsigned char *) system->alloc(system, LZSS_WINDOW_SIZE + input_buffer_size);
56  if (!window) return MSPACK_ERR_NOMEMORY;
57 
58  /* initialise decompression */
61  pos = LZSS_WINDOW_SIZE - ((mode == LZSS_MODE_QBASIC) ? 18 : 16);
62  invert = (mode == LZSS_MODE_MSHELP) ? ~0 : 0;
63  i_ptr = i_end = &inbuf[0];
64 
65  /* loop forever; exit condition is in ENSURE_BYTES macro */
66  for (;;) {
67  ENSURE_BYTES; c = *i_ptr++ ^ invert;
68  for (i = 0x01; i & 0xFF; i <<= 1) {
69  if (c & i) {
70  /* literal */
71  ENSURE_BYTES; window[pos] = *i_ptr++;
72  WRITE_BYTE;
73  pos++; pos &= LZSS_WINDOW_SIZE - 1;
74  }
75  else {
76  /* match */
77  ENSURE_BYTES; mpos = *i_ptr++;
78  ENSURE_BYTES; mpos |= (*i_ptr & 0xF0) << 4;
79  len = (*i_ptr++ & 0x0F) + 3;
80  while (len--) {
81  window[pos] = window[mpos];
82  WRITE_BYTE;
83  pos++; pos &= LZSS_WINDOW_SIZE - 1;
84  mpos++; mpos &= LZSS_WINDOW_SIZE - 1;
85  }
86  }
87  }
88  }
89 
90  /* not reached */
91  system->free(window);
92  return MSPACK_ERR_OK;
93 }
size_t len
Definition: 6502dis.c:15
static unsigned invert(unsigned x)
Definition: aesdata.c:73
lzma_index ** i
Definition: index.h:629
#define MSPACK_ERR_ARGS
Definition: mspack.h:487
#define MSPACK_ERR_NOMEMORY
Definition: mspack.h:497
const char int mode
Definition: ioapi.h:137
return memset(p, 0, total)
#define LZSS_WINDOW_FILL
Definition: lzss.h:20
#define LZSS_WINDOW_SIZE
Definition: lzss.h:19
#define LZSS_MODE_EXPAND
Definition: lzss.h:22
#define LZSS_MODE_QBASIC
Definition: lzss.h:24
#define LZSS_MODE_MSHELP
Definition: lzss.h:23
#define WRITE_BYTE
Definition: lzssd.c:30
#define ENSURE_BYTES
Definition: lzssd.c:17
#define c(i)
Definition: sha256.c:43
void(* free)(void *ptr)
Definition: mspack.h:430
void *(* alloc)(struct mspack_system *self, size_t bytes)
Definition: mspack.h:421
struct _window window

References mspack_system::alloc, c, ENSURE_BYTES, mspack_system::free, i, inbuf, invert(), len, LZSS_MODE_EXPAND, LZSS_MODE_MSHELP, LZSS_MODE_QBASIC, LZSS_WINDOW_FILL, LZSS_WINDOW_SIZE, memset(), MSPACK_ERR_ARGS, MSPACK_ERR_NOMEMORY, MSPACK_ERR_OK, pos, read(), and WRITE_BYTE.

Referenced by kwajd_extract(), and szddd_extract().