summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSteven Fuller <relnev@icculus.org>2001-07-30 05:22:12 +0000
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-20 02:22:36 +0200
commiteb5c2cc01dbd5756790860ad5eb2302f911d9dc7 (patch)
tree2928560dd46bce280d95e549069a7130dcccd1c1 /src
parentf097dd925866f7a25c9fa58dcf46b4fc59302cb6 (diff)
Tools for testing.
Diffstat (limited to 'src')
-rw-r--r--src/tools/data.c440
-rw-r--r--src/tools/data.h61
-rw-r--r--src/tools/dehuff.c67
-rw-r--r--src/tools/ffread.c94
-rw-r--r--src/tools/ilbmread.c258
-rw-r--r--src/tools/util.c90
-rw-r--r--src/tools/util.h21
-rw-r--r--src/win95/huffman.hpp2
8 files changed, 1032 insertions, 1 deletions
diff --git a/src/tools/data.c b/src/tools/data.c
new file mode 100644
index 0000000..1da39b7
--- /dev/null
+++ b/src/tools/data.c
@@ -0,0 +1,440 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "data.h"
+
+unsigned char *Pal_3_4(unsigned char *dat)
+{
+ unsigned char *buf;
+ int i;
+
+ buf = (unsigned char *)malloc(256 * 4);
+
+ for (i = 0; i < 256; i++) {
+ buf[i*4+0] = dat[i*3+0];
+ buf[i*4+1] = dat[i*3+1];
+ buf[i*4+2] = dat[i*3+2];
+ buf[i*4+3] = 0xFF;
+ }
+ buf[3] = 0;
+
+ free(dat);
+
+ return buf;
+}
+
+unsigned char *Pixel_BGR_RGB(unsigned char *data, int length)
+{
+ int x;
+ unsigned char *ptr;
+ unsigned char tmp;
+
+ if (length % 3)
+ return data;
+
+ length /= 3;
+
+ ptr = data;
+ for (x = 0; x < length; x++) {
+ tmp = *ptr;
+ *ptr = *(ptr + 2);
+ *(ptr + 2) = tmp;
+ ptr += 3;
+ }
+
+ return data;
+}
+
+unsigned char *Pixel_BGRA_RGBA(unsigned char *data, int length)
+{
+ int x;
+ unsigned char *ptr;
+ unsigned char tmp;
+
+ if (length & 3)
+ return data;
+
+ length /= 4;
+
+ ptr = data;
+ for (x = 0; x < length; x++) {
+ tmp = *ptr;
+ *ptr = *(ptr + 2);
+ *(ptr + 2) = tmp;
+ ptr += 4;
+ }
+
+ return data;
+}
+
+unsigned char *Pixel_256_RGB(unsigned char *data, unsigned char *pal, int length)
+{
+ unsigned char *buf;
+ int x;
+
+ buf = (unsigned char *)malloc(length * 3);
+
+ for (x = 0; x < length; x++) {
+ buf[x*3+0] = pal[data[x]*3+0];
+ buf[x*3+1] = pal[data[x]*3+1];
+ buf[x*3+2] = pal[data[x]*3+2];
+ }
+
+ return buf;
+}
+
+unsigned char *Pixel_256_RGBA(unsigned char *data, unsigned char *pal, int length, int trans)
+{
+ unsigned char *buf;
+ int x;
+
+ buf = (unsigned char *)malloc(length * 4);
+
+ for (x = 0; x < length; x++) {
+ buf[x*4+0] = pal[data[x]*3+0];
+ buf[x*4+1] = pal[data[x]*3+1];
+ buf[x*4+2] = pal[data[x]*3+2];
+ if (data[x] == trans)
+ buf[x*4+3] = 0;
+ else
+ buf[x*4+3] = 0xFF;
+ }
+
+ return buf;
+}
+
+unsigned char *LoadTGA(char *filename, int *width, int *height)
+{
+ FILE *fp;
+ unsigned char *buf;
+ int len;
+ int x, y, w, h;
+
+ fp = fopen(filename, "rb");
+ if (fp == NULL)
+ return NULL;
+
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ rewind(fp);
+
+ buf = (unsigned char *)malloc(len);
+ fread(buf, len, 1, fp);
+ fclose(fp);
+
+ len = buf[0];
+
+ printf("one");
+
+ if (buf[1] != 0)
+ return NULL;
+
+ printf("one");
+
+ if (buf[2] != 2)
+ return NULL;
+
+ printf("one");
+
+ x = buf[8] | (buf[9] << 8);
+ y = buf[10] | (buf[11] << 8);
+ w = buf[12] | (buf[13] << 8);
+ h = buf[14] | (buf[15] << 8);
+
+ if (buf[16] != 24)
+ return NULL;
+
+ printf("one");
+
+ printf("buf 17 = %d\n", buf[17]);
+
+ if (buf[17] != 32)
+ return NULL;
+
+ printf("one");
+
+ *width = (w - x);
+ *height = (h - y);
+
+ return Pixel_BGR_RGB(&buf[18 + len], *width * *height * 3);
+}
+
+void SaveTGA()
+{
+}
+
+unsigned char *LoadPCX(char *filename, unsigned char **pal, int *width, int *height)
+{
+ pcx_header pcx;
+ FILE *fp;
+ unsigned char *buf, *ptr;
+ int i, j, n, x, y, ch;
+
+ fp = fopen(filename, "rb");
+ if (fp == NULL)
+ return NULL;
+
+ fread(&pcx, sizeof(pcx), 1, fp);
+
+ if (pcx.manufacturer != 10)
+ return NULL;
+
+ if (pcx.version != 5)
+ return NULL;
+
+ if (pcx.encoding != 1)
+ return NULL;
+
+ if (pcx.bits_per_pixel != 8)
+ return NULL;
+
+ if (pcx.num_color_planes != 1)
+ return NULL;
+
+ if (pcx.palette_type != 1)
+ return NULL;
+
+ x = pcx.width - pcx.x + 1;
+ y = pcx.height - pcx.y + 1;
+
+ buf = (unsigned char *)malloc(x * y);
+
+ ptr = buf;
+ for (i = 0; i < (x * y); i++) {
+ ch = fgetc(fp);
+ if (ch == -1)
+ return NULL;
+ if (ch > 0xC0) {
+ n = ch - 0xC1; /* 0xC0 */
+ ch = fgetc(fp);
+ for (j = 0; j < n; j++) {
+ *ptr = (unsigned char)ch;
+ ptr++;
+ i++;
+ }
+ }
+ *ptr = (unsigned char)ch;
+ ptr++;
+ }
+
+ fgetc(fp);
+
+ ptr = (unsigned char *)malloc(768);
+ for (i = 0; i < 768; i++) {
+ ptr[i] = (unsigned char)fgetc(fp);
+ }
+
+ fclose(fp);
+
+ *pal = ptr;
+ *width = x;
+ *height = y;
+
+ return buf;
+}
+
+unsigned char *LoadPCX_RGB(char *filename, int *width, int *height)
+{
+ unsigned char *pal;
+ unsigned char *dat, *dat2;
+
+ dat = LoadPCX(filename, &pal, width, height);
+
+ if (dat == NULL)
+ return NULL;
+
+ dat2 = Pixel_256_RGB(dat, pal, *width * *height);
+ free(dat);
+ free(pal);
+
+ return dat2;
+}
+
+unsigned char *LoadPCX_RGBA(char *filename, int *width, int *height)
+{
+ unsigned char *pal;
+ unsigned char *dat, *dat2;
+
+ dat = LoadPCX(filename, &pal, width, height);
+
+ if (dat == NULL)
+ return NULL;
+
+ dat2 = Pixel_256_RGBA(dat, pal, *width * *height, 0);
+ free(dat);
+ free(pal);
+
+ return dat2;
+}
+
+void SavePCX(unsigned char *buf, int width, int height, unsigned char *pal, char *name)
+{
+ FILE *fp;
+ pcx_header ph;
+ unsigned char *dat, *ptr, *ptrd, ch;
+ int x, y, z;
+
+ ph.manufacturer = 10;
+ ph.version = 5;
+ ph.encoding = 1;
+ ph.bits_per_pixel = 8;
+ ph.x = ph.y = 0;
+ ph.width = width - 1;
+ ph.height = height - 1;
+ ph.horz_res = ph.virt_res = 0; /* ? */
+ for (x = 0; x < sizeof(ph.ega_palette); x++)
+ ph.ega_palette[x] = 0;
+ ph.reserved = 0;
+ ph.num_color_planes = 1;
+ ph.byte_per_line = width;
+ ph.palette_type = 1;
+ ph.hscreen_size = width;
+ ph.vscreen_size = height;
+ for (x = 0; x < sizeof(ph.padding); x++)
+ ph.padding[x] = 0;
+
+#if 0
+ dat = malloc(width * height * 2);
+ for (x = 0; x < width * height; x++) {
+ *(dat + x*2) = 0xC1;
+ *(dat + x*2+1) = *(buf + x);
+ }
+#endif
+
+ dat = malloc(width * height * 2);
+ ptr = buf; ptrd = dat;
+ x = 0; z = 0;
+ while (x < width * height) {
+ ch = *ptr;
+ ptr++;
+ x++;
+ y = 0xC1;
+ while((x < width * height) && (*ptr == ch) && (y < 0xFF)) {
+ x++; y++; ptr++;
+ }
+ *ptrd = y;
+ ptrd++;
+ *ptrd = ch;
+ ptrd++;
+ z += 2;
+ }
+ dat = realloc(dat, z);
+
+ fp = fopen(name, "w");
+ fwrite(&ph, sizeof(ph), 1, fp);
+ fwrite(dat, 1, z, fp);
+ fputc(12, fp);
+ fwrite(pal, 1, 768, fp);
+ fclose(fp);
+
+ free(dat);
+
+ return;
+}
+
+void SavePCX256ToFile(unsigned char *buf, int width, int height, unsigned char *pal, char *name)
+{
+ FILE *fp;
+ pcx_header ph;
+ unsigned char *dat, *ptr, *ptrd, ch;
+ int x, y, z;
+
+ memset(&ph, 0, sizeof(ph));
+
+ ph.manufacturer = 10;
+ ph.version = 5;
+ ph.encoding = 1;
+ ph.bits_per_pixel = 8;
+ ph.x = ph.y = 0;
+ ph.width = width - 1;
+ ph.height = height - 1;
+ ph.horz_res = ph.virt_res = 0;
+ ph.reserved = 0;
+ ph.num_color_planes = 1;
+ ph.byte_per_line = width;
+ ph.palette_type = 1;
+ ph.hscreen_size = width;
+ ph.vscreen_size = height;
+
+ dat = (unsigned char *)malloc(width * height * 2);
+
+ ptr = buf; ptrd = dat;
+ x = 0; z = 0;
+ while (x < (width * height)) {
+ ch = *ptr;
+ ptr++;
+ x++;
+ y = 0xC1;
+ while((x < (width * height)) && (*ptr == ch) && (y < 0xFF)) {
+ x++; y++; ptr++;
+ }
+ if ((y == 0xC1) && (ch < 0xC0)) {
+ *ptrd = ch;
+ ptrd++;
+ z++;
+ } else {
+ *ptrd = y;
+ ptrd++;
+ *ptrd = ch;
+ ptrd++;
+ z += 2;
+ }
+ }
+
+ fp = fopen(name, "wb");
+ fwrite(&ph, sizeof(ph), 1, fp);
+ fwrite(dat, 1, z, fp);
+ fputc(12, fp);
+ fwrite(pal, 1, 768, fp);
+ fclose(fp);
+
+ free(dat);
+}
+
+/* TODO: make sure RGB version works */
+void SavePCXRGBToFile(unsigned char *buf, int width, int height, char *name)
+{
+ FILE *fp;
+ pcx_header ph;
+ unsigned char *dat;
+ int x, y, s;
+
+ memset(&ph, 0, sizeof(ph));
+
+ ph.manufacturer = 10;
+ ph.version = 5;
+ ph.encoding = 1;
+ ph.bits_per_pixel = 8;
+ ph.x = ph.y = 0;
+ ph.width = width - 1;
+ ph.height = height - 1;
+ ph.horz_res = ph.virt_res = 0;
+ ph.num_color_planes = 3;
+ ph.byte_per_line = width;
+ ph.palette_type = 1;
+ ph.hscreen_size = width;
+ ph.vscreen_size = height;
+
+ dat = malloc(width * height * 2 * 3);
+ for (y = 0; y < height; y++) {
+ for (s = 0; s < 3; s++) {
+ for (x = 0; x < width; x++) {
+ *(dat + (y*(width*3) + (width*s) + x)*2) = 0xC1;
+ *(dat + (y*(width*3) + (width*s) + x)*2+1) = *(buf + y*(width*3) + x*3 + s);
+ }
+ }
+ }
+
+ fp = fopen(name, "wb");
+ fwrite(&ph, sizeof(ph), 1, fp);
+ fwrite(dat, 1, width * height * 2 * 3, fp);
+ fclose(fp);
+
+ free(dat);
+}
+
+void LoadILBM()
+{
+}
diff --git a/src/tools/data.h b/src/tools/data.h
new file mode 100644
index 0000000..b1b9717
--- /dev/null
+++ b/src/tools/data.h
@@ -0,0 +1,61 @@
+#ifndef __DATA_H__
+#define __DATA_H__
+
+#define PACKED __attribute__((packed))
+
+typedef struct pcx_header_type
+{
+ char manufacturer;
+ char version;
+ char encoding;
+ char bits_per_pixel;
+ short int x, y;
+ short int width, height;
+ short int horz_res;
+ short int virt_res;
+ char ega_palette[48];
+ char reserved;
+ char num_color_planes;
+ short int byte_per_line;
+ short int palette_type;
+ short int hscreen_size;
+ short int vscreen_size;
+ char padding[54];
+} PACKED pcx_header, *pcx_header_ptr;
+
+unsigned char *Pal_3_4(unsigned char *dat);
+
+unsigned char *Pixel_BGR_RGB(unsigned char *data, int length);
+unsigned char *Pixel_BGRA_RGBA(unsigned char *data, int length);
+unsigned char *Pixel_256_RGB(unsigned char *data, unsigned char *pal, int length);
+unsigned char *Pixel_256_RGBA(unsigned char *data, unsigned char *pal, int length, int trans);
+
+unsigned char *LoadTGA(char *filename, int *width, int *height);
+
+unsigned char *LoadPCX(char *filename, unsigned char **pal, int *width, int *height);
+unsigned char *LoadPCX_RGB(char *filename, int *width, int *height);
+unsigned char *LoadPCX_RGBA(char *filename, int *width, int *height);
+void SavePCX(unsigned char *buf, int width, int height, unsigned char *pal, char *name);
+
+void SavePCX256ToFile(unsigned char *buf, int width, int height, unsigned char *pal, char *name);
+void SavePCXRGBToFile(unsigned char *buf, int width, int height, char *name);
+/*
+
+todo: sgi graphic format, microsoft bmp format, rest of tga/pcx, ilbm
+gif?
+jpg?
+png?
+
+function call asks for certain graphic format and data is converted if needed
+
+of course asking for an indexed type from a truecolor type will generate an
+error
+
+EnumerateLoadImageTypes
+EnumerateSaveImageTypes
+EnumerateLoadImageTypeCaps
+EnumerateSaveImageTypeCaps
+DetermineImageType
+*/
+
+#endif
diff --git a/src/tools/dehuff.c b/src/tools/dehuff.c
new file mode 100644
index 0000000..d5805b8
--- /dev/null
+++ b/src/tools/dehuff.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "huffman.hpp"
+
+#include "util.h"
+
+int main(int argc, char *argv[])
+{
+ FILE *fp;
+ char str[8];
+ unsigned char *buf, *dbuf;
+ int len;
+
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s <compressed.rif> <outfile>\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ fp = fopen(argv[1], "rb");
+ if (fp == NULL) {
+ perror("fopen");
+ exit(EXIT_FAILURE);
+ }
+
+ fread(str, 1, 8, fp);
+ if (strncmp(str, COMPRESSED_RIF_IDENTIFIER, 8) != 0) {
+ fprintf(stderr, "%s: invalid compressed rif file\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ len = fsize(argv[1]);
+ buf = (unsigned char *)malloc(len);
+ if (buf == NULL) {
+ fprintf(stderr, "could not allocate %d bytes to load %s\n", len, argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ fseek(fp, 0, SEEK_SET);
+
+ fread(buf, 1, len, fp);
+ fclose(fp);
+
+ len = ((HuffmanPackage *)buf)->UncompressedDataSize;
+
+ dbuf = (unsigned char *)HuffmanDecompress((HuffmanPackage *)buf);
+ if (dbuf == NULL) {
+ fprintf(stderr, "Something went wrong with HuffmanDecompress\n");
+ exit(EXIT_FAILURE);
+ }
+
+ free(buf);
+
+ fp = fopen(argv[2], "wb");
+ if (fp == NULL) {
+ perror("fopen");
+ exit(EXIT_FAILURE);
+ }
+
+ fwrite(dbuf, 1, len, fp);
+ fclose(fp);
+
+ free(dbuf);
+
+ return 0;
+}
diff --git a/src/tools/ffread.c b/src/tools/ffread.c
new file mode 100644
index 0000000..0206229
--- /dev/null
+++ b/src/tools/ffread.c
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "util.h"
+
+int main(int argc, char *argv[])
+{
+ FILE *fp;
+ unsigned char id[4];
+ char cdir[560];
+ int nfiles;
+ int off;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <file.ffl>\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ fp = fopen(argv[1], "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "unable to open %s\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ fread(id, 1, 4, fp);
+ if ((id[0] != 'R') || (id[1] != 'F') | (id[2] != 'F') | (id[3] != 'L')) {
+ fprintf(stderr, "%s is not a valid RFFL file\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (ReadInt32L(fp) != 0x0000) {
+ fprintf(stderr, "%s is not a version 0000 RFFL file\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ nfiles = ReadInt32L(fp);
+
+ off = ReadInt32L(fp) + 20;
+ ReadInt32L(fp);
+
+ //if (getcwd(cdir, sizeof(cdir)) == NULL) {
+ // fprintf(stderr, "your cwd is too long...\n");
+ // exit(EXIT_FAILURE);
+ //}
+
+ while (nfiles--) {
+ FILE *ofp;
+ char name[512], *nptr;
+ int i, j;
+ int c;
+
+ int offset = ReadInt32L(fp);
+ int length = ReadInt32L(fp);
+ int pffset;
+
+ j = 0;
+ do {
+ for (i = 0; i < 4; i++, j++) {
+ c = fgetc(fp);
+ name[j] = c;
+
+ if (c == 0) break;
+ }
+
+ } while (c != 0);
+ for (; i < 3; i++) fgetc(fp);
+
+ printf("Filename: %s (%d, %d)\n", name, offset, length);
+
+ pffset = ftell(fp);
+
+ for (j = 0, nptr = &name[0]; name[j]; j++)
+ if (name[j] == '\\')
+ nptr = &name[j+1];
+
+ fseek(fp, off+offset, SEEK_SET);
+
+ ofp = fopen(nptr, "wb");
+
+ for (i = 0; i < length; i++)
+ fputc(fgetc(fp), ofp);
+
+ fclose(ofp);
+
+ fseek(fp, pffset, SEEK_SET);
+
+ }
+
+ fclose(fp);
+
+ return 0;
+}
diff --git a/src/tools/ilbmread.c b/src/tools/ilbmread.c
new file mode 100644
index 0000000..b0e64ec
--- /dev/null
+++ b/src/tools/ilbmread.c
@@ -0,0 +1,258 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "data.h"
+
+int8_t ReadInt8(FILE *fp)
+{
+ unsigned char d[1];
+
+ fread(d, 1, 1, fp);
+
+ return d[0];
+}
+
+int16_t ReadInt16M(FILE *fp)
+{
+ unsigned char d[2];
+
+ fread(d, 1, 2, fp);
+
+ return d[1] | (d[0] << 8);
+}
+
+int32_t ReadInt32M(FILE *fp)
+{
+ unsigned char d[4];
+
+ fread(d, 1, 4, fp);
+
+ return d[3] | (d[2] << 8) | (d[1] << 16) | (d[0] << 24);
+}
+
+#define IFF_UNKNOWN -1
+#define IFF_LIST 0
+#define IFF_FORM 1
+#define IFF_TYPE_ILBM 2
+#define IFF_PROP 3
+#define IFF_TRAN 4
+#define IFF_BMHD 6
+#define IFF_CMAP 7
+#define IFF_BODY 8
+#define IFF_TYPE_MIPM 9
+#define IFF_CONT 10
+#define IFF_TYPE_PBM 11
+#define IFF_DPPS 12
+#define IFF_CRNG 13
+#define IFF_TINY 14
+
+int main(int argc, char *argv[])
+{
+ FILE *fp;
+ char tag[4];
+ int c;
+ unsigned char *cmap;
+ int w, h;
+ int x, y;
+ int planes;
+ int masking;
+ int compression;
+ int tcolor;
+ int xa, ya;
+ int pw, ph;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <file.lbm>\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ fp = fopen(argv[1], "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "unable to open %s for reading\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Filename: %s\n", argv[1]);
+
+ /* printf("This program is lame. You have been warned.\n"); */
+
+ fseek(fp, 48, SEEK_SET);
+
+ fread(tag, 1, 4, fp);
+ if (tag[0] != 'I' || tag[1] != 'L' || tag[2] != 'B' || tag[3] != 'M') {
+ fprintf(stderr, "This program is lame! Give me a file in the right format please!\n");
+ exit(EXIT_FAILURE);
+ }
+ fread(tag, 1, 4, fp);
+ if (tag[0] != 'B' || tag[1] != 'M' || tag[2] != 'H' || tag[3] != 'D') {
+ fprintf(stderr, "This program is lame! Give me a file in the right format please!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (ReadInt32M(fp) != 0x14) {
+ fprintf(stderr, "This program is lame! Give me a file in the right format please!\n");
+ exit(EXIT_FAILURE);
+ }
+{
+ /* 'BMHD' */
+
+
+ w = ReadInt16M(fp);
+ h = ReadInt16M(fp);
+ x = ReadInt16M(fp);
+ y = ReadInt16M(fp);
+
+ planes = ReadInt8(fp);
+ masking = ReadInt8(fp);
+ compression = ReadInt8(fp);
+
+ ReadInt8(fp); /* padding */
+
+ tcolor = ReadInt16M(fp);
+ xa = ReadInt8(fp);
+ ya = ReadInt8(fp);
+ pw = ReadInt16M(fp);
+ ph = ReadInt16M(fp);
+
+ printf("Info: w:%d h:%d x:%d y:%d p:%d m:%02X c:%d tc:%d xa:%d ya:%d pw:%d ph:%d\n", w, h, x, y, planes, masking, compression, tcolor, xa, ya, pw, ph);
+
+}
+ fread(tag, 1, 4, fp);
+ if (tag[0] != 'C' || tag[1] != 'M' || tag[2] != 'A' || tag[3] != 'P') {
+ fprintf(stderr, "How could you betray me, this is crap!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ c = ReadInt32M(fp);
+
+ printf("Colors present = %d (%d)\n", c / 3, c);
+ if (c % 3) {
+ fprintf(stderr, "Gee, your colormap is messed up!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Offset = %d\n", ftell(fp));
+
+ cmap = (unsigned char *)malloc(c);
+ fread(cmap, 1, c, fp);
+
+ if (c & 1)
+ fgetc(fp); /* throwaway extra byte (even padding) */
+
+ printf("Offset = %d\n", ftell(fp));
+ fread(tag, 1, 4, fp);
+ printf("Offset = %d\n", ftell(fp));
+ if (tag[0] != 'B' || tag[1] != 'O' || tag[2] != 'D' || tag[3] != 'Y') {
+ printf("Where's the body tag!?\n");
+ exit(EXIT_FAILURE);
+ }
+
+{
+ unsigned char *compbuf;
+ unsigned char *grphbuf;
+ int len, len2;
+ int rw;
+ int i, j, p, pixel;
+
+ len2 = ReadInt32M(fp);
+
+ printf("Pos 1: pos:%d len:%d\n", ftell(fp), len2);
+
+ rw = ((w + 7) / 8) * 8; /* round up to multiple of 8 */
+ len = rw * h * planes / 8;
+ grphbuf = (unsigned char *)malloc(w * h * 3);
+ compbuf = (unsigned char *)malloc(len);
+
+ if (compression == 1) {
+ j = 0;
+
+ while (len2 > 0) {
+ signed char s = fgetc(fp);
+ len2--;
+
+ if (s >= 0) {
+ i = s + 1;
+
+ fread(&compbuf[j], 1, i, fp);
+ j += i;
+ len2 -= i;
+ } else {
+ if (s == -128) printf("Nop?\n");
+
+ i = -s+1;
+
+ p = fgetc(fp);
+ len2--;
+
+ while (i--) {
+ compbuf[j] = p;
+ j++;
+ }
+ }
+ }
+ if (len2 < 0) printf("somebody set up us the messed up decompression: %d\n", len2);
+
+ } else if (compression == 0) {
+ fread(compbuf, 1, len, fp);
+
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ for (pixel = 0, p = 0; p < planes; p++) {
+ if (compbuf[(rw/8)*p+(rw*planes/8)*j+i/8] & (1 << (7 - (i & 7))))
+ pixel |= (1 << p);
+ }
+ grphbuf[(w*j+i)*3+0] = cmap[3*pixel+0];
+ grphbuf[(w*j+i)*3+1] = cmap[3*pixel+1];
+ grphbuf[(w*j+i)*3+2] = cmap[3*pixel+2];
+ }
+ }
+
+ } else {
+ fprintf(stderr, "What kinda compression is this?!\n");
+ exit(EXIT_FAILURE);
+ }
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ for (pixel = 0, p = 0; p < planes; p++) {
+ if (compbuf[(rw/8)*p+(rw*planes/8)*j+i/8] & (1 << (7 - (i & 7))))
+ pixel |= (1 << p);
+ }
+ grphbuf[(w*j+i)*3+0] = cmap[3*pixel+0];
+ grphbuf[(w*j+i)*3+1] = cmap[3*pixel+1];
+ grphbuf[(w*j+i)*3+2] = cmap[3*pixel+2];
+ }
+ }
+
+ if (ftell(fp) & 1) fgetc(fp);
+
+ printf("Pos 2: pos:%d\n", ftell(fp));
+ {
+ char *fn;
+
+ fn = (char *)malloc(strlen(argv[1])+6);
+ strcpy(fn, argv[1]);
+ strcat(fn, ".pcx");
+ SavePCXRGBToFile(grphbuf, w, h, fn);
+ free(fn);
+ }
+
+ p = fgetc(fp);
+ if (p != -1) {
+ printf("%c", p);
+ printf("%c", fgetc(fp));
+ printf("%c", fgetc(fp));
+ printf("%c", fgetc(fp));
+ printf("\n");
+ }
+
+ free(compbuf);
+ free(grphbuf);
+}
+
+ free(cmap);
+ fclose(fp);
+
+ return 0;
+}
diff --git a/src/tools/util.c b/src/tools/util.c
new file mode 100644
index 0000000..3c1f5aa
--- /dev/null
+++ b/src/tools/util.c
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "util.h"
+
+int32_t ReadInt32M(FILE *fp)
+{
+ unsigned char d[4];
+
+ fread(d, 1, 4, fp);
+
+ return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | (d[3] << 0);
+}
+
+int32_t ReadInt24M(FILE *fp)
+{
+ unsigned char d[3];
+
+ fread(d, 1, 3, fp);
+
+ return (d[0] << 16) | (d[1] << 8) | (d[2] << 0);
+}
+
+int16_t ReadInt16M(FILE *fp)
+{
+ unsigned char d[2];
+
+ fread(d, 1, 2, fp);
+
+ return (d[0] << 8) | (d[1] << 0);
+}
+
+int32_t ReadInt32L(FILE *fp)
+{
+ unsigned char d[4];
+
+ fread(d, 1, 4, fp);
+
+ return (d[3] << 24) | (d[2] << 16) | (d[1] << 8) | (d[0] << 0);
+}
+
+int32_t ReadInt24L(FILE *fp)
+{
+ unsigned char d[3];
+
+ fread(d, 1, 3, fp);
+
+ return (d[2] << 16) | (d[1] << 8) | (d[0] << 0);
+}
+
+int16_t ReadInt16L(FILE *fp)
+{
+ unsigned char d[2];
+
+ fread(d, 1, 2, fp);
+
+ return (d[1] << 8) | (d[0] << 0);
+}
+
+int8_t ReadInt8(FILE *fp)
+{
+ unsigned char d[1];
+
+ fread(d, 1, 1, fp);
+
+ return d[0];
+}
+
+int filelength(int filedes)
+{
+ struct stat buf;
+
+ if (fstat(filedes, &buf) == -1)
+ return -1;
+
+ return buf.st_size;
+}
+
+int fsize(char *file_name)
+{
+ struct stat buf;
+
+ if (stat(file_name, &buf) == -1)
+ return -1;
+
+ return buf.st_size;
+}
diff --git a/src/tools/util.h b/src/tools/util.h
new file mode 100644
index 0000000..d11a43f
--- /dev/null
+++ b/src/tools/util.h
@@ -0,0 +1,21 @@
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include <stdint.h>
+
+/* TODO: need unsigned version, way to signify success/EOF */
+/* ReadBytes */
+
+int32_t ReadInt32M(FILE *fp);
+int32_t ReadInt24M(FILE *fp);
+int16_t ReadInt16M(FILE *fp);
+int32_t ReadInt32L(FILE *fp);
+int32_t ReadInt24L(FILE *fp);
+int16_t ReadInt16L(FILE *fp);
+
+int8_t ReadInt8(FILE *fp);
+
+int filelength(int filedes);
+int fsize(char *file_name);
+
+#endif
diff --git a/src/win95/huffman.hpp b/src/win95/huffman.hpp
index 58faf2a..607ff8b 100644
--- a/src/win95/huffman.hpp
+++ b/src/win95/huffman.hpp
@@ -28,4 +28,4 @@ extern char *HuffmanDecompress(HuffmanPackage *inpackage);
};
#endif
-#endif \ No newline at end of file
+#endif