Hi!
I have now produced a patch of my currently done work.
The patch compiles for me, but I've nothing tested yet, so be beware.
I post it, because I want have some comments about it.
Then I will hack on.
Christoph Egger
E-Mail: [EMAIL PROTECTED]
Binary files 20000130/degas/lib/libggi/display/file/.libs/file.so and
degas/lib/libggi/display/file/.libs/file.so differ
diff -uNr 20000130/degas/lib/libggi/display/file/fileio.c
degas/lib/libggi/display/file/fileio.c
--- 20000130/degas/lib/libggi/display/file/fileio.c Tue Apr 13 07:07:28 1999
+++ degas/lib/libggi/display/file/fileio.c Wed Feb 2 20:44:56 2000
@@ -36,8 +36,21 @@
#include <ggi/internal/ggi-dl.h>
#include <ggi/display/file.h>
+#include <ggi/system.h>
+
+struct file_type_op_t file_type[] =
+{
+ { "ppm", _ggi_file_detect_ppm, NULL, _ggi_file_ppm_write },
+ { "bmp", _ggi_file_detect_bmp, _ggi_file_bmp_read, NULL },
+ { NULL, NULL, NULL, NULL }
+};
+
+
+
+/* common primitives */
+
int _ggi_file_create_file(ggi_visual *vis, char *filename)
{
FileHook *ff = FILE_PRIV(vis);
@@ -85,6 +98,87 @@
ff->buf_len = 0;
}
+/* Read primitives */
+
+void _ggi_file_read_byte(ggi_visual *vis, int *val)
+{
+ FileHook *ff = FILE_PRIV(vis);
+
+#if 0
+ if (ff->buf_len > 0) {
+ (uint8) val = ff->buffer[ff->buf_len++];
+ return;
+ }
+
+ if ((ff->buf_len = read(LIBGGI_FD(vis), ff->buffer, FILE_BUFFER_SIZE) < 0) {
+ perror("display-file: read error");
+ }
+
+ if (ff->buf_len < FILE_BUFFER_SIZE) {
+ /* FIXME: eof is reached */
+ }
+#else
+
+ if ((ff->buf_len = read(LIBGGI_FD(vis), ff->buffer, 1)) < 0) {
+ perror("display-file: read error");
+ }
+
+ if (ff->buf_len == 0) {
+ /* FIXME: eof is reached */
+ }
+
+ (uint8)(*val) = (uint8)(ff->buffer[0]);
+#endif
+}
+
+void _ggi_file_read_word(ggi_visual *vis, int *val)
+{
+#ifdef GGI_LITTLE_ENDIAN
+ _ggi_file_read_byte(vis, (int*)(val) );
+ _ggi_file_read_byte(vis, (int*)(val+1) );
+#else
+ _ggi_file_read_byte(vis, (int*)(val+1) );
+ _ggi_file_read_byte(vis, (int*)(val) );
+#endif
+}
+
+void _ggi_file_read_longword(ggi_visual *vis, long *val)
+{
+#ifdef GGI_LITTLE_ENDIAN
+ _ggi_file_read_word(vis, (int*)(val) );
+ _ggi_file_read_word(vis, (int*)(val+2) );
+#else
+ _ggi_file_read_word(vis, (int*)(val+2) );
+ _ggi_file_read_word(vis, (int*)(val) );
+#endif
+}
+
+void _ggi_file_read_string(ggi_visual *vis, char *str, int strlen)
+{
+ for (; strlen > 0; strlen--) {
+ _ggi_file_read_byte(vis, (int*)(str));
+ }
+}
+
+void _ggi_file_read_zeros(ggi_visual *vis, int count)
+{
+ FileHook *ff = FILE_PRIV(vis);
+
+ if ((ff->buf_len + count) >= FILE_BUFFER_SIZE) {
+ count = (ff->buf_len + count) - FILE_BUFFER_SIZE;
+
+ /* FIXME: Is it that, what I should do here? */
+ }
+
+ for (; count > 0; count--) {
+ ff->buffer[ff->buf_len++] = 0;
+ }
+}
+
+
+
+/* Write primitives */
+
void _ggi_file_write_byte(ggi_visual *vis, int val)
{
FileHook *ff = FILE_PRIV(vis);
@@ -99,8 +193,24 @@
void _ggi_file_write_word(ggi_visual *vis, int val)
{
+#ifdef GGI_LITTLE_ENDIAN
_ggi_file_write_byte(vis, val >> 8);
_ggi_file_write_byte(vis, val & 0xff);
+#else
+ _ggi_file_write_byte(vis, val & 0xff);
+ _ggi_file_write_byte(vis, val >> 8);
+#endif
+}
+
+void _ggi_file_write_longword(ggi_visual *vis, long val)
+{
+#ifdef GGI_LITTLE_ENDIAN
+ _ggi_file_write_word(vis, val >> 16);
+ _ggi_file_write_word(vis, val & 0xffff);
+#else
+ _ggi_file_write_word(vis, val & 0xffff);
+ _ggi_file_write_word(vis, val >> 16);
+#endif
}
void _ggi_file_write_string(ggi_visual *vis, char *str)
@@ -116,3 +226,31 @@
_ggi_file_write_byte(vis, 0);
}
}
+
+
+/* some helpers */
+
+
+/* _ggi_file_get_extension:
+ * When passed a complete filename (with or without path information)
+ * this returns a pointer to the file extension.
+ */
+char *_ggi_file_get_extension(char *filename)
+{
+ int pos, end;
+
+ pos = end = strlen(filename);
+
+ while ((pos > 0)
+ && (filename[pos - 1] != '.')
+ && (filename[pos - 1] != '/')
+ && (filename[pos - 1] != '\0')
+ && (filename[pos - 1] != '#'))
+ pos--;
+
+ if (filename[pos - 1] == '.')
+ return filename + pos;
+
+ return filename + end;
+}
+
diff -uNr 20000130/degas/lib/libggi/display/file/mode.c
degas/lib/libggi/display/file/mode.c
--- 20000130/degas/lib/libggi/display/file/mode.c Mon Dec 13 07:10:45 1999
+++ degas/lib/libggi/display/file/mode.c Wed Feb 2 20:47:15 2000
@@ -46,11 +46,19 @@
#define MAP_FAILED ((void*)-1)
#endif
-#define write_byte _ggi_file_write_byte
-#define write_word _ggi_file_write_word
-#define write_string _ggi_file_write_string
-#define write_zeros _ggi_file_write_zeros
-#define write_flush _ggi_file_flush
+#define write_byte _ggi_file_write_byte
+#define write_word _ggi_file_write_word
+#define write_longword _ggi_file_write_longword
+#define write_string _ggi_file_write_string
+#define write_zeros _ggi_file_write_zeros
+#define write_flush _ggi_file_flush
+
+#define read_byte _ggi_file_read_byte
+#define read_word _ggi_file_read_word
+#define read_longword _ggi_file_read_longword
+#define read_string _ggi_file_read_string
+#define read_zeros _ggi_file_read_zeros
+
static void dowritefile(ggi_visual *vis)
{
@@ -59,7 +67,7 @@
if (!(ff->flags & FILEFLAG_RAW)) {
_ggi_file_rewind(vis);
- (* ff->writer)(vis);
+ (* ff->file_op->writer)(vis);
}
sprintf(cmdbuf,ff->flushcmd,
@@ -364,7 +372,7 @@
/* This is where we write the non-raw file */
_ggi_file_rewind(vis);
- (* ff->writer)(vis);
+ (* ff->file_op->writer)(vis);
free((void *)ff->fb_ptr);
}
diff -uNr 20000130/degas/lib/libggi/display/file/ppm.c
degas/lib/libggi/display/file/ppm.c
--- 20000130/degas/lib/libggi/display/file/ppm.c Fri Dec 18 22:36:22 1998
+++ degas/lib/libggi/display/file/ppm.c Wed Feb 2 20:48:13 2000
@@ -40,13 +40,8 @@
int _ggi_file_ppm_detect(char *filename)
{
- int len = strlen(filename);
-
- if (len < 5) {
- return 0;
- }
-
- return (strcmp(filename + (len-4), ".ppm") == 0);
+ return ((file_type[FILE_PPM].ext) &&
+ (strcmp(file_type[FILE_PPM].ext, _ggi_file_get_extension(filename)) ==
+0));
}
void _ggi_file_ppm_write(ggi_visual *vis)
diff -uNr 20000130/degas/lib/libggi/display/file/visual.c
degas/lib/libggi/display/file/visual.c
--- 20000130/degas/lib/libggi/display/file/visual.c Sat Jan 30 07:08:17 1999
+++ degas/lib/libggi/display/file/visual.c Wed Feb 2 21:11:43 2000
@@ -33,18 +33,27 @@
#include <ggi/internal/ggi-dl.h>
#include <ggi/display/file.h>
-#define NUM_OPTS 3
-static gg_option file_options[NUM_OPTS] =
+#define NUM_OPTS (sizeof(file_options)/sizeof(gg_option))
+
+static gg_option file_options[] =
{
{ "flushcmd", "" },
{ "flushframe", "0" },
- { "flushtime", "0.0" }
+ { "flushtime", "0.0" },
+ { "command", "" }
};
int GGIdlinit(ggi_visual *vis, const char *args,void *argptr)
{
FileHook *ff;
double fltime;
+
+#define FALSE 0
+#define TRUE !FALSE
+
+
+ int nothing_detect = TRUE;
+ int i;
LIBGGI_FD(vis) = -1;
@@ -62,7 +71,7 @@
LIBGGI_GC(vis) = _ggi_malloc(sizeof(ggi_gc));
ff->flags = 0;
- ff->writer = (file_writer_func *) NULL;
+ ff->file_op = file_type;
ff->fb_ptr = ff->file_mmap = NULL;
/* handle arguments */
@@ -95,11 +104,40 @@
gettimeofday(&ff->flushlast,NULL);
ff->flushstep.tv_sec = fltime;
ff->flushstep.tv_usec = (fltime-ff->flushstep.tv_sec)*1000000;
-
-
- if (_ggi_file_ppm_detect(ff->filename)) {
- ff->writer = &_ggi_file_ppm_write;
- } else {
+
+ ff->command = file_options[3].result[0] ? atoi(file_options[3].result) :
+FILECMD_NOTHING;
+
+ for_each_file_type(i) {
+ if (ff->file_op[i].detect(ff->filename)) {
+ switch (ff->command) {
+ case FILECMD_READ:
+ if (!ff->file_op[i].reader) {
+ perror("display-file: loading of this
+file-format is not supported yet.\n");
+ return -1;
+ }
+ nothing_detect = FALSE;
+ break;
+
+ case FILECMD_WRITE:
+ if (!ff->file_op[i].writer) {
+ perror("display-file: saving of this
+file-format is not supported yet.\n");
+ return -1;
+ }
+ nothing_detect = FALSE;
+ break;
+
+ case FILECMD_NOTHING:
+ perror("display-file: no given command, if
+file should be read or written.\n");
+ return -1;
+
+ default:
+ perror("display-file: unknown command.\n");
+ return -1;
+ }
+ }
+ }
+
+ if (nothing_detect == FALSE) {
ff->flags |= FILEFLAG_RAW;
}
@@ -111,6 +149,10 @@
vis->opdisplay->setflags=GGI_file_setflags;
return GGI_DL_OPDISPLAY;
+
+#undef TRUE
+#undef FALSE
+
}
int GGIdlcleanup(ggi_visual *vis)
diff -uNr 20000130/degas/lib/libggi/include/ggi/display/file.h
degas/lib/libggi/include/ggi/display/file.h
--- 20000130/degas/lib/libggi/include/ggi/display/file.h Tue Jan 19 07:07:25
1999
+++ degas/lib/libggi/include/ggi/display/file.h Wed Feb 2 21:12:15 2000
@@ -30,9 +30,37 @@
#include <ggi/internal/ggi-dl.h>
+typedef struct file_type_op_t {
+ char *ext; /* i.e. "ppm", "bmp", "pcx" ... */
+ int (*detect)(char *filename);
+ int (*reader)(ggi_visual *vis);
+ void (*writer)(ggi_visual *vis);
+} file_type_op_t;
+
+
+#if 0
+
+/* FIXME: compiler fails on using this with: "sizeof applied to an incomplete type"
+*/
+#define NUM_FILE_TYPES (sizeof(file_type) / sizeof(struct file_type_op_t))
+
+#else
+
+#define NUM_FILE_TYPES 2
+
+#endif
+
+#define FILE_PPM 0
+#define FILE_BMP 1
+
+
+extern struct file_type_op_t file_type[];
+
+
+#define for_each_file_type(f) \
+ for (f = 0; f < NUM_FILE_TYPES; f++)
+
+
-typedef int (file_detect_func)(char *filename);
-typedef void (file_writer_func)(ggi_visual *vis);
#define FILE_BUFFER_SIZE 1024
@@ -43,7 +71,12 @@
char *filename;
- file_writer_func *writer;
+ int command; /* read or write ? */
+#define FILECMD_NOTHING 0
+#define FILECMD_READ 1
+#define FILECMD_WRITE 2
+
+ struct file_type_op_t *file_op; /* file_operands */
int fb_size;
int fb_stride;
@@ -86,18 +119,38 @@
extern void _ggi_file_close_file(ggi_visual *vis);
extern void _ggi_file_rewind(ggi_visual *vis);
extern void _ggi_file_flush(ggi_visual *vis);
+extern char *_ggi_file_get_extension(char *filename);
extern void _ggi_file_write_byte(ggi_visual *vis, int val);
extern void _ggi_file_write_word(ggi_visual *vis, int val);
+extern void _ggi_file_write_longword(ggi_visual *vis, long val);
extern void _ggi_file_write_string(ggi_visual *vis, char *str);
extern void _ggi_file_write_zeros(ggi_visual *vis, int count);
+extern void _ggi_file_read_byte(ggi_visual *vis, int *val);
+extern void _ggi_file_read_word(ggi_visual *vis, int *val);
+extern void _ggi_file_read_longword(ggi_visual *vis, long *val);
+extern void _ggi_file_read_string(ggi_visual *vis, char *str, int strlen);
+extern void _ggi_file_read_zeros(ggi_visual *vis, int count);
+
+
+/* Image Detectors
+ */
+
+extern int _ggi_file_detect_ppm(char *filename);
+extern int _ggi_file_detect_bmp(char *filename);
-/* Image Writers
+
+/* Image Readers
+ */
+
+extern int _ggi_file_bmp_read(ggi_visual *vis);
+
+
+/* Image Writers
*/
-
-extern file_detect_func _ggi_file_ppm_detect;
-extern file_writer_func _ggi_file_ppm_write;
+
+extern void _ggi_file_ppm_write(ggi_visual *vis);
/* LibGGI Interface