diff options
Diffstat (limited to 'engines/sci/scicore/exe_lzexe.cpp')
-rw-r--r-- | engines/sci/scicore/exe_lzexe.cpp | 328 |
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 -}; |