aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/scicore/exe_lzexe.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/scicore/exe_lzexe.cpp')
-rw-r--r--engines/sci/scicore/exe_lzexe.cpp328
1 files changed, 0 insertions, 328 deletions
diff --git a/engines/sci/scicore/exe_lzexe.cpp b/engines/sci/scicore/exe_lzexe.cpp
deleted file mode 100644
index a8876b3bc5..0000000000
--- a/engines/sci/scicore/exe_lzexe.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/* Based on public domain code by Mitugu Kurizono. */
-
-#include "sci/include/sci_memory.h"
-#include "sci/scicore/exe_dec.h"
-
-/* Macro to interpret two sequential bytes as an unsigned integer. */
-#define UINT16(A) ((*((A) + 1) << 8) + *(A))
-
-/* The amount of most recent data (in bytes) that we need to keep in the
-** buffer. lzexe compression is based on copying chunks of previous data to
-** form new data.
-*/
-#define LZEXE_WINDOW 8192
-
-/* Buffer size. */
-#define LZEXE_BUFFER_SIZE (LZEXE_WINDOW + 4096)
-
-/* Maximum amount of data (in bytes) that can be in the buffer at the start
-** of the decompression loop. The maximum amount of data that can be added
-** to the buffer during a single step of the loop is 256 bytes.
-*/
-#define LZEXE_BUFFER_MAX (LZEXE_BUFFER_SIZE - 256)
-
-struct _exe_handle {
- FILE *f;
-
- /* Output buffer. */
- guint8 buffer[LZEXE_BUFFER_SIZE];
- guint8 *bufptr;
-
- /* Bit buffer. Bits [0..count) still contain unprocessed data. */
- int buf;
- int count;
-
- /* End of data flag. */
- int eod;
-};
-
-static int
-lzexe_read_uint16(FILE *f, int *value) {
- int data;
-
- if ((*value = fgetc(f)) == EOF)
- return 0;
-
- if ((data = fgetc(f)) == EOF)
- return 0;
-
- *value |= data << 8;
- return 1;
-}
-
-static int
-lzexe_read_uint8(FILE *f, int *value) {
- if ((*value = fgetc(f)) == EOF)
- return 0;
-
- return 1;
-}
-
-static int
-lzexe_init(exe_handle_t *handle, FILE *f) {
- handle->f = f;
- handle->bufptr = handle->buffer;
- handle->eod = 0;
-
- if (!lzexe_read_uint16(handle->f, &handle->buf))
- return 0;
-
- handle->count = 16;
- return 1;
-}
-
-static int
-lzexe_get_bit(exe_handle_t *handle, int *bit) {
- *bit = handle->buf & 1;
-
- if (--handle->count == 0) {
- if (!lzexe_read_uint16(handle->f, &handle->buf))
- return 0;
- handle->count = 16;
- } else
- handle->buf >>= 1;
-
- return 1;
-}
-
-static int
-lzexe_decompress(exe_handle_t *handle) {
- while (!handle->eod
- && handle->bufptr - handle->buffer <= LZEXE_BUFFER_MAX) {
- int bit;
- int len, span;
-
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- if (bit) {
- /* 1: copy byte verbatim. */
-
- int data;
-
- if (!lzexe_read_uint8(handle->f, &data))
- return 0;
-
- *handle->bufptr++ = data;
-
- continue;
- }
-
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- if (!bit) {
- /* 00: copy small block. */
-
- /* Next two bits indicate block length - 2. */
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- len = bit << 1;
-
- if (!lzexe_get_bit(handle, &bit))
- return 0;
-
- len |= bit;
- len += 2;
-
- /* Read span byte. This forms the low byte of a
- ** negative two's compliment value.
- */
- if (!lzexe_read_uint8(handle->f, &span))
- return 0;
-
- /* Convert to negative integer. */
- span -= 256;
- } else {
- /* 01: copy large block. */
- int data;
-
- /* Read low byte of span value. */
- if (!lzexe_read_uint8(handle->f, &span))
- return 0;
-
- /* Read next byte. Bits [7..3] contain bits [12..8]
- ** of span value. Bits [2..0] contain block length -
- ** 2.
- */
- if (!lzexe_read_uint8(handle->f, &data))
- return 0;
- span |= (data & 0xf8) << 5;
- /* Convert to negative integer. */
- span -= 8192;
-
- len = (data & 7) + 2;
-
- if (len == 2) {
- /* Next byte is block length value - 1. */
- if (!lzexe_read_uint8(handle->f, &len))
- return 0;
-
- if (len == 0) {
- /* End of data reached. */
- handle->eod = 1;
- break;
- }
-
- if (len == 1)
- /* Segment change marker. */
- continue;
-
- len++;
- }
- }
-
- assert(handle->bufptr + span >= handle->buffer);
-
- /* Copy block. */
- while (len-- > 0) {
- *handle->bufptr = *(handle->bufptr + span);
- handle->bufptr++;
- }
- }
-
- return 1;
-}
-
-static exe_handle_t *
-lzexe_open(const char *filename) {
- exe_handle_t *handle;
- guint8 head[0x20];
- guint8 size[2];
- off_t fpos;
-
- FILE *f = sci_fopen(filename, "rb");
-
- if (!f)
- return NULL;
-
- /* Read exe header plus possible lzexe signature. */
- if (fread(head, 1, 0x20, f) != 0x20)
- return NULL;
-
- /* Verify "MZ" signature, header size == 2 paragraphs and number of
- ** overlays == 0.
- */
- if (UINT16(head) != 0x5a4d || UINT16(head + 8) != 2
- || UINT16(head + 0x1a) != 0)
- return NULL;
-
- /* Verify that first relocation item offset is 0x1c. */
- if (UINT16(head + 0x18) != 0x1c)
- return NULL;
-
- /* Look for lzexe signature. */
- if (memcmp(head + 0x1c, "LZ09", 4)
- && memcmp(head + 0x1c, "LZ91", 4)) {
- return NULL;
- }
-
- /* Calculate code segment offset in exe file. */
- fpos = (UINT16(head + 0x16) + UINT16(head + 8)) << 4;
- /* Seek to offset 8 of info table at start of code segment. */
- if (fseek(f, fpos + 8, SEEK_SET) == -1)
- return NULL;
-
- /* Read size of compressed data in paragraphs. */
- if (fread(size, 1, 2, f) != 2)
- return NULL;
-
- /* Move file pointer to start of compressed data. */
- fpos -= UINT16(size) << 4;
- if (fseek(f, fpos, SEEK_SET) == -1)
- return NULL;
-
- handle = (exe_handle_t*)sci_malloc(sizeof(exe_handle_t));
-
- if (!lzexe_init(handle, f)) {
- free(handle);
- return NULL;
- }
-
- return handle;
-}
-
-static int
-lzexe_read(exe_handle_t *handle, void *buf, int count) {
- int done = 0;
-
- while (done != count) {
- int size, copy, i;
- int left = count - done;
-
- if (!lzexe_decompress(handle))
- return done;
-
- /* Total amount of bytes in buffer. */
- size = handle->bufptr - handle->buffer;
-
- /* If we're not at end of data we need to maintain the
- ** window.
- */
- if (!handle->eod)
- copy = size - LZEXE_WINDOW;
- else {
- if (size == 0)
- /* No data left. */
- return done;
-
- copy = size;
- }
-
- /* Do not copy more than requested. */
- if (copy > left)
- copy = left;
-
- memcpy((char *) buf + done, handle->buffer, copy);
-
- /* Move remaining data to start of buffer. */
- for (i = copy; i < size; i++)
- handle->buffer[i - copy] = handle->buffer[i];
-
- handle->bufptr -= copy;
- done += copy;
- }
-
- return done;
-}
-
-static void
-lzexe_close(exe_handle_t *handle) {
- fclose(handle->f);
-
- free(handle);
-}
-
-exe_decompressor_t
-exe_decompressor_lzexe = {
- "lzexe",
- lzexe_open,
- lzexe_read,
- lzexe_close
-};