extractor-gtk-cvslog Mailing List for Obscure-Extractor-GTK (Page 2)
Extract files from unusual archive formats
Brought to you by:
someone-guy
You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(8) |
Sep
(19) |
Oct
(1) |
Nov
|
Dec
|
2008 |
Jan
|
Feb
(19) |
Mar
(6) |
Apr
(6) |
May
(2) |
Jun
|
Jul
|
Aug
(31) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <som...@us...> - 2008-08-22 16:09:28
|
Revision: 99 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=99&view=rev Author: someone-guy Date: 2008-08-22 16:09:24 +0000 (Fri, 22 Aug 2008) Log Message: ----------- re-add incorrectly removed rewind() Modified Paths: -------------- trunk/extractor/generic.c Modified: trunk/extractor/generic.c =================================================================== --- trunk/extractor/generic.c 2008-08-22 16:09:05 UTC (rev 98) +++ trunk/extractor/generic.c 2008-08-22 16:09:24 UTC (rev 99) @@ -67,6 +67,7 @@ int pngidx = -1; int cnt = 0; file_t *list = calloc(1, sizeof(file_t)); + rewind(in); while (cnt < MAX_FILES) { uint8_t *p; int i; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:09:08
|
Revision: 98 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=98&view=rev Author: someone-guy Date: 2008-08-22 16:09:05 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Cleanup compiler flags handling in Makefile Modified Paths: -------------- trunk/extractor/Makefile Modified: trunk/extractor/Makefile =================================================================== --- trunk/extractor/Makefile 2008-08-22 16:08:44 UTC (rev 97) +++ trunk/extractor/Makefile 2008-08-22 16:09:05 UTC (rev 98) @@ -16,12 +16,14 @@ helpers.c \ ifeq ($(WITHOUT_GTK), yes) -GTKFLAGS=-DWITHOUT_GTK +CFLAGS+=-DWITHOUT_GTK else MAIN+= gtkstuff.c -GTKFLAGS=`pkg-config --cflags --libs gtk+-2.0` -#GTKFLAGS=-mms-bitfields -Iinclude libglib-2.0-0.dll libgobject-2.0-0.dll libgdk-win32-2.0-0.dll libgdk_pixbuf-2.0-0.dll libgtk-win32-2.0-0.dll intl.dll -#GTKFLAGS+=-mwindows +CFLAGS+=$(shell pkg-config --cflags gtk+-2.0) +LDFLAGS=$(shell pkg-config --libs gtk+-2.0) +#CFLAGS+=-mms-bitfields -Iinclude +#LDFLAGS=libglib-2.0-0.dll libgobject-2.0-0.dll libgdk-win32-2.0-0.dll libgdk_pixbuf-2.0-0.dll libgtk-win32-2.0-0.dll intl.dll +#LDFLAGS+=-mwindows endif SRCS=$(MAIN) $(MODULES) @@ -33,13 +35,13 @@ depend: $(DEPS) %.d: %.c - $(CC) -MM $(CFLAGS) $(GTKFLAGS) $< -o $@ + $(CC) -MM $(CFLAGS) $< -o $@ %.o: %.c - $(CC) -c $(CFLAGS) $(GTKFLAGS) $< -o $@ + $(CC) -c $(CFLAGS) $< -o $@ extractor: $(OBJS) - $(CC) $(CFLAGS) $(GTKFLAGS) $^ -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ clean: rm -f extractor *.o *.d This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:08:49
|
Revision: 97 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=97&view=rev Author: someone-guy Date: 2008-08-22 16:08:44 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Optimize generic file parsing. Modified Paths: -------------- trunk/extractor/generic.c Modified: trunk/extractor/generic.c =================================================================== --- trunk/extractor/generic.c 2008-08-22 16:08:20 UTC (rev 96) +++ trunk/extractor/generic.c 2008-08-22 16:08:44 UTC (rev 97) @@ -31,56 +31,99 @@ typedef uint64_t buffer_t; +#define RAMBUF_SZ (256 * 1024) + +static inline uint16_t get_le16(uint8_t **p) { + uint16_t res = *(*p)++; + res += *(*p)++ << 8; + return res; +} + +static inline uint16_t get_be16(uint8_t **p) { + uint16_t res = *(*p)++ << 8; + res += *(*p)++; + return res; +} + +static inline uint32_t get_le32(uint8_t **p) { + uint32_t res = get_le16(p); + res += get_le16(p) << 16; + return res; +} + +static inline uint32_t get_be32(uint8_t **p) { + uint32_t res = get_be16(p) << 16; + res += get_be16(p); + return res; +} + static file_t *get_list(FILE *in) { register buffer_t t = 0; + uint8_t *rambuf = malloc(2 * RAMBUF_SZ); + uint64_t fpos = 0; + int rambuf_used = 0; + int rambuf_pos = 0; int bz2idx = -1; int pngidx = -1; int cnt = 0; file_t *list = calloc(1, sizeof(file_t)); - rewind(in); - while (!feof(in) && cnt < MAX_FILES) { + while (cnt < MAX_FILES) { + uint8_t *p; int i; - t = t << 8 | fgetc(in); + if (rambuf_pos >= rambuf_used || rambuf_pos >= RAMBUF_SZ) { + if (rambuf_pos >= RAMBUF_SZ) { + rambuf_pos -= RAMBUF_SZ; + rambuf_used -= RAMBUF_SZ; + memcpy(rambuf, rambuf + RAMBUF_SZ, RAMBUF_SZ); + } else { + rambuf_pos = rambuf_used = 0; + } + rambuf_used += fread(rambuf + rambuf_used, 1, 2 * RAMBUF_SZ - rambuf_used, in); + if (rambuf_used <= 0) break; // EOF + } + t = t << 8 | rambuf[rambuf_pos++]; + p = rambuf + rambuf_pos; + fpos++; switch (t) { case HUGETAG(0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1): add_entry(&list, cnt, "msi"); - list[cnt].start = ftell(in) - 8; + list[cnt].start = fpos - 8; cnt++; break; case HUGETAG(0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a): if (pngidx >= 0 && list[pngidx].len == 0) - list[pngidx].len = ftell(in) - list[pngidx].start - 8; + list[pngidx].len = fpos - list[pngidx].start - 8; add_entry(&list, cnt, "png"); - list[cnt].start = ftell(in) - 8; + list[cnt].start = fpos - 8; pngidx = cnt; cnt++; break; case HUGETAG(0, 0, 0, 0, 'I', 'E', 'N', 'D'): if (pngidx >= 0) - list[pngidx].len = ftell(in) - list[pngidx].start + 4; + list[pngidx].len = fpos - list[pngidx].start + 4; break; } - switch (t & 0xffffffff) { + switch ((uint32_t)t) { case TAG('M', 'S', 'C', 'F'): { - uint32_t unk = read_le32(in); - uint32_t size = read_le32(in); - fseek(in, -8, SEEK_CUR); + uint32_t unk = get_le32(&p); + uint32_t size = get_le32(&p); + p -= 8; add_entry(&list, cnt, "cab"); - list[cnt].start = ftell(in) - 4; + list[cnt].start = fpos - 4; list[cnt].len = size; cnt++; break; } case TAG('R', 'I', 'F', 'F'): { const char *ext = "riff"; - uint32_t len = read_le32(in); - uint32_t type = read_be32(in); - fseek(in, -8, SEEK_CUR); + uint32_t len = get_le32(&p); + uint32_t type = get_be32(&p); + p -= 8; if (len <= 4 || !is_valid_fourcc(type)) break; if (type == TAG('W', 'A', 'V', 'E')) ext = "wav"; if (type >> 8 == TAG(0, 'A', 'V', 'I')) ext = "avi"; add_entry(&list, cnt, ext); - list[cnt].start = ftell(in) - 4; + list[cnt].start = fpos - 4; list[cnt].len = len + 8; cnt++; break; @@ -88,16 +131,16 @@ case TAG('P', 'K', 5, 6): { uint64_t offset; uint16_t comment_len; - fseek(in, 8, SEEK_CUR); - offset = read_le32(in); // size of central directory - offset += read_le32(in); // offset of central directory + p += 8; + offset = get_le32(&p); // size of central directory + offset += get_le32(&p); // offset of central directory offset += 4; // PK.. - comment_len = read_le16(in); // comment length - fseek(in, -18, SEEK_CUR); - if (offset > ftell(in)) + comment_len = get_le16(&p); // comment length + p -= 18; + if (offset > fpos) break; add_entry(&list, cnt, "zip"); - list[cnt].start = ftell(in) - offset; + list[cnt].start = fpos - offset; list[cnt].len = offset + 18 + comment_len; cnt++; } @@ -107,49 +150,49 @@ // compressed flash. Note that length is _decompressed_ size // so we will extract more data than necessary case TAG(0, 'C', 'W', 'S'): { - uint8_t ver = fgetc(in); - uint32_t size = read_le32(in); - uint8_t rectbits = fgetc(in) >> 3; - fseek(in, -6, SEEK_CUR); + uint8_t ver = *p++; + uint32_t size = get_le32(&p); + uint8_t rectbits = *p++ >> 3; + p -= 6; if ((ver & 0xf0) || rectbits != 15) break; add_entry(&list, cnt, "swf"); - list[cnt].start = ftell(in) - 3; + list[cnt].start = fpos - 3; list[cnt].len = size; cnt++; break; } case TAG(0, 'B', 'Z', 'h'): if (bz2idx >= 0 && list[bz2idx].len == 0) { - list[bz2idx].start = ftell(in) - 3; + list[bz2idx].start = fpos - 3; break; } add_entry(&list, cnt, "bz2"); - list[cnt].start = ftell(in) - 3; + list[cnt].start = fpos - 3; bz2idx = cnt; cnt++; break; case 0xffd8ff: add_entry(&list, cnt, "jpg"); - list[cnt].start = ftell(in) - 3; + list[cnt].start = fpos - 3; list[cnt].priv = (void *)1; cnt++; break; } - switch (t & 0xffff) { + switch ((uint16_t)t) { case TAG(0, 0, 'B', 'M'): { - uint32_t len = read_le32(in); - uint16_t res1 = read_le16(in); - uint16_t res2 = read_le16(in); - uint32_t dataoff = read_le32(in); - uint32_t bisize = read_le32(in); - fseek(in, -16, SEEK_CUR); + uint32_t len = get_le32(&p); + uint16_t res1 = get_le16(&p); + uint16_t res2 = get_le16(&p); + uint32_t dataoff = get_le32(&p); + uint32_t bisize = get_le32(&p); + p -= 16; if (bisize < 40 || bisize > 1024*1024 || dataoff < bisize + 14 || len < dataoff || len > 1024*1024*1024) break; add_entry(&list, cnt, "bmp"); - list[cnt].start = ftell(in) - 2; + list[cnt].start = fpos - 2; list[cnt].len = len; cnt++; break; @@ -157,7 +200,7 @@ case 0xffd9: for (i = 0; i < cnt; i++) { if (list[i].priv == (void *)1 && list[i].len == 0) - list[i].len = ftell(in) - list[i].start; + list[i].len = fpos - list[i].start; } break; } @@ -166,17 +209,19 @@ // if buffer_t is changed to only 32 bits, otherwise all 48 bits buffer_t endmark = 0x177245385090ULL; buffer_t mask = 0xffffffffffffULL; - for (i = 0; i < 8; i++) { + i = 8; + do { if ((t & mask) == endmark) { // end marker plus space for CRC - list[bz2idx].len = ftell(in) - list[bz2idx].start + 4; + list[bz2idx].len = fpos - list[bz2idx].start + 4; break; } endmark <<= 1; mask <<= 1; - } + } while (--i); } } + free(rambuf); return list; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:08:23
|
Revision: 96 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=96&view=rev Author: someone-guy Date: 2008-08-22 16:08:20 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Reduce scope of another global variable Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:07:59 UTC (rev 95) +++ trunk/extractor/extractor.c 2008-08-22 16:08:20 UTC (rev 96) @@ -30,7 +30,6 @@ }; static FILE *input_file = NULL; -static file_t *flist = NULL; static const fmt_desc_t *cur_fmt = NULL; int extract_file(const file_t *file, FILE *out) { @@ -42,6 +41,7 @@ } file_t *open_file(const char *fname, const fmt_desc_t *fmt) { + static file_t *flist = NULL; // close previous file and free its data if (cur_fmt && flist) cur_fmt->free_list(flist); @@ -83,6 +83,7 @@ int main(int argc, char *argv[]) { int fmt_idx = -1; int list_files = 0; + file_t *flist = NULL; if (argc > 1) { int pos = 1; @@ -121,7 +122,8 @@ return 1; } } - if (!open_file(argv[pos], fmt_idx >= 0 ? fmts[fmt_idx] : NULL)) { + flist = open_file(argv[pos], fmt_idx >= 0 ? fmts[fmt_idx] : NULL); + if (!flist) { fprintf(stderr, _("Could not open file %s\n"), argv[pos]); return 1; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:08:02
|
Revision: 95 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=95&view=rev Author: someone-guy Date: 2008-08-22 16:07:59 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Change open_file to make it also work for freeing data. Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:07:38 UTC (rev 94) +++ trunk/extractor/extractor.c 2008-08-22 16:07:59 UTC (rev 95) @@ -49,6 +49,8 @@ cur_fmt = NULL; if (input_file) fclose(input_file); + if (!fname) + return NULL; // open new file input_file = fopen(fname, "rb"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:07:40
|
Revision: 94 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=94&view=rev Author: someone-guy Date: 2008-08-22 16:07:38 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Nicer Makefile Modified Paths: -------------- trunk/extractor/Makefile Modified: trunk/extractor/Makefile =================================================================== --- trunk/extractor/Makefile 2008-08-22 16:07:14 UTC (rev 93) +++ trunk/extractor/Makefile 2008-08-22 16:07:38 UTC (rev 94) @@ -1,10 +1,6 @@ CC=gcc CFLAGS=-Wall -Wdeclaration-after-statement -Wpointer-arith -Wredundant-decls -Wcast-qual -Wwrite-strings -g -O2 CFLAGS+=-std=c99 -D_XOPEN_SOURCE=500 -GTKFLAGS=`pkg-config --cflags --libs gtk+-2.0` -#GTKFLAGS=-DWITHOUT_GTK -#GTKFLAGS=-mms-bitfields -Iinclude libglib-2.0-0.dll libgobject-2.0-0.dll libgdk-win32-2.0-0.dll libgdk_pixbuf-2.0-0.dll libgtk-win32-2.0-0.dll intl.dll -#GTKFLAGS+=-mwindows MODULES= \ bloodrayne.c \ generic.c \ @@ -18,16 +14,38 @@ MAIN= \ extractor.c \ helpers.c \ - gtkstuff.c \ -HEADERS= \ - helpers.h \ - formats.h \ +ifeq ($(WITHOUT_GTK), yes) +GTKFLAGS=-DWITHOUT_GTK +else +MAIN+= gtkstuff.c +GTKFLAGS=`pkg-config --cflags --libs gtk+-2.0` +#GTKFLAGS=-mms-bitfields -Iinclude libglib-2.0-0.dll libgobject-2.0-0.dll libgdk-win32-2.0-0.dll libgdk_pixbuf-2.0-0.dll libgtk-win32-2.0-0.dll intl.dll +#GTKFLAGS+=-mwindows +endif +SRCS=$(MAIN) $(MODULES) +OBJS=${SRCS:.c=.o} +DEPS=${SRCS:.c=.d} + all: extractor -extractor: $(MAIN) $(MODULES) +depend: $(DEPS) + +%.d: %.c + $(CC) -MM $(CFLAGS) $(GTKFLAGS) $< -o $@ + +%.o: %.c + $(CC) -c $(CFLAGS) $(GTKFLAGS) $< -o $@ + +extractor: $(OBJS) $(CC) $(CFLAGS) $(GTKFLAGS) $^ -o $@ clean: - rm -f extractor *.o + rm -f extractor *.o *.d + +.PHONY: all clean depend + +ifneq ($(MAKECMDGOALS), clean) +-include $(DEPS) +endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:07:18
|
Revision: 93 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=93&view=rev Author: someone-guy Date: 2008-08-22 16:07:14 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Split gtk stuff out into a separate file. Modified Paths: -------------- trunk/extractor/Makefile trunk/extractor/extractor.c Added Paths: ----------- trunk/extractor/extractor.h trunk/extractor/gtkstuff.c trunk/extractor/gtkstuff.h Modified: trunk/extractor/Makefile =================================================================== --- trunk/extractor/Makefile 2008-08-22 16:06:35 UTC (rev 92) +++ trunk/extractor/Makefile 2008-08-22 16:07:14 UTC (rev 93) @@ -1,5 +1,6 @@ CC=gcc CFLAGS=-Wall -Wdeclaration-after-statement -Wpointer-arith -Wredundant-decls -Wcast-qual -Wwrite-strings -g -O2 +CFLAGS+=-std=c99 -D_XOPEN_SOURCE=500 GTKFLAGS=`pkg-config --cflags --libs gtk+-2.0` #GTKFLAGS=-DWITHOUT_GTK #GTKFLAGS=-mms-bitfields -Iinclude libglib-2.0-0.dll libgobject-2.0-0.dll libgdk-win32-2.0-0.dll libgdk_pixbuf-2.0-0.dll libgtk-win32-2.0-0.dll intl.dll @@ -14,10 +15,19 @@ wad.c \ xtre.c \ +MAIN= \ + extractor.c \ + helpers.c \ + gtkstuff.c \ + +HEADERS= \ + helpers.h \ + formats.h \ + all: extractor -extractor: extractor.c helpers.c helpers.h formats.h $(MODULES) - $(CC) $(CFLAGS) -o extractor extractor.c helpers.c $(MODULES) $(GTKFLAGS) +extractor: $(MAIN) $(MODULES) + $(CC) $(CFLAGS) $(GTKFLAGS) $^ -o $@ clean: rm -f extractor *.o Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:06:35 UTC (rev 92) +++ trunk/extractor/extractor.c 2008-08-22 16:07:14 UTC (rev 93) @@ -8,18 +8,16 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <errno.h> #include <unistd.h> #include <inttypes.h> +#include "formats.h" +#include "extractor.h" #ifndef WITHOUT_GTK -#include <gtk/gtk.h> +#include "gtkstuff.h" #endif -#include <libintl.h> -#define _(String) gettext(String) -#include "formats.h" //! brief NULL-terminated array of supported formats -static const fmt_desc_t * const fmts[] = { +const fmt_desc_t * const fmts[] = { &bloodrayne_fmt, &generic_fmt, &homeworld2_fmt, @@ -31,117 +29,19 @@ NULL }; -#ifndef WITHOUT_GTK -#define SHOW_MSG(t, s, a...) \ -{\ - GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,\ - t, GTK_BUTTONS_CLOSE, s, ##a);\ - gtk_dialog_run(GTK_DIALOG(dialog));\ - gtk_widget_destroy(dialog);\ -} - -//! columns in file list table -enum { - FNAME_COL, - SIZE_COL, - OFFSET_COL, - COMPR_COL, - PTR_COL, - N_COLS -}; - -//! types of columns in the file list table -static const GType coltypes[N_COLS] = { - [FNAME_COL] = G_TYPE_STRING, - [SIZE_COL] = G_TYPE_UINT64, - [OFFSET_COL] = G_TYPE_UINT64, - [COMPR_COL] = G_TYPE_BOOLEAN, - [PTR_COL] = G_TYPE_POINTER, -}; - -static GtkWidget *dir_button; -static GtkListStore *gflist; -static GtkWidget *treeview; -#endif static FILE *input_file = NULL; static file_t *flist = NULL; static const fmt_desc_t *cur_fmt = NULL; -#ifndef WITHOUT_GTK -/** - * \brief extracts the file specified by iter - * \param data path to extract the file into - * - * to be used with e.g. gtk_tree_selection_selected_foreach - */ -static void extract_foreach(GtkTreeModel *model, GtkTreePath *path, - GtkTreeIter *iter, gpointer data) { - char *fname; - char *good_slash, *slash; - file_t *file; - FILE *out; - gtk_tree_model_get(model, iter, PTR_COL, &file, -1); - fname = malloc(strlen(data) + strlen(file->name) + 2); - strcpy(fname, data); - strcat(fname, "/"); - strcat(fname, file->name); - good_slash = fname + strlen(data); - while ((slash = strrchr(fname, '/')) > good_slash) - *slash = '_'; - out = fopen(fname, "wb"); - if (out) - cur_fmt->extract_file(input_file, file, out); - fclose(out); - free(fname); +int extract_file(const file_t *file, FILE *out) { + return cur_fmt->extract_file(input_file, file, out); } -/** - * \brief extracts all the files selected in the tree view to the selected path - */ -static void extract_selected(GtkWidget *widget, gpointer data) { - gchar *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dir_button)); - GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - gtk_tree_selection_selected_foreach(selection, extract_foreach, path); - g_free(path); +int extract_mem(const file_t *file, uint8_t *out, int out_size) { + return cur_fmt->extract_mem(input_file, file, out, out_size); } -static void set_treeview_model(GtkTreeView *view, GtkTreeModel *model) { - GtkTreeModel *sort = gtk_tree_model_sort_new_with_model(model); - gtk_tree_view_set_model(view, sort); - g_object_unref(sort); -} - -static void clear_treeview() { - gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); - gtk_list_store_clear(gflist); - set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); -} - -/** - * \brief modifies the treeview to display the contents of the given - * file_t array - * \param list array describing the files in the archive. - * Must be NULL-terminated. - */ -static void set_treeview(file_t *list) { - GtkTreeIter iter; - if (!list) { - clear_treeview(); - return; - } - gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); - gtk_list_store_clear(gflist); - while (list->name) { - gtk_list_store_append(gflist, &iter); - gtk_list_store_set(gflist, &iter, FNAME_COL, list->name, - SIZE_COL, list->len, OFFSET_COL, list->start, COMPR_COL, list->compressed, PTR_COL, list, -1); - list++; - } - set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); -} -#endif - -static int open_file(const char *fname, const fmt_desc_t *fmt) { +file_t *open_file(const char *fname, const fmt_desc_t *fmt) { // close previous file and free its data if (cur_fmt && flist) cur_fmt->free_list(flist); @@ -153,7 +53,7 @@ // open new file input_file = fopen(fname, "rb"); if (!input_file) - return 0; + return NULL; if (!fmt) { int i; for (i = 0; fmts[i]; i++) { @@ -167,92 +67,9 @@ fmt = &generic_fmt; cur_fmt = fmt; flist = cur_fmt->get_list(input_file); - return 1; + return flist; } -#ifndef WITHOUT_GTK -/** - * \brief called when a new archive is selected - */ -static void file_select(GtkWidget *widget, gpointer data) { - const char *filter = - gtk_file_filter_get_name(gtk_file_chooser_get_filter( - GTK_FILE_CHOOSER(widget))); - const fmt_desc_t * const *fmt = fmts; - gchar *fname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); - while ((*fmt)->desc && strcmp(filter, _((*fmt)->desc)) != 0) fmt++; - if (!(*fmt)->desc) { - SHOW_MSG(GTK_MESSAGE_ERROR, _("Invalid file type selected")); - goto err_out; - } - - if (!open_file(fname, *fmt)) { - SHOW_MSG(GTK_MESSAGE_ERROR, _("Error opening file '%s': %s"), - fname, g_strerror(errno)); - goto err_out; - } - g_free(fname); - set_treeview(flist); - return; - -err_out: - // error opening new file, clean everything up - if (fname) - g_free(fname); - if (input_file) - fclose(input_file); - input_file = NULL; - if (cur_fmt && flist) - cur_fmt->free_list(flist); - flist = NULL; - cur_fmt = NULL; - clear_treeview(); -} - -static gboolean delete_event(GtkWidget *widget, GdkEvent *event, - gpointer data) { - gtk_main_quit(); - return FALSE; -} - -#define MAX_IMG_SZ (100*1024*1024) - -/** - * Called when user double-clicks on a archive content - */ -static void row_activate(GtkTreeView *treeview, GtkTreePath *path, - GtkTreeViewColumn *col, gpointer data) { - GtkTreeModel *model = gtk_tree_view_get_model(treeview); - GtkTreeIter iter; - GtkWidget *preview_win = data; - file_t *file; - int size; - uint8_t *tmpdata; - GdkPixbufLoader *pbl; - GdkPixbuf *pb; - GtkWidget *img = gtk_bin_get_child(GTK_BIN(preview_win)); - if (img) - gtk_container_remove(GTK_CONTAINER(preview_win), img); - - if (!gtk_tree_model_get_iter(model, &iter, path)) - return; - gtk_tree_model_get(model, &iter, PTR_COL, &file, -1); - tmpdata = malloc(MAX_IMG_SZ); - size = cur_fmt->extract_mem(input_file, file, tmpdata, MAX_IMG_SZ); - if (size > MAX_IMG_SZ || size < 0) size = MAX_IMG_SZ; - pbl = gdk_pixbuf_loader_new(); - gdk_pixbuf_loader_write(pbl, tmpdata, size, NULL); - free(tmpdata); - gdk_pixbuf_loader_close(pbl, NULL); - pb = gdk_pixbuf_loader_get_pixbuf(pbl); - img = gtk_image_new_from_pixbuf(pb); - g_object_unref(pbl); - gtk_container_add(GTK_CONTAINER(preview_win), img); - gtk_widget_show(img); - gtk_window_present(GTK_WINDOW(preview_win)); -} -#endif - static void print_help(void) { int i; fprintf(stderr, _("Usage: extractor [-h|[-l|--] filename [format]]\n")); @@ -262,21 +79,7 @@ } int main(int argc, char *argv[]) { - int i; int fmt_idx = -1; -#ifndef WITHOUT_GTK - GtkWidget *window; - GtkWidget *preview_win; - GtkWidget *table; - GtkWidget *file_button; - GtkWidget *button; - GtkWidget *scrollwin; - GtkWidget *lbl; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - GtkTreeSelection *selection; - int row = 0, col = 0; -#endif int list_files = 0; if (argc > 1) { @@ -330,116 +133,10 @@ } } -#ifndef WITHOUT_GTK - gtk_disable_setlocale(); - gtk_init(&argc, &argv); - - preview_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_resizable(GTK_WINDOW(preview_win), FALSE); - g_signal_connect(G_OBJECT(preview_win), "delete_event", - G_CALLBACK(gtk_widget_hide_on_delete), NULL); - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(window), _("extractor")); - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(delete_event), NULL); - - table = gtk_table_new(3, 3, FALSE); - gtk_container_add(GTK_CONTAINER(window), table); - - scrollwin = gtk_scrolled_window_new(NULL, NULL); - gtk_table_attach(GTK_TABLE(table), scrollwin, col, col + 3, row, row + 1, - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); - gflist = gtk_list_store_new(N_COLS, coltypes[0], coltypes[1], coltypes[2], - coltypes[3], coltypes[4]); - treeview = gtk_tree_view_new(); - set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); - gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer, - "text", FNAME_COL, NULL); - gtk_tree_view_column_set_sort_column_id(column, FNAME_COL); - gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Size"), renderer, - "text", SIZE_COL, NULL); - gtk_tree_view_column_set_sort_column_id(column, SIZE_COL); - gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Offset"), renderer, - "text", OFFSET_COL, NULL); - gtk_tree_view_column_set_sort_column_id(column, OFFSET_COL); - gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); - - renderer = gtk_cell_renderer_toggle_new(); - column = gtk_tree_view_column_new_with_attributes(_("Compressed"), renderer, - "active", COMPR_COL, NULL); - gtk_tree_view_column_set_sort_column_id(column, COMPR_COL); - gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); - - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - g_signal_connect(G_OBJECT(treeview), "row-activated", - G_CALLBACK(row_activate), preview_win); - gtk_container_add(GTK_CONTAINER(scrollwin), treeview); - - row++; - col = 0; - lbl = gtk_label_new(_("Archive Filename")); - gtk_table_attach(GTK_TABLE(table), lbl, col, col + 1, row, row + 1, - (GtkAttachOptions)(GTK_FILL), - (GtkAttachOptions)(0), 5, 0); - col++; - lbl = gtk_label_new(_("Output Directory")); - gtk_table_attach(GTK_TABLE(table), lbl, col, col + 1, row, row + 1, - (GtkAttachOptions)(GTK_FILL), - (GtkAttachOptions)(0), 5, 0); - - row++; - col = 0; - file_button = gtk_file_chooser_button_new(_("open"), - GTK_FILE_CHOOSER_ACTION_OPEN); - for (i = 0; fmts[i]; i++) { - GtkFileFilter *filter = gtk_file_filter_new(); - char *patterns = strdup(fmts[i]->pattern); - char *pattern = strtok(patterns, ";"); - while (pattern && pattern[0]) { - gtk_file_filter_add_pattern(filter, pattern); - pattern = strtok(NULL, ";"); - } - free(patterns); - gtk_file_filter_set_name(filter, _(fmts[i]->desc)); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_button), filter); - } - g_signal_connect(G_OBJECT(file_button), "selection-changed", - G_CALLBACK(file_select), NULL); - gtk_table_attach(GTK_TABLE(table), file_button, col, col + 1, row, row + 1, - (GtkAttachOptions)(GTK_FILL), - (GtkAttachOptions)(0), 5, 0); - - col++; - dir_button = gtk_file_chooser_button_new(_("select"), - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); - gtk_table_attach(GTK_TABLE(table), dir_button, col, col + 1, row, row + 1, - (GtkAttachOptions)(GTK_FILL), - (GtkAttachOptions)(0), 5, 0); - - col++; - button = gtk_button_new_with_mnemonic(_("extract selected")); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(extract_selected), NULL); - gtk_table_attach(GTK_TABLE(table), button, col, col + 1, row, row + 1, - (GtkAttachOptions)(GTK_FILL), - (GtkAttachOptions)(0), 5, 0); - - gtk_window_set_default_size(GTK_WINDOW(window), -1, 400); - gtk_widget_show_all(window); - set_treeview(flist); - gtk_main(); +#ifdef WITHOUT_GTK + print_help(); + return 1; +#else + return start_gtk_gui(argc, argv, flist); #endif - return 0; } Added: trunk/extractor/extractor.h =================================================================== --- trunk/extractor/extractor.h (rev 0) +++ trunk/extractor/extractor.h 2008-08-22 16:07:14 UTC (rev 93) @@ -0,0 +1,6 @@ +#include <libintl.h> +#define _(String) gettext(String) +file_t *open_file(const char *fname, const fmt_desc_t *fmt); +int extract_file(const file_t *file, FILE *out); +int extract_mem(const file_t *file, uint8_t *out, int out_size); +extern const fmt_desc_t * const fmts[]; Copied: trunk/extractor/gtkstuff.c (from rev 92, trunk/extractor/extractor.c) =================================================================== --- trunk/extractor/gtkstuff.c (rev 0) +++ trunk/extractor/gtkstuff.c 2008-08-22 16:07:14 UTC (rev 93) @@ -0,0 +1,313 @@ +#include <gtk/gtk.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "formats.h" +#include "extractor.h" +#include "gtkstuff.h" + +#define SHOW_MSG(t, s, a...) \ +{\ + GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,\ + t, GTK_BUTTONS_CLOSE, s, ##a);\ + gtk_dialog_run(GTK_DIALOG(dialog));\ + gtk_widget_destroy(dialog);\ +} + +//! columns in file list table +enum { + FNAME_COL, + SIZE_COL, + OFFSET_COL, + COMPR_COL, + PTR_COL, + N_COLS +}; + +//! types of columns in the file list table +static const GType coltypes[N_COLS] = { + [FNAME_COL] = G_TYPE_STRING, + [SIZE_COL] = G_TYPE_UINT64, + [OFFSET_COL] = G_TYPE_UINT64, + [COMPR_COL] = G_TYPE_BOOLEAN, + [PTR_COL] = G_TYPE_POINTER, +}; + +static GtkWidget *dir_button; +static GtkListStore *gflist; +static GtkWidget *treeview; + +/** + * \brief extracts the file specified by iter + * \param data path to extract the file into + * + * to be used with e.g. gtk_tree_selection_selected_foreach + */ +static void extract_foreach(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data) { + char *fname; + char *good_slash, *slash; + file_t *file; + FILE *out; + gtk_tree_model_get(model, iter, PTR_COL, &file, -1); + fname = malloc(strlen(data) + strlen(file->name) + 2); + strcpy(fname, data); + strcat(fname, "/"); + strcat(fname, file->name); + good_slash = fname + strlen(data); + while ((slash = strrchr(fname, '/')) > good_slash) + *slash = '_'; + out = fopen(fname, "wb"); + if (out) + extract_file(file, out); + fclose(out); + free(fname); +} + +/** + * \brief extracts all the files selected in the tree view to the selected path + */ +static void extract_selected(GtkWidget *widget, gpointer data) { + gchar *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dir_button)); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + gtk_tree_selection_selected_foreach(selection, extract_foreach, path); + g_free(path); +} + +static void set_treeview_model(GtkTreeView *view, GtkTreeModel *model) { + GtkTreeModel *sort = gtk_tree_model_sort_new_with_model(model); + gtk_tree_view_set_model(view, sort); + g_object_unref(sort); +} + +static void clear_treeview() { + gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); + gtk_list_store_clear(gflist); + set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); +} + +/** + * \brief modifies the treeview to display the contents of the given + * file_t array + * \param list array describing the files in the archive. + * Must be NULL-terminated. + */ +static void set_treeview(file_t *list) { + GtkTreeIter iter; + if (!list) { + clear_treeview(); + return; + } + gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); + gtk_list_store_clear(gflist); + while (list->name) { + gtk_list_store_append(gflist, &iter); + gtk_list_store_set(gflist, &iter, FNAME_COL, list->name, + SIZE_COL, list->len, OFFSET_COL, list->start, COMPR_COL, list->compressed, PTR_COL, list, -1); + list++; + } + set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); +} + +/** + * \brief called when a new archive is selected + */ +static void file_select(GtkWidget *widget, gpointer data) { + file_t *flist; + const char *filter = + gtk_file_filter_get_name(gtk_file_chooser_get_filter( + GTK_FILE_CHOOSER(widget))); + const fmt_desc_t * const *fmt = fmts; + gchar *fname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); + while ((*fmt)->desc && strcmp(filter, _((*fmt)->desc)) != 0) fmt++; + if (!(*fmt)->desc) { + SHOW_MSG(GTK_MESSAGE_ERROR, _("Invalid file type selected")); + goto err_out; + } + + flist = open_file(fname, *fmt); + if (!flist) { + SHOW_MSG(GTK_MESSAGE_ERROR, _("Error opening file '%s': %s"), + fname, g_strerror(errno)); + goto err_out; + } + g_free(fname); + set_treeview(flist); + return; + +err_out: + // error opening new file, clean everything up + if (fname) + g_free(fname); + clear_treeview(); +} + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, + gpointer data) { + gtk_main_quit(); + return FALSE; +} + +#define MAX_IMG_SZ (100*1024*1024) + +/** + * Called when user double-clicks on a archive content + */ +static void row_activate(GtkTreeView *treeview, GtkTreePath *path, + GtkTreeViewColumn *col, gpointer data) { + GtkTreeModel *model = gtk_tree_view_get_model(treeview); + GtkTreeIter iter; + GtkWidget *preview_win = data; + file_t *file; + int size; + uint8_t *tmpdata; + GdkPixbufLoader *pbl; + GdkPixbuf *pb; + GtkWidget *img = gtk_bin_get_child(GTK_BIN(preview_win)); + if (img) + gtk_container_remove(GTK_CONTAINER(preview_win), img); + + if (!gtk_tree_model_get_iter(model, &iter, path)) + return; + gtk_tree_model_get(model, &iter, PTR_COL, &file, -1); + tmpdata = malloc(MAX_IMG_SZ); + size = extract_mem(file, tmpdata, MAX_IMG_SZ); + if (size > MAX_IMG_SZ || size < 0) size = MAX_IMG_SZ; + pbl = gdk_pixbuf_loader_new(); + gdk_pixbuf_loader_write(pbl, tmpdata, size, NULL); + free(tmpdata); + gdk_pixbuf_loader_close(pbl, NULL); + pb = gdk_pixbuf_loader_get_pixbuf(pbl); + img = gtk_image_new_from_pixbuf(pb); + g_object_unref(pbl); + gtk_container_add(GTK_CONTAINER(preview_win), img); + gtk_widget_show(img); + gtk_window_present(GTK_WINDOW(preview_win)); +} + +int start_gtk_gui(int argc, char *argv[], file_t *flist) { + int i; + GtkWidget *window; + GtkWidget *preview_win; + GtkWidget *table; + GtkWidget *file_button; + GtkWidget *button; + GtkWidget *scrollwin; + GtkWidget *lbl; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + int row = 0, col = 0; + + gtk_disable_setlocale(); + gtk_init(&argc, &argv); + + preview_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_resizable(GTK_WINDOW(preview_win), FALSE); + g_signal_connect(G_OBJECT(preview_win), "delete_event", + G_CALLBACK(gtk_widget_hide_on_delete), NULL); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), _("extractor")); + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(delete_event), NULL); + + table = gtk_table_new(3, 3, FALSE); + gtk_container_add(GTK_CONTAINER(window), table); + + scrollwin = gtk_scrolled_window_new(NULL, NULL); + gtk_table_attach(GTK_TABLE(table), scrollwin, col, col + 3, row, row + 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); + gflist = gtk_list_store_new(N_COLS, coltypes[0], coltypes[1], coltypes[2], + coltypes[3], coltypes[4]); + treeview = gtk_tree_view_new(); + set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); + gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer, + "text", FNAME_COL, NULL); + gtk_tree_view_column_set_sort_column_id(column, FNAME_COL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Size"), renderer, + "text", SIZE_COL, NULL); + gtk_tree_view_column_set_sort_column_id(column, SIZE_COL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Offset"), renderer, + "text", OFFSET_COL, NULL); + gtk_tree_view_column_set_sort_column_id(column, OFFSET_COL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_toggle_new(); + column = gtk_tree_view_column_new_with_attributes(_("Compressed"), renderer, + "active", COMPR_COL, NULL); + gtk_tree_view_column_set_sort_column_id(column, COMPR_COL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); + g_signal_connect(G_OBJECT(treeview), "row-activated", + G_CALLBACK(row_activate), preview_win); + gtk_container_add(GTK_CONTAINER(scrollwin), treeview); + + row++; + col = 0; + lbl = gtk_label_new(_("Archive Filename")); + gtk_table_attach(GTK_TABLE(table), lbl, col, col + 1, row, row + 1, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions)(0), 5, 0); + col++; + lbl = gtk_label_new(_("Output Directory")); + gtk_table_attach(GTK_TABLE(table), lbl, col, col + 1, row, row + 1, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions)(0), 5, 0); + + row++; + col = 0; + file_button = gtk_file_chooser_button_new(_("open"), + GTK_FILE_CHOOSER_ACTION_OPEN); + for (i = 0; fmts[i]; i++) { + GtkFileFilter *filter = gtk_file_filter_new(); + char *patterns = strdup(fmts[i]->pattern); + char *pattern = strtok(patterns, ";"); + while (pattern && pattern[0]) { + gtk_file_filter_add_pattern(filter, pattern); + pattern = strtok(NULL, ";"); + } + free(patterns); + gtk_file_filter_set_name(filter, _(fmts[i]->desc)); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_button), filter); + } + g_signal_connect(G_OBJECT(file_button), "selection-changed", + G_CALLBACK(file_select), NULL); + gtk_table_attach(GTK_TABLE(table), file_button, col, col + 1, row, row + 1, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions)(0), 5, 0); + + col++; + dir_button = gtk_file_chooser_button_new(_("select"), + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); + gtk_table_attach(GTK_TABLE(table), dir_button, col, col + 1, row, row + 1, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions)(0), 5, 0); + + col++; + button = gtk_button_new_with_mnemonic(_("extract selected")); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(extract_selected), NULL); + gtk_table_attach(GTK_TABLE(table), button, col, col + 1, row, row + 1, + (GtkAttachOptions)(GTK_FILL), + (GtkAttachOptions)(0), 5, 0); + + gtk_window_set_default_size(GTK_WINDOW(window), -1, 400); + gtk_widget_show_all(window); + set_treeview(flist); + gtk_main(); + return 0; +} Added: trunk/extractor/gtkstuff.h =================================================================== --- trunk/extractor/gtkstuff.h (rev 0) +++ trunk/extractor/gtkstuff.h 2008-08-22 16:07:14 UTC (rev 93) @@ -0,0 +1 @@ +int start_gtk_gui(int argc, char *argv[], file_t *flist); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:06:41
|
Revision: 92 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=92&view=rev Author: someone-guy Date: 2008-08-22 16:06:35 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Allow compilation without GTK Modified Paths: -------------- trunk/extractor/Makefile trunk/extractor/extractor.c Modified: trunk/extractor/Makefile =================================================================== --- trunk/extractor/Makefile 2008-08-22 16:06:08 UTC (rev 91) +++ trunk/extractor/Makefile 2008-08-22 16:06:35 UTC (rev 92) @@ -1,6 +1,7 @@ CC=gcc CFLAGS=-Wall -Wdeclaration-after-statement -Wpointer-arith -Wredundant-decls -Wcast-qual -Wwrite-strings -g -O2 GTKFLAGS=`pkg-config --cflags --libs gtk+-2.0` +#GTKFLAGS=-DWITHOUT_GTK #GTKFLAGS=-mms-bitfields -Iinclude libglib-2.0-0.dll libgobject-2.0-0.dll libgdk-win32-2.0-0.dll libgdk_pixbuf-2.0-0.dll libgtk-win32-2.0-0.dll intl.dll #GTKFLAGS+=-mwindows MODULES= \ Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:06:08 UTC (rev 91) +++ trunk/extractor/extractor.c 2008-08-22 16:06:35 UTC (rev 92) @@ -11,7 +11,9 @@ #include <errno.h> #include <unistd.h> #include <inttypes.h> +#ifndef WITHOUT_GTK #include <gtk/gtk.h> +#endif #include <libintl.h> #define _(String) gettext(String) #include "formats.h" @@ -29,6 +31,7 @@ NULL }; +#ifndef WITHOUT_GTK #define SHOW_MSG(t, s, a...) \ {\ GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,\ @@ -59,10 +62,12 @@ static GtkWidget *dir_button; static GtkListStore *gflist; static GtkWidget *treeview; +#endif static FILE *input_file = NULL; static file_t *flist = NULL; static const fmt_desc_t *cur_fmt = NULL; +#ifndef WITHOUT_GTK /** * \brief extracts the file specified by iter * \param data path to extract the file into @@ -134,6 +139,7 @@ } set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); } +#endif static int open_file(const char *fname, const fmt_desc_t *fmt) { // close previous file and free its data @@ -164,6 +170,7 @@ return 1; } +#ifndef WITHOUT_GTK /** * \brief called when a new archive is selected */ @@ -244,6 +251,7 @@ gtk_widget_show(img); gtk_window_present(GTK_WINDOW(preview_win)); } +#endif static void print_help(void) { int i; @@ -256,6 +264,7 @@ int main(int argc, char *argv[]) { int i; int fmt_idx = -1; +#ifndef WITHOUT_GTK GtkWidget *window; GtkWidget *preview_win; GtkWidget *table; @@ -267,6 +276,7 @@ GtkCellRenderer *renderer; GtkTreeSelection *selection; int row = 0, col = 0; +#endif int list_files = 0; if (argc > 1) { @@ -320,6 +330,7 @@ } } +#ifndef WITHOUT_GTK gtk_disable_setlocale(); gtk_init(&argc, &argv); @@ -429,5 +440,6 @@ gtk_widget_show_all(window); set_treeview(flist); gtk_main(); +#endif return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:06:12
|
Revision: 91 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=91&view=rev Author: someone-guy Date: 2008-08-22 16:06:08 +0000 (Fri, 22 Aug 2008) Log Message: ----------- One global variable less Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:05:43 UTC (rev 90) +++ trunk/extractor/extractor.c 2008-08-22 16:06:08 UTC (rev 91) @@ -59,7 +59,6 @@ static GtkWidget *dir_button; static GtkListStore *gflist; static GtkWidget *treeview; -static GtkTreeSelection *selection; static FILE *input_file = NULL; static file_t *flist = NULL; static const fmt_desc_t *cur_fmt = NULL; @@ -96,6 +95,7 @@ */ static void extract_selected(GtkWidget *widget, gpointer data) { gchar *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dir_button)); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_selected_foreach(selection, extract_foreach, path); g_free(path); } @@ -265,6 +265,7 @@ GtkWidget *lbl; GtkTreeViewColumn *column; GtkCellRenderer *renderer; + GtkTreeSelection *selection; int row = 0, col = 0; int list_files = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:05:47
|
Revision: 90 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=90&view=rev Author: someone-guy Date: 2008-08-22 16:05:43 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Allow forcing a format Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:05:19 UTC (rev 89) +++ trunk/extractor/extractor.c 2008-08-22 16:05:43 UTC (rev 90) @@ -247,7 +247,7 @@ static void print_help(void) { int i; - fprintf(stderr, _("Usage: extractor [--|-h|-l] [filename]\n")); + fprintf(stderr, _("Usage: extractor [-h|[-l|--] filename [format]]\n")); fprintf(stderr, _("Supported formats:\n")); for (i = 0; fmts[i]; i++) fprintf(stderr, "%-16s %s\n", fmts[i]->shortname, fmts[i]->name); @@ -255,6 +255,7 @@ int main(int argc, char *argv[]) { int i; + int fmt_idx = -1; GtkWidget *window; GtkWidget *preview_win; GtkWidget *table; @@ -292,7 +293,19 @@ fprintf(stderr, _("Missing filename argument\n")); return 1; } - if (!open_file(argv[pos], NULL)) { + if (argc > pos + 2) { + fprintf(stderr, _("Too many arguments\n")); + return 1; + } + if (argc > pos + 1) { + for (fmt_idx = 0; fmts[fmt_idx]; fmt_idx++) + if (strcmp(argv[pos + 1], fmts[fmt_idx]->shortname) == 0) break; + if (!fmts[fmt_idx]) { + fprintf(stderr, _("Unknown format name\n")); + return 1; + } + } + if (!open_file(argv[pos], fmt_idx >= 0 ? fmts[fmt_idx] : NULL)) { fprintf(stderr, _("Could not open file %s\n"), argv[pos]); return 1; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:05:22
|
Revision: 89 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=89&view=rev Author: someone-guy Date: 2008-08-22 16:05:19 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Print a supported formats list in help text. Modified Paths: -------------- trunk/extractor/bloodrayne.c trunk/extractor/extractor.c trunk/extractor/formats.h trunk/extractor/generic.c trunk/extractor/homeworld2.c trunk/extractor/nwn.c trunk/extractor/pak.c trunk/extractor/solid.c trunk/extractor/wad.c trunk/extractor/xtre.c Modified: trunk/extractor/bloodrayne.c =================================================================== --- trunk/extractor/bloodrayne.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/bloodrayne.c 2008-08-22 16:05:19 UTC (rev 89) @@ -45,6 +45,7 @@ } const fmt_desc_t bloodrayne_fmt = { + "bloodrayne", "BloodRayne", "BloodRayne (*.pod)", "*.pod;*.POD", Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/extractor.c 2008-08-22 16:05:19 UTC (rev 89) @@ -246,7 +246,11 @@ } static void print_help(void) { + int i; fprintf(stderr, _("Usage: extractor [--|-h|-l] [filename]\n")); + fprintf(stderr, _("Supported formats:\n")); + for (i = 0; fmts[i]; i++) + fprintf(stderr, "%-16s %s\n", fmts[i]->shortname, fmts[i]->name); } int main(int argc, char *argv[]) { Modified: trunk/extractor/formats.h =================================================================== --- trunk/extractor/formats.h 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/formats.h 2008-08-22 16:05:19 UTC (rev 89) @@ -15,6 +15,7 @@ //! struct describing an archive format and handling functions typedef struct fmt_desc_s { + const char *shortname; ///< short name of format for commandline use const char *name; ///< archive format name const char *desc; ///< archive format description const char *pattern; ///< file name pattern Modified: trunk/extractor/generic.c =================================================================== --- trunk/extractor/generic.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/generic.c 2008-08-22 16:05:19 UTC (rev 89) @@ -181,6 +181,7 @@ } const fmt_desc_t generic_fmt = { + "generic", "Generic File", "Generic File", "*", Modified: trunk/extractor/homeworld2.c =================================================================== --- trunk/extractor/homeworld2.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/homeworld2.c 2008-08-22 16:05:19 UTC (rev 89) @@ -86,6 +86,7 @@ } const fmt_desc_t homeworld2_fmt = { + "homeworld2", "Homeworld 2", "Homeworld 2 (*.big)", "*.big", Modified: trunk/extractor/nwn.c =================================================================== --- trunk/extractor/nwn.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/nwn.c 2008-08-22 16:05:19 UTC (rev 89) @@ -90,6 +90,7 @@ } const fmt_desc_t nwn_fmt = { + "nwn", "Neverwinter Nights (1/2)", "Neverwinter Nights (1/2) (*.mod;*.nwm;*.sav)", "*.mod;*.nwm;*.sav", Modified: trunk/extractor/pak.c =================================================================== --- trunk/extractor/pak.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/pak.c 2008-08-22 16:05:19 UTC (rev 89) @@ -41,6 +41,7 @@ } const fmt_desc_t pak_fmt = { + "pak", "PAK (HalfLife)", "PAK (*.pak)", "*.pak;*.PAK", Modified: trunk/extractor/solid.c =================================================================== --- trunk/extractor/solid.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/solid.c 2008-08-22 16:05:19 UTC (rev 89) @@ -172,6 +172,7 @@ } const fmt_desc_t solid_fmt = { + "solid", "MetalGear Solid: TS", "MetalGear Solid: TS (vox.dat)", "vox.dat", Modified: trunk/extractor/wad.c =================================================================== --- trunk/extractor/wad.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/wad.c 2008-08-22 16:05:19 UTC (rev 89) @@ -50,6 +50,7 @@ } const fmt_desc_t wad_fmt = { + "wad", "WAD (Doom etc.)", "WAD (*.wad)", "*.wad;*.WAD", Modified: trunk/extractor/xtre.c =================================================================== --- trunk/extractor/xtre.c 2008-08-22 16:04:22 UTC (rev 88) +++ trunk/extractor/xtre.c 2008-08-22 16:05:19 UTC (rev 89) @@ -68,6 +68,7 @@ } const fmt_desc_t xtre_fmt = { + "xtre", "Wing Commander IV", "Wing Commander IV (*.tre)", "*.tre", This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:04:25
|
Revision: 88 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=88&view=rev Author: someone-guy Date: 2008-08-22 16:04:22 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Inline several speed-relevant functions Modified Paths: -------------- trunk/extractor/helpers.c trunk/extractor/helpers.h trunk/extractor/solid.c Modified: trunk/extractor/helpers.c =================================================================== --- trunk/extractor/helpers.c 2008-08-22 16:03:53 UTC (rev 87) +++ trunk/extractor/helpers.c 2008-08-22 16:04:22 UTC (rev 88) @@ -33,41 +33,6 @@ return name; } -//! read a 32 bit little-endian value from file -uint32_t read_le32(FILE *f) { - unsigned char t[4]; - fread(t, 4, 1, f); - return (t[3] << 8 | t[2]) << 16 | (t[1] << 8 | t[0]); -} - -//! as read_le32 but do not advance file pointer -uint32_t peek_le32(FILE *f) { - uint32_t res = read_le32(f); - fseek(f, -4, SEEK_CUR); - return res; -} - -//! read a 32 bit big-endian value from file -uint32_t read_be32(FILE *f) { - unsigned char t[4]; - fread(t, 4, 1, f); - return (t[0] << 8 | t[1]) << 16 | (t[2] << 8 | t[3]); -} - -//! read a 16 bit little-endian value from file -uint16_t read_le16(FILE *f) { - unsigned char t[2]; - fread(t, 2, 1, f); - return t[1] << 8 | t[0]; -} - -//! read a 16 bit big-endian value from file -uint16_t read_be16(FILE *f) { - unsigned char t[2]; - fread(t, 2, 1, f); - return t[0] << 8 | t[1]; -} - /** * \brief append a new entry to a file list * \param list file list to append to Modified: trunk/extractor/helpers.h =================================================================== --- trunk/extractor/helpers.h 2008-08-22 16:03:53 UTC (rev 87) +++ trunk/extractor/helpers.h 2008-08-22 16:04:22 UTC (rev 88) @@ -1,11 +1,42 @@ #ifndef HELPERS_H #define HELPERS_H char *read_cstring(FILE *f); -uint16_t read_le16(FILE *f); -uint32_t read_le32(FILE *f); -uint32_t peek_le32(FILE *f); -uint32_t read_be32(FILE *f); -uint16_t read_be16(FILE *f); + +//! read a 32 bit little-endian value from file +static inline uint32_t read_le32(FILE *f) { + unsigned char t[4]; + fread(t, 4, 1, f); + return (t[3] << 8 | t[2]) << 16 | (t[1] << 8 | t[0]); +} + +//! as read_le32 but do not advance file pointer +static inline uint32_t peek_le32(FILE *f) { + uint32_t res = read_le32(f); + fseek(f, -4, SEEK_CUR); + return res; +} + +//! read a 32 bit big-endian value from file +static inline uint32_t read_be32(FILE *f) { + unsigned char t[4]; + fread(t, 4, 1, f); + return (t[0] << 8 | t[1]) << 16 | (t[2] << 8 | t[3]); +} + +//! read a 16 bit little-endian value from file +static inline uint16_t read_le16(FILE *f) { + unsigned char t[2]; + fread(t, 2, 1, f); + return t[1] << 8 | t[0]; +} + +//! read a 16 bit big-endian value from file +static inline uint16_t read_be16(FILE *f) { + unsigned char t[2]; + fread(t, 2, 1, f); + return t[0] << 8 | t[1]; +} + int fcopy(FILE *in, FILE *out, int len); #define TAG(a, b, c, d) ((uint32_t)((a) << 8 | (b)) << 16 | ((c) << 8 | (d))) #define HUGETAG(a, b, c, d, e, f, g, h) (((uint64_t)(TAG(a, b, c, d)) << 32) | TAG(e, f, g, h)) Modified: trunk/extractor/solid.c =================================================================== --- trunk/extractor/solid.c 2008-08-22 16:03:53 UTC (rev 87) +++ trunk/extractor/solid.c 2008-08-22 16:04:22 UTC (rev 88) @@ -60,7 +60,7 @@ return "bin"; } -static int read_block_header(FILE *in, int *lang, int *type, uint32_t *len) { +static inline int read_block_header(FILE *in, int *lang, int *type, uint32_t *len) { *lang = read_be16(in); *type = read_be16(in); *len = read_be32(in); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:03:59
|
Revision: 87 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=87&view=rev Author: someone-guy Date: 2008-08-22 16:03:53 +0000 (Fri, 22 Aug 2008) Log Message: ----------- NWN2 support, hopefully more reliable type detection Modified Paths: -------------- trunk/extractor/nwn.c Modified: trunk/extractor/nwn.c =================================================================== --- trunk/extractor/nwn.c 2008-08-22 16:03:31 UTC (rev 86) +++ trunk/extractor/nwn.c 2008-08-22 16:03:53 UTC (rev 87) @@ -24,12 +24,14 @@ static file_t *get_list(FILE *in) { file_t *list; uint32_t count, namepos, tblpos; + int version = 0; int namelen = 16; int i; char sig[9] = {0}; rewind(in); fread(sig, 8, 1, in); - if (strcmp(sig, "MOD V1.1") == 0) namelen = 32; + if (strcmp(sig, "MOD V1.1") == 0) version = 1; + if (version) namelen = 32; fseek(in, 0x10, SEEK_SET); count = read_le32(in); if (count > MAX_FILES) count = MAX_FILES; @@ -48,20 +50,40 @@ fseek(in, tblpos + 8 * i, SEEK_SET); list[i].start = read_le32(in); list[i].len = read_le32(in); - if (type_id == 0x7d9) // script source - strcat(list[i].name, ".nss"); - else { // generate extension from content start - char *ptr = &list[i].name[strlen(list[i].name)]; - fseek(in, list[i].start, SEEK_SET); - *ptr++ = '.'; - fread(ptr, 3, 1, in); - *ptr = tolower(*ptr); - ptr++; - *ptr = tolower(*ptr); - ptr++; - *ptr = tolower(*ptr); - ptr++; - *ptr = 0; + switch (type_id) { + case 0x07d9: // script source + strcat(list[i].name, ".nss"); + break; + case 0x0bcd: // visual sourcesafe stuff?? + strcat(list[i].name, ".vss"); + break; + case 0x0000: + case 0x0bc1: + case 0x0bc3: + case 0x0bca: + case 0x0bbe: + case 0x0bbf: // effect xml files? + strcat(list[i].name, ".xml"); + break; + case 0x0003: // act start image + strcat(list[i].name, ".img"); + break; + default: + { + // generate extension from content start + char *ptr = &list[i].name[strlen(list[i].name)]; + fseek(in, list[i].start, SEEK_SET); + *ptr++ = '.'; + fread(ptr, 3, 1, in); + *ptr = tolower(*ptr); + ptr++; + *ptr = tolower(*ptr); + ptr++; + *ptr = tolower(*ptr); + ptr++; + *ptr = 0; + break; + } } } return list; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:03:33
|
Revision: 86 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=86&view=rev Author: someone-guy Date: 2008-08-22 16:03:31 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Partial support for NWN2 data files Modified Paths: -------------- trunk/extractor/nwn.c Modified: trunk/extractor/nwn.c =================================================================== --- trunk/extractor/nwn.c 2008-08-22 16:03:12 UTC (rev 85) +++ trunk/extractor/nwn.c 2008-08-22 16:03:31 UTC (rev 86) @@ -13,18 +13,23 @@ #include "formats.h" #include "helpers.h" -//! check for nwn archive (starts with MOD V1.0) +//! check for nwn archive (starts with MOD V1.0 or MOD V1.1 for NWN2) static int check_file(FILE *in) { char sig[9] = {0}; rewind(in); fread(sig, 8, 1, in); - return strcmp(sig, "MOD V1.0") == 0; + return strcmp(sig, "MOD V1.0") == 0 || strcmp(sig, "MOD V1.1") == 0; } static file_t *get_list(FILE *in) { file_t *list; uint32_t count, namepos, tblpos; + int namelen = 16; int i; + char sig[9] = {0}; + rewind(in); + fread(sig, 8, 1, in); + if (strcmp(sig, "MOD V1.1") == 0) namelen = 32; fseek(in, 0x10, SEEK_SET); count = read_le32(in); if (count > MAX_FILES) count = MAX_FILES; @@ -34,10 +39,10 @@ list = calloc(count + 1, sizeof(file_t)); for (i = 0; i < count; i++) { uint32_t type_id; - fseek(in, namepos + 24 * i, SEEK_SET); - list[i].name = calloc(1, 21); - fread(list[i].name, 16, 1, in); - list[i].name[16] = 0; + fseek(in, namepos + (namelen + 8) * i, SEEK_SET); + list[i].name = calloc(1, namelen + 5); + fread(list[i].name, namelen, 1, in); + list[i].name[namelen] = 0; read_le32(in); // file number type_id = read_le32(in); fseek(in, tblpos + 8 * i, SEEK_SET); @@ -63,8 +68,8 @@ } const fmt_desc_t nwn_fmt = { - "Neverwinter Nights", - "Neverwinter Nights (*.mod;*.nwm;*.sav)", + "Neverwinter Nights (1/2)", + "Neverwinter Nights (1/2) (*.mod;*.nwm;*.sav)", "*.mod;*.nwm;*.sav", check_file, get_list, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:03:13
|
Revision: 85 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=85&view=rev Author: someone-guy Date: 2008-08-22 16:03:12 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Print more information in text-mode list like file size and offset. Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:02:52 UTC (rev 84) +++ trunk/extractor/extractor.c 2008-08-22 16:03:12 UTC (rev 85) @@ -294,7 +294,10 @@ } if (list_files) { file_t *f = flist; - while(f->name) { printf("%s\n", f->name); f++; }; + while(f->name) { + printf("%12"PRId64" 0x%012"PRIx64" %c %s\n", f->len, f->start, f->compressed ? 'c' : ' ', f->name); + f++; + }; return 0; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:02:56
|
Revision: 84 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=84&view=rev Author: someone-guy Date: 2008-08-22 16:02:52 +0000 (Fri, 22 Aug 2008) Log Message: ----------- More advanced argument parsing. Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:02:26 UTC (rev 83) +++ trunk/extractor/extractor.c 2008-08-22 16:02:52 UTC (rev 84) @@ -161,7 +161,6 @@ fmt = &generic_fmt; cur_fmt = fmt; flist = cur_fmt->get_list(input_file); - set_treeview(flist); return 1; } @@ -186,6 +185,7 @@ goto err_out; } g_free(fname); + set_treeview(flist); return; err_out: @@ -245,6 +245,10 @@ gtk_window_present(GTK_WINDOW(preview_win)); } +static void print_help(void) { + fprintf(stderr, _("Usage: extractor [--|-h|-l] [filename]\n")); +} + int main(int argc, char *argv[]) { int i; GtkWidget *window; @@ -257,7 +261,44 @@ GtkTreeViewColumn *column; GtkCellRenderer *renderer; int row = 0, col = 0; + int list_files = 0; + if (argc > 1) { + int pos = 1; + if (argv[pos][0] == '-') { + if (strlen(argv[pos]) == 2) { + switch (argv[pos][1]) { + case 'l': + list_files = 1; + break; + case '-': + break; + case 'h': + default: + print_help(); + return argc > pos + 1 || argv[pos][1] != 'h'; + } + pos++; + } else { + print_help(); + return 1; + } + } + if (argc <= pos) { + fprintf(stderr, _("Missing filename argument\n")); + return 1; + } + if (!open_file(argv[pos], NULL)) { + fprintf(stderr, _("Could not open file %s\n"), argv[pos]); + return 1; + } + if (list_files) { + file_t *f = flist; + while(f->name) { printf("%s\n", f->name); f++; }; + return 0; + } + } + gtk_disable_setlocale(); gtk_init(&argc, &argv); @@ -365,8 +406,7 @@ gtk_window_set_default_size(GTK_WINDOW(window), -1, 400); gtk_widget_show_all(window); - if (argc > 1) - open_file(argv[1], NULL); + set_treeview(flist); gtk_main(); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:02:29
|
Revision: 83 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=83&view=rev Author: someone-guy Date: 2008-08-22 16:02:26 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Change code to implicitly check N_COLS. Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:02:06 UTC (rev 82) +++ trunk/extractor/extractor.c 2008-08-22 16:02:26 UTC (rev 83) @@ -48,7 +48,7 @@ }; //! types of columns in the file list table -static const GType coltypes[] = { +static const GType coltypes[N_COLS] = { [FNAME_COL] = G_TYPE_STRING, [SIZE_COL] = G_TYPE_UINT64, [OFFSET_COL] = G_TYPE_UINT64, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:02:08
|
Revision: 82 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=82&view=rev Author: someone-guy Date: 2008-08-22 16:02:06 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Make globals file-local (static), use proper GType instead of int type. Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-08-22 16:01:44 UTC (rev 81) +++ trunk/extractor/extractor.c 2008-08-22 16:02:06 UTC (rev 82) @@ -17,7 +17,7 @@ #include "formats.h" //! brief NULL-terminated array of supported formats -const fmt_desc_t * const fmts[] = { +static const fmt_desc_t * const fmts[] = { &bloodrayne_fmt, &generic_fmt, &homeworld2_fmt, @@ -48,7 +48,7 @@ }; //! types of columns in the file list table -const int coltypes[] = { +static const GType coltypes[] = { [FNAME_COL] = G_TYPE_STRING, [SIZE_COL] = G_TYPE_UINT64, [OFFSET_COL] = G_TYPE_UINT64, @@ -56,13 +56,13 @@ [PTR_COL] = G_TYPE_POINTER, }; -GtkWidget *dir_button; -GtkListStore *gflist; -GtkWidget *treeview; -GtkTreeSelection *selection; -FILE *input_file = NULL; -file_t *flist = NULL; -const fmt_desc_t *cur_fmt = NULL; +static GtkWidget *dir_button; +static GtkListStore *gflist; +static GtkWidget *treeview; +static GtkTreeSelection *selection; +static FILE *input_file = NULL; +static file_t *flist = NULL; +static const fmt_desc_t *cur_fmt = NULL; /** * \brief extracts the file specified by iter This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-08-22 16:01:46
|
Revision: 81 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=81&view=rev Author: someone-guy Date: 2008-08-22 16:01:44 +0000 (Fri, 22 Aug 2008) Log Message: ----------- Fix speed problems related to updating the file list. Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-05-23 17:48:15 UTC (rev 80) +++ trunk/extractor/extractor.c 2008-08-22 16:01:44 UTC (rev 81) @@ -58,6 +58,7 @@ GtkWidget *dir_button; GtkListStore *gflist; +GtkWidget *treeview; GtkTreeSelection *selection; FILE *input_file = NULL; file_t *flist = NULL; @@ -99,8 +100,16 @@ g_free(path); } +static void set_treeview_model(GtkTreeView *view, GtkTreeModel *model) { + GtkTreeModel *sort = gtk_tree_model_sort_new_with_model(model); + gtk_tree_view_set_model(view, sort); + g_object_unref(sort); +} + static void clear_treeview() { + gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); gtk_list_store_clear(gflist); + set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); } /** @@ -111,14 +120,19 @@ */ static void set_treeview(file_t *list) { GtkTreeIter iter; - clear_treeview(); - if (!list) return; + if (!list) { + clear_treeview(); + return; + } + gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); + gtk_list_store_clear(gflist); while (list->name) { gtk_list_store_append(gflist, &iter); gtk_list_store_set(gflist, &iter, FNAME_COL, list->name, SIZE_COL, list->len, OFFSET_COL, list->start, COMPR_COL, list->compressed, PTR_COL, list, -1); list++; } + set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); } static int open_file(const char *fname, const fmt_desc_t *fmt) { @@ -239,11 +253,9 @@ GtkWidget *file_button; GtkWidget *button; GtkWidget *scrollwin; - GtkWidget *treeview; GtkWidget *lbl; GtkTreeViewColumn *column; GtkCellRenderer *renderer; - GtkTreeModel *sort; int row = 0, col = 0; gtk_disable_setlocale(); @@ -268,8 +280,8 @@ (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); gflist = gtk_list_store_new(N_COLS, coltypes[0], coltypes[1], coltypes[2], coltypes[3], coltypes[4]); - sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(gflist)); - treeview = gtk_tree_view_new_with_model(sort); + treeview = gtk_tree_view_new(); + set_treeview_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(gflist)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE); renderer = gtk_cell_renderer_text_new(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-05-23 17:48:23
|
Revision: 80 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=80&view=rev Author: someone-guy Date: 2008-05-23 10:48:15 -0700 (Fri, 23 May 2008) Log Message: ----------- Add empty lines for better readability Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-05-23 17:48:07 UTC (rev 79) +++ trunk/extractor/extractor.c 2008-05-23 17:48:15 UTC (rev 80) @@ -271,26 +271,31 @@ sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(gflist)); treeview = gtk_tree_view_new_with_model(sort); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE); + renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer, "text", FNAME_COL, NULL); gtk_tree_view_column_set_sort_column_id(column, FNAME_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Size"), renderer, "text", SIZE_COL, NULL); gtk_tree_view_column_set_sort_column_id(column, SIZE_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Offset"), renderer, "text", OFFSET_COL, NULL); gtk_tree_view_column_set_sort_column_id(column, OFFSET_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + renderer = gtk_cell_renderer_toggle_new(); column = gtk_tree_view_column_new_with_attributes(_("Compressed"), renderer, "active", COMPR_COL, NULL); gtk_tree_view_column_set_sort_column_id(column, COMPR_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); g_signal_connect(G_OBJECT(treeview), "row-activated", This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-05-23 17:48:16
|
Revision: 79 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=79&view=rev Author: someone-guy Date: 2008-05-23 10:48:07 -0700 (Fri, 23 May 2008) Log Message: ----------- Add offset column Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-04-06 21:57:14 UTC (rev 78) +++ trunk/extractor/extractor.c 2008-05-23 17:48:07 UTC (rev 79) @@ -41,6 +41,7 @@ enum { FNAME_COL, SIZE_COL, + OFFSET_COL, COMPR_COL, PTR_COL, N_COLS @@ -50,6 +51,7 @@ const int coltypes[] = { [FNAME_COL] = G_TYPE_STRING, [SIZE_COL] = G_TYPE_UINT64, + [OFFSET_COL] = G_TYPE_UINT64, [COMPR_COL] = G_TYPE_BOOLEAN, [PTR_COL] = G_TYPE_POINTER, }; @@ -114,7 +116,7 @@ while (list->name) { gtk_list_store_append(gflist, &iter); gtk_list_store_set(gflist, &iter, FNAME_COL, list->name, - SIZE_COL, list->len, COMPR_COL, list->compressed, PTR_COL, list, -1); + SIZE_COL, list->len, OFFSET_COL, list->start, COMPR_COL, list->compressed, PTR_COL, list, -1); list++; } } @@ -265,7 +267,7 @@ (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); gflist = gtk_list_store_new(N_COLS, coltypes[0], coltypes[1], coltypes[2], - coltypes[3]); + coltypes[3], coltypes[4]); sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(gflist)); treeview = gtk_tree_view_new_with_model(sort); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE); @@ -279,6 +281,11 @@ "text", SIZE_COL, NULL); gtk_tree_view_column_set_sort_column_id(column, SIZE_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Offset"), renderer, + "text", OFFSET_COL, NULL); + gtk_tree_view_column_set_sort_column_id(column, OFFSET_COL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_toggle_new(); column = gtk_tree_view_column_new_with_attributes(_("Compressed"), renderer, "active", COMPR_COL, NULL); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-04-06 21:57:16
|
Revision: 78 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=78&view=rev Author: someone-guy Date: 2008-04-06 14:57:14 -0700 (Sun, 06 Apr 2008) Log Message: ----------- Switch to the much faster GtkListStore (instead of GtkTreeStore). Modified Paths: -------------- trunk/extractor/extractor.c Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-04-06 21:39:31 UTC (rev 77) +++ trunk/extractor/extractor.c 2008-04-06 21:57:14 UTC (rev 78) @@ -55,7 +55,7 @@ }; GtkWidget *dir_button; -GtkTreeStore *ftree; +GtkListStore *gflist; GtkTreeSelection *selection; FILE *input_file = NULL; file_t *flist = NULL; @@ -98,7 +98,7 @@ } static void clear_treeview() { - gtk_tree_store_clear(ftree); + gtk_list_store_clear(gflist); } /** @@ -112,8 +112,8 @@ clear_treeview(); if (!list) return; while (list->name) { - gtk_tree_store_append(ftree, &iter, NULL); - gtk_tree_store_set(ftree, &iter, FNAME_COL, list->name, + gtk_list_store_append(gflist, &iter); + gtk_list_store_set(gflist, &iter, FNAME_COL, list->name, SIZE_COL, list->len, COMPR_COL, list->compressed, PTR_COL, list, -1); list++; } @@ -264,9 +264,9 @@ gtk_table_attach(GTK_TABLE(table), scrollwin, col, col + 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); - ftree = gtk_tree_store_new(N_COLS, coltypes[0], coltypes[1], coltypes[2], + gflist = gtk_list_store_new(N_COLS, coltypes[0], coltypes[1], coltypes[2], coltypes[3]); - sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(ftree)); + sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(gflist)); treeview = gtk_tree_view_new_with_model(sort); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE); renderer = gtk_cell_renderer_text_new(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-04-06 21:39:33
|
Revision: 77 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=77&view=rev Author: someone-guy Date: 2008-04-06 14:39:31 -0700 (Sun, 06 Apr 2008) Log Message: ----------- Also display "file" sizes for Metal Gear vox.dat Modified Paths: -------------- trunk/extractor/solid.c Modified: trunk/extractor/solid.c =================================================================== --- trunk/extractor/solid.c 2008-04-06 21:34:41 UTC (rev 76) +++ trunk/extractor/solid.c 2008-04-06 21:39:31 UTC (rev 77) @@ -67,6 +67,8 @@ return !feof(in); } +static int do_extract(FILE *in, const file_t *file, FILE *outf, uint8_t *outb, int max_size); + static file_t *get_list(FILE *in) { int cnt = 0; file_t *list = calloc(1, sizeof(file_t)); @@ -96,6 +98,8 @@ fseek(in, 8, SEEK_CUR); fseek(in, len - 16, SEEK_CUR); } + for (cnt = 0; list[cnt].name; cnt++) + list[cnt].len = do_extract(in, &list[cnt], NULL, NULL, 0); return list; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-04-06 21:34:43
|
Revision: 76 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=76&view=rev Author: someone-guy Date: 2008-04-06 14:34:41 -0700 (Sun, 06 Apr 2008) Log Message: ----------- Extraction support for Metal Gear vox.dat Modified Paths: -------------- trunk/extractor/solid.c Modified: trunk/extractor/solid.c =================================================================== --- trunk/extractor/solid.c 2008-04-06 20:09:49 UTC (rev 75) +++ trunk/extractor/solid.c 2008-04-06 21:34:41 UTC (rev 76) @@ -60,15 +60,21 @@ return "bin"; } +static int read_block_header(FILE *in, int *lang, int *type, uint32_t *len) { + *lang = read_be16(in); + *type = read_be16(in); + *len = read_be32(in); + return !feof(in); +} + static file_t *get_list(FILE *in) { int cnt = 0; file_t *list = calloc(1, sizeof(file_t)); rewind(in); while (cnt < MAX_FILES) { - int lang = read_be16(in); - int type = read_be16(in); - uint32_t len = read_be32(in); - if (feof(in)) break; + int lang, type; + uint32_t len; + if (!read_block_header(in, &lang, &type, &len)) break; if (type == TYPE_INDEX) { char ext[8]; read_be32(in); // unknown, always 0? @@ -93,6 +99,74 @@ return list; } +//! quick and dirty hack to avoid overflow problems +#define MAX_FILE_SZ (1024*1024*1024) + +static int do_extract(FILE *in, const file_t *file, FILE *outf, uint8_t *outb, int max_size) { + int extract_lang, extract_type; + int lang, type; + int extracted = 0; + int first = 1; + uint32_t len; + uint32_t skip; + if (!outb || max_size > MAX_FILE_SZ) max_size = MAX_FILE_SZ; + fseek(in, file->start, SEEK_SET); + read_block_header(in, &lang, &type, &len); + read_be32(in); + extract_lang = read_be16(in); + extract_type = read_be16(in); + fseek(in, len - 16, SEEK_CUR); + // skip remaining index entries + while (read_block_header(in, &lang, &type, &len) && type == TYPE_INDEX) + fseek(in, len - 8, SEEK_CUR); + while (type != TYPE_INDEX && type != TYPE_PADDING) { + skip = len - 8; + if (lang == extract_lang && type == extract_type) { + skip = 0; + len -= 16; + if (type == TYPE_AUDIO) { + uint32_t data_len; + read_be32(in); + data_len = read_be32(in); + if (data_len > len) data_len = len; + + // first packet does not contain any data useful to us + if (first) data_len = 0; + first = 0; + + skip = len - data_len; + len = data_len; + } else + fseek(in, 8, SEEK_CUR); + + // some sanity checks + if (extracted >= max_size || len > max_size) break; + if (extracted + len > max_size) len = max_size - extracted; + + // read data part + if (outf) fcopy(in, outf, len); + else if (outb) { + fread(outb, 1, len, in); + outb += len; + } else + fseek(in, len, SEEK_CUR); + extracted += len; + } + fseek(in, skip, SEEK_CUR); + if (!read_block_header(in, &lang, &type, &len)) + break; + } + return extracted; +} + +static int extract_file(FILE *in, const file_t *file, FILE *out) { + return do_extract(in, file, out, NULL, 0); +} + +static int extract_mem(FILE *in, const file_t *file, uint8_t *out, int size) { + return do_extract(in, file, NULL, out, size); +} + const fmt_desc_t solid_fmt = { "MetalGear Solid: TS", "MetalGear Solid: TS (vox.dat)", @@ -100,6 +174,6 @@ check_file, get_list, default_free_list, - default_extract_file, - default_extract_mem, + extract_file, + extract_mem, }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <som...@us...> - 2008-04-06 20:09:59
|
Revision: 75 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=75&view=rev Author: someone-guy Date: 2008-04-06 13:09:49 -0700 (Sun, 06 Apr 2008) Log Message: ----------- Add parsing support for Metal Gear Solid: The Twin Snakes vox.dat file Modified Paths: -------------- trunk/extractor/Makefile trunk/extractor/extractor.c trunk/extractor/formats.h Added Paths: ----------- trunk/extractor/solid.c Modified: trunk/extractor/Makefile =================================================================== --- trunk/extractor/Makefile 2008-04-06 20:09:20 UTC (rev 74) +++ trunk/extractor/Makefile 2008-04-06 20:09:49 UTC (rev 75) @@ -9,6 +9,7 @@ homeworld2.c \ nwn.c \ pak.c \ + solid.c \ wad.c \ xtre.c \ Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2008-04-06 20:09:20 UTC (rev 74) +++ trunk/extractor/extractor.c 2008-04-06 20:09:49 UTC (rev 75) @@ -23,6 +23,7 @@ &homeworld2_fmt, &nwn_fmt, &pak_fmt, + &solid_fmt, &wad_fmt, &xtre_fmt, NULL Modified: trunk/extractor/formats.h =================================================================== --- trunk/extractor/formats.h 2008-04-06 20:09:20 UTC (rev 74) +++ trunk/extractor/formats.h 2008-04-06 20:09:49 UTC (rev 75) @@ -30,6 +30,7 @@ extern const fmt_desc_t homeworld2_fmt; extern const fmt_desc_t nwn_fmt; extern const fmt_desc_t pak_fmt; +extern const fmt_desc_t solid_fmt; extern const fmt_desc_t wad_fmt; extern const fmt_desc_t xtre_fmt; Added: trunk/extractor/solid.c =================================================================== --- trunk/extractor/solid.c (rev 0) +++ trunk/extractor/solid.c 2008-04-06 20:09:49 UTC (rev 75) @@ -0,0 +1,105 @@ +/** + * \file solid.c + * \brief routines for handling the GameCube Metal Gear Solid: Twin Snakes vox.dat format + * + * Copyright (C) 2008 Reimar Döffinger + * License: GPL v2 (see LICENSE file) + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include "formats.h" +#include "helpers.h" + +//! this is only a heuristic check, hopefully it is reliable enough +static int check_file(FILE *in) { + rewind(in); + return read_be32(in) == 0x10 && read_be32(in) == 0x10 && read_be32(in) == 0; +} + +enum { + LANG_ANY, + LANG_EN, + LANG_FR, + LANG_DE, + LANG_IT, + LANG_ES, +}; + +static const char *langstr(int lang) { + switch (lang) { + case LANG_ANY: return ""; + case LANG_EN : return "en"; + case LANG_FR : return "fr"; + case LANG_DE : return "de"; + case LANG_IT : return "it"; + case LANG_ES : return "es"; + } + return "nn"; +} + +enum { + TYPE_AUDIO = 0x01, + TYPE_SUB = 0x04, + TYPE_T6 = 0x06, // subtitle references? (unsure) + TYPE_T7 = 0x07, + TYPE_INDEX = 0x10, + TYPE_PADDING = 0xf0, +}; + +static const char *typestr(int type) { + switch (type) { + case TYPE_AUDIO : return "ogg"; + case TYPE_SUB : return "sub"; + case TYPE_T6 : return "t6"; + case TYPE_T7 : return "t7"; + case TYPE_INDEX : return "idx"; // should never be used + case TYPE_PADDING: return "pad"; // should not be used either + } + return "bin"; +} + +static file_t *get_list(FILE *in) { + int cnt = 0; + file_t *list = calloc(1, sizeof(file_t)); + rewind(in); + while (cnt < MAX_FILES) { + int lang = read_be16(in); + int type = read_be16(in); + uint32_t len = read_be32(in); + if (feof(in)) break; + if (type == TYPE_INDEX) { + char ext[8]; + read_be32(in); // unknown, always 0? + lang = read_be16(in); + type = read_be16(in); + if (*langstr(lang)) + snprintf(ext, sizeof(ext), "%s.%s", langstr(lang), typestr(type)); + else + snprintf(ext, sizeof(ext), "%s", typestr(type)); + add_entry(&list, cnt, ext); + list[cnt].start = ftell(in) - 16; + cnt++; + } else if (type == TYPE_PADDING) { + uint64_t pos = ftell(in); + len = 16; // should be already 16, just to be sure + pos = (pos + 0x800) & ~0x7ff; + fseek(in, pos, SEEK_SET); + } else + fseek(in, 8, SEEK_CUR); + fseek(in, len - 16, SEEK_CUR); + } + return list; +} + +const fmt_desc_t solid_fmt = { + "MetalGear Solid: TS", + "MetalGear Solid: TS (vox.dat)", + "vox.dat", + check_file, + get_list, + default_free_list, + default_extract_file, + default_extract_mem, +}; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |