[Scummvm-cvs-logs] SF.net SVN: scummvm: [32460] scummvm/trunk/common

sev at users.sourceforge.net sev at users.sourceforge.net
Sun Jun 1 13:43:20 CEST 2008


Revision: 32460
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32460&view=rev
Author:   sev
Date:     2008-06-01 04:43:20 -0700 (Sun, 01 Jun 2008)

Log Message:
-----------
Unarj code based on unarj 2.62. Used by Drascula engine

Modified Paths:
--------------
    scummvm/trunk/common/module.mk

Added Paths:
-----------
    scummvm/trunk/common/unarj.cpp
    scummvm/trunk/common/unarj.h

Modified: scummvm/trunk/common/module.mk
===================================================================
--- scummvm/trunk/common/module.mk	2008-06-01 11:13:55 UTC (rev 32459)
+++ scummvm/trunk/common/module.mk	2008-06-01 11:43:20 UTC (rev 32460)
@@ -14,6 +14,7 @@
 	stream.o \
 	util.o \
 	system.o \
+	unarj.o \
 	unzip.o \
 	zlib.o
 

Added: scummvm/trunk/common/unarj.cpp
===================================================================
--- scummvm/trunk/common/unarj.cpp	                        (rev 0)
+++ scummvm/trunk/common/unarj.cpp	2008-06-01 11:43:20 UTC (rev 32460)
@@ -0,0 +1,666 @@
+/* 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$
+ *
+ */
+
+// Heavily based on Unarj 2.65
+
+/* UNARJ.C, UNARJ, R JUNG, 06/05/02
+ * Main Extractor routine
+ * Copyright (c) 1991-2002 by ARJ Software, Inc.  All rights reserved.
+ *
+ *   This code may be freely used in programs that are NOT ARJ archivers
+ *   (both compress and extract ARJ archives).
+ *
+ *   If you wish to distribute a modified version of this program, you
+ *   MUST indicate that it is a modified version both in the program and
+ *   source code.
+ *
+ *   We are holding the copyright on the source code, so please do not
+ *   delete our name from the program files or from the documentation.
+ *
+ *   We wish to give credit to Haruhiko Okumura for providing the
+ *   basic ideas for ARJ and UNARJ in his program AR.  Please note
+ *   that UNARJ is significantly different from AR from an archive
+ *   structural point of view.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/util.h"
+#include "common/unarj.h"
+
+namespace Common {
+
+static uint32 CRCtable[256];
+
+static void	InitCRC(void) {
+	const uint32 poly = 0xEDB88320;
+	int i, j;
+	uint32 n;
+
+	for (i = 0; i < 256; i++) {
+		n = i;
+		for (j = 0; j < 8; j++)
+			n = (n & 1) ? ((n >> 1) ^ poly) : (n >> 1);
+		CRCtable[i] = n;
+	}
+}
+
+static uint32 GetCRC(byte *data, int len) {
+	uint32 CRC = 0xFFFFFFFF;
+	int i;
+	for (i = 0; i < len; i++)
+		CRC = (CRC >> 8) ^ CRCtable[(CRC ^ data[i]) & 0xFF];
+	return CRC ^ 0xFFFFFFFF;
+}
+
+ArjFile::ArjFile() {
+	InitCRC();
+}
+
+ArjFile::~ArjFile() {
+	close();
+
+	for (uint i = 0; i < _headers.size(); i++)
+		delete _headers[i];
+
+	_headers.clear();
+}
+
+void ArjFile::registerArchive(const String &filename) {
+	int32 first_hdr_pos;
+	ArjHeader *header;
+
+	if (!_currArchive.open(filename))
+		return;
+
+	first_hdr_pos = findHeader();
+
+	if (first_hdr_pos < 0) {
+		warning("ArjFile::registerArchive(): Could not find a valid header");
+		return;
+	}
+
+	_currArchive.seek(first_hdr_pos, SEEK_SET);
+	if (readHeader() == NULL)
+		return;
+
+	while ((header = readHeader()) != NULL) {
+		_headers.push_back(header);
+
+		_currArchive.seek(header->compSize, SEEK_CUR);
+
+		_fileMap[header->filename] = _headers.size() - 1;
+		_archMap[header->filename] = filename;
+	}
+
+	_currArchive.close();
+
+	debug(0, "ArjFile::registerArchive(%s): Located %d files", filename.c_str(), _headers.size());
+}
+
+int32 ArjFile::findHeader(void) {
+	long arcpos, lastpos;
+	int c;
+	byte header[HEADERSIZE_MAX];
+	uint32 crc;
+	uint16 headersize;
+
+	arcpos = _currArchive.pos();
+	_currArchive.seek(0L, SEEK_END);
+	lastpos = _currArchive.pos() - 2;
+	if (lastpos > MAXSFX)
+		lastpos = MAXSFX;
+
+	for ( ; arcpos < lastpos; arcpos++) {
+		_currArchive.seek(arcpos, SEEK_SET);
+		c = _currArchive.readByte();
+		while (arcpos < lastpos) {
+			if (c != HEADER_ID_LO)  // low order first
+				c = _currArchive.readByte();
+			else if ((c = _currArchive.readByte()) == HEADER_ID_HI)
+				break;
+			arcpos++;
+		}
+		if (arcpos >= lastpos)
+			break;
+		if ((headersize = _currArchive.readUint16LE()) <= HEADERSIZE_MAX) {
+			_currArchive.read(header, headersize);
+			crc = GetCRC(header, headersize);
+			if (crc == _currArchive.readUint32LE()) {
+				_currArchive.seek(arcpos, SEEK_SET);
+				return arcpos;
+			}
+		}
+	}
+	return -1;		  // could not find a valid header
+}
+
+ArjHeader *ArjFile::readHeader() {
+	ArjHeader header;
+	ArjHeader *head;
+	byte headData[HEADERSIZE_MAX];
+
+	header.id = _currArchive.readUint16LE();
+	if (header.id != HEADER_ID) {
+		warning("ArjFile::readHeader(): Bad header ID (%x)", header.id);
+
+		return NULL;
+	}
+
+	header.headerSize = _currArchive.readUint16LE();
+	if (header.headerSize == 0)
+		return NULL;			// end of archive
+	if (header.headerSize > HEADERSIZE_MAX) {
+		warning("ArjFile::readHeader(): Bad header");
+
+		return NULL;
+	}
+
+	int rSize = _currArchive.read(headData, header.headerSize);
+
+	MemoryReadStream readS(headData, rSize);
+
+	header.headerCrc = _currArchive.readUint32LE();
+	if (GetCRC(headData, header.headerSize) != header.headerCrc) {
+		warning("ArjFile::readHeader(): Bad header CRC");
+		return NULL;
+	}
+
+	header.firstHdrSize = readS.readByte();
+	header.nbr = readS.readByte();
+	header.xNbr = readS.readByte();
+	header.hostOs = readS.readByte();
+	header.flags = readS.readByte();
+	header.method = readS.readByte();
+	header.fileType = readS.readByte();
+	(void)readS.readByte();
+	header.timeStamp = readS.readUint32LE();
+	header.compSize = readS.readSint32LE();
+	header.origSize = readS.readSint32LE();
+	header.fileCRC = readS.readUint32LE();
+	header.entryPos = readS.readUint16LE();
+	header.fileMode = readS.readUint16LE();
+	header.hostData = readS.readUint16LE();
+
+	if (header.origSize < 0 || header.compSize < 0) {
+		warning("ArjFile::readHeader(): Wrong file size");
+		return NULL;
+	}
+
+	strncpy(header.filename, (const char *)&headData[header.firstHdrSize], FNAME_MAX);
+
+	strncpy(header.comment, (const char *)&headData[header.firstHdrSize + strlen(header.filename) + 1], COMMENT_MAX);
+
+	/* if extheadersize == 0 then no CRC */
+	/* otherwise read extheader data and read 4 bytes for CRC */
+
+	while ((header.extHeaderSize = _currArchive.readUint16LE()) != 0)
+		_currArchive.seek((long)(header.extHeaderSize + 4), SEEK_CUR);
+
+	header.pos = _currArchive.pos();
+
+	head = new ArjHeader(header);
+
+	return head;
+}
+
+
+bool ArjFile::open(const Common::String &filename, AccessMode mode) {
+	_isOpen = false;
+
+	if (!_fileMap.contains(filename))
+		return false;
+
+	_isOpen = true;
+
+	ArjHeader *hdr = _headers[_fileMap[filename]];
+
+	_compsize = hdr->compSize;
+	_origsize = hdr->origSize;
+
+	_uncompressedData = (byte *)malloc(_origsize);
+	_outstream = new MemoryWriteStream(_uncompressedData, _origsize);
+
+	_currArchive.open(_archMap[filename]);
+	_currArchive.seek(hdr->pos, SEEK_SET);
+
+	if (hdr->method == 0) // store
+        _currArchive.read(_uncompressedData, _origsize);
+    else if (hdr->method == 1 || hdr->method == 2 || hdr->method == 3)
+        decode();
+    else if (hdr->method == 4)
+        decode_f();
+
+	_currArchive.close();
+	delete _outstream;
+	_outstream = NULL;
+
+	_uncompressed = new MemoryReadStream(_uncompressedData, _origsize);
+
+	return true;
+}
+
+void ArjFile::close() {
+	_isOpen = false;
+
+	delete _uncompressed;
+	_uncompressed = NULL;
+
+	free(_uncompressedData);
+	_uncompressedData = NULL;
+}
+
+uint32 ArjFile::read(void *dataPtr, uint32 dataSize) {
+	return _uncompressed->read(dataPtr, dataSize);
+}
+
+bool ArjFile::eos() {
+	return _uncompressed->eos();
+}
+
+uint32 ArjFile::pos() {
+	return _uncompressed->pos();
+}
+
+uint32 ArjFile::size() {
+	return _uncompressed->size();
+}
+
+void ArjFile::seek(int32 offset, int whence) {
+	_uncompressed->seek(offset, whence);
+}
+
+void ArjFile::init_getbits() {
+	_bitbuf = 0;
+	_subbitbuf = 0;
+	_bitcount = 0;
+	fillbuf(2 * CHAR_BIT);
+}
+
+void ArjFile::fillbuf(int n) {    // Shift bitbuf n bits left, read n bits
+	_bitbuf = (_bitbuf << n) & 0xFFFF;  /* lose the first n bits */
+	while (n > _bitcount) {
+		_bitbuf |= _subbitbuf << (n -= _bitcount);
+		if (_compsize != 0) {
+			_compsize--;
+			_subbitbuf = _currArchive.readByte();
+		} else
+			_subbitbuf = 0;
+		_bitcount = CHAR_BIT;
+	}
+	_bitbuf |= _subbitbuf >> (_bitcount -= n);
+}
+
+uint16 ArjFile::getbits(int n) {
+	uint16 x;
+
+	x = _bitbuf >> (2 * CHAR_BIT - n);
+	fillbuf(n);
+	return x;
+}
+
+
+
+/* Huffman decode routines */
+
+void ArjFile::make_table(int nchar, byte *bitlen, int tablebits, uint16 *table, int tablesize) {
+	uint16 count[17], weight[17], start[18], *p;
+	uint i, k, len, ch, jutbits, avail, nextcode, mask;
+
+	for (i = 1; i <= 16; i++)
+		count[i] = 0;
+	for (i = 0; (int)i < nchar; i++)
+		count[bitlen[i]]++;
+
+	start[1] = 0;
+	for (i = 1; i <= 16; i++)
+		start[i + 1] = start[i] + (count[i] << (16 - i));
+	if (start[17] != (uint16) (1 << 16))
+		error("ArjFile::make_table(): bad file data");
+
+	jutbits = 16 - tablebits;
+	for (i = 1; (int)i <= tablebits; i++) {
+		start[i] >>= jutbits;
+		weight[i] = 1 << (tablebits - i);
+	}
+	while (i <= 16) {
+		weight[i] = 1 << (16 - i);
+		i++;
+	}
+
+	i = start[tablebits + 1] >> jutbits;
+	if (i != (uint16) (1 << 16)) {
+		k = 1 << tablebits;
+		while (i != k)
+			table[i++] = 0;
+	}
+
+	avail = nchar;
+	mask = 1 << (15 - tablebits);
+	for (ch = 0; (int)ch < nchar; ch++) {
+		if ((len = bitlen[ch]) == 0)
+			continue;
+		k = start[len];
+		nextcode = k + weight[len];
+		if ((int)len <= tablebits) {
+			if (nextcode > (uint)tablesize)
+				error("ArjFile::make_table(): bad file data");
+			for (i = start[len]; i < nextcode; i++)
+				table[i] = ch;
+		} else {
+			p = &table[k >> jutbits];
+			i = len - tablebits;
+			while (i != 0) {
+				if (*p == 0) {
+					_right[avail] = _left[avail] = 0;
+					*p = avail++;
+				}
+				if (k & mask)
+					p = &_right[*p];
+				else
+					p = &_left[*p];
+				k <<= 1;
+				i--;
+			}
+			*p = ch;
+		}
+		start[len] = nextcode;
+	}
+}
+
+void ArjFile::read_pt_len(int nn, int nbit, int i_special) {
+	int i, n;
+	int16 c;
+	uint16 mask;
+
+	n = getbits(nbit);
+	if (n == 0) {
+		c = getbits(nbit);
+		for (i = 0; i < nn; i++)
+			_pt_len[i] = 0;
+		for (i = 0; i < 256; i++)
+			_pt_table[i] = c;
+	} else {
+		i = 0;
+		while (i < n) {
+			c = _bitbuf >> (13);
+			if (c == 7) {
+				mask = 1 << (12);
+				while (mask & _bitbuf) {
+					mask >>= 1;
+					c++;
+				}
+			}
+			fillbuf((c < 7) ? 3 : (int)(c - 3));
+			_pt_len[i++] = (byte)c;
+			if (i == i_special) {
+				c = getbits(2);
+				while (--c >= 0)
+					_pt_len[i++] = 0;
+			}
+		}
+		while (i < nn)
+			_pt_len[i++] = 0;
+		make_table(nn, _pt_len, 8, _pt_table, PTABLESIZE);  // replaced sizeof
+	}
+}
+
+void ArjFile::read_c_len() {
+	int16 i, c, n;
+	uint16 mask;
+
+	n = getbits(CBIT);
+	if (n == 0) {
+		c = getbits(CBIT);
+		for (i = 0; i < NC; i++)
+			_c_len[i] = 0;
+		for (i = 0; i < CTABLESIZE; i++)
+			_c_table[i] = c;
+	} else {
+		i = 0;
+		while (i < n) {
+			c = _pt_table[_bitbuf >> (8)];
+			if (c >= NT) {
+				mask = 1 << (7);
+				do {
+					if (_bitbuf & mask)
+						c = _right[c];
+					else
+						c = _left[c];
+					mask >>= 1;
+				} while (c >= NT);
+			}
+			fillbuf((int)(_pt_len[c]));
+			if (c <= 2) {
+				if (c == 0)
+					c = 1;
+				else if (c == 1)
+					c = getbits(4) + 3;
+				else
+					c = getbits(CBIT) + 20;
+				while (--c >= 0)
+					_c_len[i++] = 0;
+			}
+			else
+				_c_len[i++] = (byte)(c - 2);
+		}
+		while (i < NC)
+			_c_len[i++] = 0;
+		make_table(NC, _c_len, 12, _c_table, CTABLESIZE);  // replaced sizeof
+	}
+}
+
+uint16 ArjFile::decode_c() {
+	uint16 j, mask;
+
+	if (_blocksize == 0) {
+		_blocksize = getbits(16);
+		read_pt_len(NT, TBIT, 3);
+		read_c_len();
+		read_pt_len(NP, PBIT, -1);
+	}
+	_blocksize--;
+	j = _c_table[_bitbuf >> 4];
+	if (j >= NC) {
+		mask = 1 << (3);
+		do {
+			if (_bitbuf & mask)
+				j = _right[j];
+			else
+				j = _left[j];
+			mask >>= 1;
+		} while (j >= NC);
+	}
+	fillbuf((int)(_c_len[j]));
+	return j;
+}
+
+uint16 ArjFile::decode_p() {
+	uint16 j, mask;
+
+	j = _pt_table[_bitbuf >> (8)];
+	if (j >= NP) {
+		mask = 1 << (7);
+		do {
+			if (_bitbuf & mask)
+				j = _right[j];
+			else
+				j = _left[j];
+			mask >>= 1;
+		} while (j >= NP);
+	}
+	fillbuf((int)(_pt_len[j]));
+	if (j != 0) {
+		j--;
+		j = (1 << j) + getbits((int)j);
+	}
+	return j;
+}
+
+void ArjFile::decode_start() {
+	_blocksize = 0;
+	init_getbits();
+}
+
+void ArjFile::decode() {
+	int16 i;
+	int16 j;
+	int16 c;
+	int16 r;
+	int32 count;
+
+	decode_start();
+	count = 0;
+	r = 0;
+
+	while (count < _origsize) {
+		if ((c = decode_c()) <= UCHAR_MAX) {
+			_text[r] = (byte) c;
+			count++;
+			if (++r >= DDICSIZ) {
+				r = 0;
+				_outstream->write(_text, DDICSIZ);
+			}
+		} else {
+			j = c - (UCHAR_MAX + 1 - THRESHOLD);
+			count += j;
+			i = decode_p();
+			if ((i = r - i - 1) < 0)
+				i += DDICSIZ;
+			if (r > i && r < DDICSIZ - MAXMATCH - 1) {
+				while (--j >= 0)
+					_text[r++] = _text[i++];
+			} else {
+				while (--j >= 0) {
+					_text[r] = _text[i];
+					if (++r >= DDICSIZ) {
+						r = 0;
+						_outstream->write(_text, DDICSIZ);
+					}
+					if (++i >= DDICSIZ)
+						i = 0;
+				}
+			}
+		}
+	}
+	if (r != 0)
+		_outstream->write(_text, r);
+}
+
+/* Macros */
+
+#define BFIL {_getbuf|=_bitbuf>>_getlen;fillbuf(CODE_BIT-_getlen);_getlen=CODE_BIT;}
+#define GETBIT(c) {if(_getlen<=0)BFIL c=(_getbuf&0x8000)!=0;_getbuf<<=1;_getlen--;}
+#define BPUL(l) {_getbuf<<=l;_getlen-=l;}
+#define GETBITS(c,l) {if(_getlen<l)BFIL c=(uint16)_getbuf>>(CODE_BIT-l);BPUL(l)}
+
+int16 ArjFile::decode_ptr() {
+	int16 c;
+	int16 width;
+	int16 plus;
+	int16 pwr;
+
+	plus = 0;
+	pwr = 1 << (STRTP);
+	for (width = (STRTP); width < (STOPP); width++) {
+		GETBIT(c);
+		if (c == 0)
+			break;
+		plus += pwr;
+		pwr <<= 1;
+	}
+	if (width != 0)
+		GETBITS(c, width);
+	c += plus;
+	return c;
+}
+
+int16 ArjFile::decode_len() {
+	int16 c;
+	int16 width;
+	int16 plus;
+	int16 pwr;
+
+	plus = 0;
+	pwr = 1 << (STRTL);
+	for (width = (STRTL); width < (STOPL); width++) {
+		GETBIT(c);
+		if (c == 0)
+			break;
+		plus += pwr;
+		pwr <<= 1;
+	}
+	if (width != 0)
+		GETBITS(c, width);
+	c += plus;
+	return c;
+}
+
+void ArjFile::decode_f() {
+	int16 i;
+	int16 j;
+	int16 c;
+	int16 r;
+	int16 pos1;
+	int32 count;
+
+	init_getbits();
+	_getlen = _getbuf = 0;
+	count = 0;
+	r = 0;
+
+	while (count < _origsize) {
+		c = decode_len();
+		if (c == 0) {
+			GETBITS(c, CHAR_BIT);
+			_text[r] = (byte)c;
+			count++;
+			if (++r >= DDICSIZ) {
+				r = 0;
+				_outstream->write(_text, DDICSIZ);
+			}
+		} else {
+			j = c - 1 + THRESHOLD;
+			count += j;
+			pos1 = decode_ptr();
+			if ((i = r - pos1 - 1) < 0)
+				i += DDICSIZ;
+			while (j-- > 0) {
+				_text[r] = _text[i];
+				if (++r >= DDICSIZ) {
+					r = 0;
+					_outstream->write(_text, DDICSIZ);
+				}
+				if (++i >= DDICSIZ)
+					i = 0;
+			}
+		}
+	}
+	if (r != 0)
+		_outstream->write(_text, r);
+}
+
+
+} // End of namespace Common


Property changes on: scummvm/trunk/common/unarj.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/common/unarj.h
===================================================================
--- scummvm/trunk/common/unarj.h	                        (rev 0)
+++ scummvm/trunk/common/unarj.h	2008-06-01 11:43:20 UTC (rev 32460)
@@ -0,0 +1,179 @@
+/* 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$
+ *
+ */
+
+#ifndef COMMON_UNARJ_H
+#define COMMON_UNARJ_H
+
+#include "common/file.h"
+#include "common/hash-str.h"
+
+namespace Common {
+
+#define HEADER_ID     0xEA60
+#define HEADER_ID_HI    0xEA
+#define HEADER_ID_LO    0x60
+#define FIRST_HDR_SIZE    30
+#define FIRST_HDR_SIZE_V  34
+#define COMMENT_MAX     2048
+#define FNAME_MAX           512
+#define HEADERSIZE_MAX   (FIRST_HDR_SIZE + 10 + FNAME_MAX + COMMENT_MAX)
+#define CRC_MASK        0xFFFFFFFFL
+#define MAXSFX              25000L
+
+#define CODE_BIT    16
+#define CHAR_BIT  8
+#define UCHAR_MAX 255
+#define THRESHOLD	3
+#define DDICSIZ	  26624
+#define MAXDICBIT   16
+#define MATCHBIT	 8
+#define MAXMATCH   256
+#define NC		  (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
+#define NP		  (MAXDICBIT + 1)
+#define CBIT		 9
+#define NT		  (CODE_BIT + 3)
+#define PBIT		 5
+#define TBIT		 5
+
+#if NT > NP
+#define NPT NT
+#else
+#define NPT NP
+#endif
+
+#define CTABLESIZE  4096
+#define PTABLESIZE   256
+
+#define STRTP		  9
+#define STOPP		 13
+
+#define STRTL		  0
+#define STOPL		  7
+
+struct ArjHeader {
+	int32 pos;
+	uint16 id;
+	uint16 headerSize;
+	//
+	byte firstHdrSize;
+	byte nbr;
+	byte xNbr;
+	byte hostOs;
+	byte flags;
+	byte method;
+	byte fileType;
+	byte pad;
+	uint32 timeStamp;
+	int32 compSize;
+	int32 origSize;
+	uint32 fileCRC;
+	uint16 entryPos;
+	uint16 fileMode;
+	uint16 hostData;
+	char   filename[FNAME_MAX];
+	char   comment[COMMENT_MAX];
+	uint16 extHeaderSize;
+
+	uint32 headerCrc;
+};
+
+typedef HashMap<String, int, IgnoreCase_Hash, IgnoreCase_EqualTo> ArjFilesMap;
+
+class ArjFile : public File {
+public:
+	ArjFile();
+	~ArjFile();
+
+	void registerArchive(const String &filename);
+
+	bool open(const Common::String &filename, AccessMode mode = kFileReadMode);
+	void close();
+
+	uint32 read(void *dataPtr, uint32 dataSize);
+	bool eos();
+	uint32 pos();
+	uint32 size();
+	void seek(int32 offset, int whence = SEEK_SET);
+	bool isOpen() { return _isOpen; }
+
+private:
+	File _currArchive;
+	Array<ArjHeader *> _headers;
+	ArjFilesMap _fileMap;
+	StringMap _archMap;
+	ReadStream *_stream;
+	byte *_uncompressedData;
+	MemoryWriteStream *_outstream;
+	MemoryReadStream *_uncompressed;
+
+	bool _isOpen;
+
+	int32 findHeader(void);
+	ArjHeader *readHeader();
+
+	void decode();
+	void decode_f();
+
+	uint16 _bitbuf;
+	int32 _compsize;
+	int32 _origsize;
+	byte _subbitbuf;
+	int _bitcount;
+
+	void init_getbits();
+	void fillbuf(int n);
+	uint16 getbits(int n);
+	
+
+	void make_table(int nchar, byte *bitlen, int tablebits, uint16 *table, int tablesize);
+	void read_pt_len(int nn, int nbit, int i_special);
+	void read_c_len(void);
+	uint16 decode_c(void);
+	uint16 decode_p(void);
+	void decode_start(void);
+	int16 decode_ptr(void);
+	int16 decode_len(void);
+
+private:
+	byte  _text[DDICSIZ];
+
+	int16  _getlen;
+	int16  _getbuf;
+
+	uint16 _left[2 * NC - 1];
+	uint16 _right[2 * NC - 1];
+	byte  _c_len[NC];
+	byte  _pt_len[NPT];
+
+	uint16 _c_table[CTABLESIZE];
+	uint16 _pt_table[PTABLESIZE];
+	uint16 _blocksize;
+
+
+};
+
+} // End of namespace Common
+
+#endif


Property changes on: scummvm/trunk/common/unarj.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list