blob: b8f9d93a71487ce26b3dfb51f77d12ab3a29fe50 [file] [log] [blame]
Luc Verhaegena2980652009-06-17 14:45:24 +02001/*
2 * Copyright 2009 Luc Verhaegen <libv@skynet.be>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <stdio.h>
20#include <unistd.h>
21#include <fcntl.h>
22#include <errno.h>
23#include <string.h>
24
25#include "lzss_extract.h"
26
27static inline int
28LZSSBufferWrite(int fd, unsigned char *Buffer, int *BufferCount, unsigned char value)
29{
30 Buffer[*BufferCount] = value;
31 *BufferCount += 1;
32
33 if (*BufferCount == 0x1000) {
34 if (write(fd, Buffer, 0x1000) != 0x1000) {
35 fprintf(stderr, "Error writing to output file: %s",
36 strerror(errno));
37 return 1;
38 }
39 *BufferCount = 0;
40 }
41
42 return 0;
43}
44
45int
46LZSSExtract(unsigned char *Input, int InputSize, int fd)
47{
48 unsigned char Buffer[0x1000];
49 unsigned short BitBuffer = 0;
50 int i = 0, k, BitCount = 8, BufferCount = 0;
51
52 while (i < InputSize) {
53
54 if (BitCount == 8) {
55 BitBuffer = Input[i];
56 BitCount = -1;
57 } else if ((BitBuffer >> BitCount) & 0x01) {
58 if (LZSSBufferWrite(fd, Buffer, &BufferCount, Input[i]))
59 return 1;
60 } else if ((i + 1) < InputSize) {
61 int offset = ((Input[i] | ((Input[i + 1] & 0xF0) << 4)) - 0xFEE) & 0xFFF;
62 int length = (Input[i + 1] & 0x0F) + 3;
63
64 for (k = 0; k < length; k++) {
65 if (LZSSBufferWrite(fd, Buffer, &BufferCount, Buffer[(offset + k) & 0xFFF]))
66 return 1;
67 }
68 i++;
69 } else {
70 fprintf(stderr, "Error: requesting data beyond end of input file.\n");
71 return 1;
72 }
73
74 i++;
75 BitCount++;
76 }
77
78 if (BufferCount) {
79 if (write(fd, Buffer, BufferCount) != BufferCount) {
80 fprintf(stderr, "Error writing to output file: %s",
81 strerror(errno));
82 return 1;
83 }
84 }
85
86 return 0;
87}