diff --git a/.gitattributes b/.gitattributes index c2640408f57b98d540e1b84f6d4b63c55e6d2a53..9fcdbed783b425bad229893207c15e9b557d1374 100644 --- a/.gitattributes +++ b/.gitattributes @@ -68,37 +68,13 @@ testfont binary /src/modules/_Crypto/pipe.c foreign_ident /src/modules/call_out/call_out.c foreign_ident /src/modules/files/file.c foreign_ident -/src/modules/gdbmmod/gdbmmod.c foreign_ident -/src/modules/gmpmod/mpz_glue.c foreign_ident -/src/modules/image/blit.c foreign_ident -/src/modules/image/dct.c foreign_ident -/src/modules/image/font.c foreign_ident -/src/modules/image/image.c foreign_ident -/src/modules/image/image.h foreign_ident -/src/modules/image/lzw.c foreign_ident -/src/modules/image/lzw.h foreign_ident -/src/modules/image/matrix.c foreign_ident -/src/modules/image/operator.c foreign_ident -/src/modules/image/pattern.c foreign_ident -/src/modules/image/pnm.c foreign_ident -/src/modules/image/quant.c foreign_ident -/src/modules/image/togif.c foreign_ident -/src/modules/mysql/Makefile.in foreign_ident -/src/modules/mysql/acconfig.h foreign_ident -/src/modules/mysql/configure.in foreign_ident -/src/modules/mysql/mysql.c foreign_ident -/src/modules/mysql/precompiled_mysql.h foreign_ident -/src/modules/mysql/result.c foreign_ident -/src/modules/pipe/pipe.c foreign_ident /src/modules/spider/dumudp.c foreign_ident /src/modules/sprintf/sprintf.c foreign_ident -/src/modules/ssleay/ssleay.c foreign_ident /src/modules/system/passwords.c foreign_ident /src/modules/system/syslog.c foreign_ident /src/modules/system/system.c foreign_ident /src/modules/system/system.h foreign_ident /src/modules/system/system_machine.h.in foreign_ident -/src/modules/zlibmod/zlibmod.c foreign_ident /src/object.c foreign_ident /src/operators.c foreign_ident /src/pike_types.c foreign_ident diff --git a/src/modules/gdbmmod/.cvsignore b/src/modules/gdbmmod/.cvsignore deleted file mode 100644 index aad00c7c3e38431b47ce053f2856beef3ae02f9a..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ - -.pure -Makefile -config.log -config.status -configure -dependencies -gdbm_machine.h -linker_options -stamp-h diff --git a/src/modules/gdbmmod/.gitignore b/src/modules/gdbmmod/.gitignore deleted file mode 100644 index 0a44e558401781df0a628ad2fdf403d806f568ba..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ - -/.pure -/Makefile -/config.log -/config.status -/configure -/dependencies -/gdbm_machine.h -/linker_options -/stamp-h diff --git a/src/modules/gdbmmod/Makefile.in b/src/modules/gdbmmod/Makefile.in deleted file mode 100644 index 75379bf80d5b3cbf7a69e307678bdd626a7ca047..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/Makefile.in +++ /dev/null @@ -1,7 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -MODULE_LDFLAGS=@LIBS@ -OBJS=gdbmmod.o - -@static_module_makefile@ -@dependencies@ diff --git a/src/modules/gdbmmod/configure.in b/src/modules/gdbmmod/configure.in deleted file mode 100644 index 1ae3ef7fa67fc824d10a947fd5ab2b5b480c017e..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/configure.in +++ /dev/null @@ -1,15 +0,0 @@ -AC_INIT(gdbmmod.c) -AC_CONFIG_HEADER(gdbm_machine.h) - -AC_ARG_WITH(gdbm, [ --with(out)-gdbm GNU database manager support ],[],[with_gdbm=yes]) - -sinclude(../module_configure.in) - -if test x$with_gdbm = xyes; then - AC_CHECK_HEADERS(gdbm.h) - AC_CHECK_LIB(gdbm, gdbm_open) -fi - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/gdbmmod/gdbm_machine.h.in b/src/modules/gdbmmod/gdbm_machine.h.in deleted file mode 100644 index e0768c6db7f225e501834cd19279e66561c2a6c6..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/gdbm_machine.h.in +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GDBM_MACHINE_H -#define GDBM_MACHINE_H - -/* Define this if you have <gdbm.h> */ -#undef HAVE_GDBM_H - -/* Define this if you have libgdbm */ -#undef HAVE_LIBGDBM - -#endif diff --git a/src/modules/gdbmmod/gdbmmod.c b/src/modules/gdbmmod/gdbmmod.c deleted file mode 100644 index 287eb8231d4b86cf9f8cf5c60d6a5cf1b6aef797..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/gdbmmod.c +++ /dev/null @@ -1,358 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#include "global.h" -RCSID("$Id: gdbmmod.c,v 1.6 1997/02/07 00:42:11 hubbe Exp $"); -#include "gdbm_machine.h" -#include "types.h" -#include "threads.h" - -/* Todo: make sure only one thread accesses the same gdbmmod */ - -#if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM) - -#include "interpret.h" -#include "svalue.h" -#include "stralloc.h" -#include "array.h" -#include "object.h" -#include "macros.h" - -#include <gdbm.h> - -#ifdef _REENTRANT -static MUTEX_T gdbm_lock; -#endif - -struct gdbm_glue -{ - GDBM_FILE dbf; -}; - -#define THIS ((struct gdbm_glue *)(fp->current_storage)) - -static void do_free() -{ - if(THIS->dbf) - { - GDBM_FILE dbf; - dbf=THIS->dbf; - THIS->dbf=0; - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - gdbm_close(dbf); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - } -} - -static int fixmods(char *mods) -{ - int mode; - mode=0; - while(1) - { - switch(*(mods++)) - { - case 0: - switch(mode & 15) - { - default: error("No mode given for gdbm->open()\n"); - case 1|16: - case 1: mode=GDBM_READER; break; - case 3: mode=GDBM_WRITER; break; - case 3|16: mode=GDBM_WRITER | GDBM_FAST; break; - case 7: mode=GDBM_WRCREAT; break; - case 7|16: mode=GDBM_WRCREAT | GDBM_FAST; break; - case 15: mode=GDBM_NEWDB; break; - case 15|16: mode=GDBM_NEWDB | GDBM_FAST; break; - } - return mode; - - case 'r': case 'R': mode|=1; break; - case 'w': case 'W': mode|=3; break; - case 'c': case 'C': mode|=7; break; - case 't': case 'T': mode|=15; break; - case 'f': case 'F': mode|=16; break; - - default: - error("Bad mode flag in gdbm->open.\n"); - } - } -} - -void gdbmmod_fatal(char *err) -{ - error("GDBM: %s\n",err); -} - -static void gdbmmod_create(INT32 args) -{ - struct gdbm_glue *this=THIS; - do_free(); - if(args) - { - GDBM_FILE tmp; - struct pike_string *tmp2; - int rwmode = GDBM_WRCREAT; - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gdbm->create()\n"); - - if(args>1) - { - if(sp[1-args].type != T_STRING) - error("Bad argument 2 to gdbm->create()\n"); - - rwmode=fixmods(sp[1-args].u.string->str); - } - - tmp2=sp[-args].u.string; - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - tmp=gdbm_open(tmp2->str, 512, rwmode, 00666, gdbmmod_fatal); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - - if(!fp->current_object->prog) - { - if(tmp) gdbm_close(tmp); - error("Object destructed in gdbm->open()n"); - } - THIS->dbf=tmp; - - pop_n_elems(args); - if(!THIS->dbf) - error("Failed to open GDBM database.\n"); - } -} - -#define STRING_TO_DATUM(dat, st) dat.dptr=st->str,dat.dsize=st->len; -#define DATUM_TO_STRING(dat) make_shared_binary_string(dat.dptr, dat.dsize) - -static void gdbmmod_fetch(INT32 args) -{ - struct gdbm_glue *this=THIS; - datum key,ret; - - if(!args) - error("Too few arguments to gdbm->fetch()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gdbm->fetch()\n"); - - if(!THIS->dbf) - error("GDBM database not open.\n"); - - STRING_TO_DATUM(key, sp[-args].u.string); - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - ret=gdbm_fetch(this->dbf, key); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - - pop_n_elems(args); - if(ret.dptr) - { - push_string(DATUM_TO_STRING(ret)); - free(ret.dptr); - }else{ - push_int(0); - } -} - -static void gdbmmod_delete(INT32 args) -{ - struct gdbm_glue *this=THIS; - datum key; - int ret; - if(!args) - error("Too few arguments to gdbm->delete()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gdbm->delete()\n"); - - if(!this->dbf) - error("GDBM database not open.\n"); - - STRING_TO_DATUM(key, sp[-args].u.string); - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - ret=gdbm_delete(this->dbf, key); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - - pop_n_elems(args); - push_int(0); -} - -static void gdbmmod_firstkey(INT32 args) -{ - struct gdbm_glue *this=THIS; - datum ret; - pop_n_elems(args); - - if(!this->dbf) error("GDBM database not open.\n"); - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - ret=gdbm_firstkey(this->dbf); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - - if(ret.dptr) - { - push_string(DATUM_TO_STRING(ret)); - free(ret.dptr); - }else{ - push_int(0); - } -} - -static void gdbmmod_nextkey(INT32 args) -{ - struct gdbm_glue *this=THIS; - datum key,ret; - if(!args) - error("Too few arguments to gdbm->nextkey()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gdbm->nextkey()\n"); - - if(!THIS->dbf) - error("GDBM database not open.\n"); - - STRING_TO_DATUM(key, sp[-args].u.string); - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - ret=gdbm_nextkey(this->dbf, key); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - - pop_n_elems(args); - if(ret.dptr) - { - push_string(DATUM_TO_STRING(ret)); - free(ret.dptr); - }else{ - push_int(0); - } -} - -static void gdbmmod_store(INT32 args) -{ - struct gdbm_glue *this=THIS; - datum key,data; - int ret; - if(args<2) - error("Too few arguments to gdbm->store()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gdbm->store()\n"); - - if(sp[1-args].type != T_STRING) - error("Bad argument 2 to gdbm->store()\n"); - - if(!THIS->dbf) - error("GDBM database not open.\n"); - - STRING_TO_DATUM(key, sp[-args].u.string); - STRING_TO_DATUM(data, sp[1-args].u.string); - - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - ret=gdbm_store(this->dbf, key, data, GDBM_REPLACE); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - - if(ret == -1) - error("GDBM database not open for writing.\n"); - - pop_n_elems(args); - push_int(ret == 0); -} - -static void gdbmmod_reorganize(INT32 args) -{ - struct gdbm_glue *this=THIS; - int ret; - pop_n_elems(args); - - if(!THIS->dbf) error("GDBM database not open.\n"); - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - ret=gdbm_reorganize(this->dbf); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - pop_n_elems(args); - push_int(ret); -} - -static void gdbmmod_sync(INT32 args) -{ - struct gdbm_glue *this=THIS; - pop_n_elems(args); - - if(!THIS->dbf) error("GDBM database not open.\n"); - THREADS_ALLOW(); - mt_lock(& gdbm_lock); - gdbm_sync(this->dbf); - mt_unlock(& gdbm_lock); - THREADS_DISALLOW(); - push_int(0); -} - -static void gdbmmod_close(INT32 args) -{ - pop_n_elems(args); - - do_free(THIS->dbf); - push_int(0); -} - -static void init_gdbm_glue(struct object *o) -{ - THIS->dbf=0; -} - -static void exit_gdbm_glue(struct object *o) -{ - do_free(); -} - -#endif - -void pike_module_exit(void) {} - -void pike_module_init(void) -{ -#if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM) - start_new_program(); - add_storage(sizeof(struct gdbm_glue)); - - add_function("create",gdbmmod_create,"function(void|string,void|string:void)",0); - - add_function("close",gdbmmod_close,"function(:void)",0); - add_function("store",gdbmmod_store,"function(string,string:int)",0); - add_function("`[]=",gdbmmod_store,"function(string,string:int)",0); - add_function("fetch",gdbmmod_fetch,"function(string:string)",0); - add_function("`[]",gdbmmod_fetch,"function(string:string)",0); - add_function("delete",gdbmmod_delete,"function(string:int)",0); - add_function("firstkey",gdbmmod_firstkey,"function(:string)",0); - add_function("nextkey",gdbmmod_nextkey,"function(string:string)",0); - add_function("reorganize",gdbmmod_reorganize,"function(:int)",0); - add_function("sync",gdbmmod_sync,"function(:void)",0); - - set_init_callback(init_gdbm_glue); - set_exit_callback(exit_gdbm_glue); - end_class("gdbm"); -#endif -} - diff --git a/src/modules/gdbmmod/testsuite.in b/src/modules/gdbmmod/testsuite.in deleted file mode 100644 index e1ce5f879ba962ce9f3af2068f7eb013214bed84..0000000000000000000000000000000000000000 --- a/src/modules/gdbmmod/testsuite.in +++ /dev/null @@ -1,52 +0,0 @@ -// gdbm -cond( [[ master()->programs["/precompiled/gdbm"] ]], -[[ - define([[GDBM]],[[ (program)"/precompiled/gdbm" ]]) - test_true(programp(GDBM)) - test_do(destruct(clone(GDBM))) - - define([[GDBMTESTS]], - [[ - test_do(rm("test.gdbm")) - test_do(add_efun("GDBMBASE",clone(GDBM,"test.gdbm"))) - test_true(file_stat("test.gdbm")) - - GDBMNULLTEST - test_true(GDBMBASE->store("foo","bar")) - GDBMNULLTEST - test_equal(GDBMBASE->fetch("foo"),"bar") - test_do([[int e; for(e=0;e<100;e++) GDBMBASE->store("x"+e,"y"+e)]]) - GDBMNULLTEST - test_any(int e; for(e=0;e<100;e++) if(GDBMBASE->fetch("x"+e)!="y"+e) return e; return -1,-1) - GDBMNULLTEST - test_true(GDBMBASE->store(sprintf("%'23'100000s","") , sprintf("%'32'100000s",""))) - test_true(GDBMBASE->fetch(sprintf("%'23'100000s",""))==sprintf("%'32'100000s","")) - GDBMNULLTEST - test_equal(GDBMBASE->fetch("foo"),"bar") - test_any(int e; for(e=0;e<100;e++) if(GDBMBASE->fetch("x"+e)!="y"+e) return e; return -1,-1) - test_true(GDBMBASE->fetch(sprintf("%'23'100000s",""))==sprintf("%'32'100000s","")) - test_any(int e; string k; for(k=GDBMBASE->firstkey();k;k=GDBMBASE->nextkey(k)) e++; return e,102) - - test_do(GDBMBASE->sync()) - test_do(GDBMBASE->reorganize()) - test_do(GDBMBASE->close()) - ]]) - - define([[GDBMNULLTEST]],[[ - test_false(GDBMBASE->fetch("slakjdfasdf")) - ]]) - - GDBMTESTS - - define([[GDBMNULLTEST]],[[ - test_false(GDBMBASE->fetch("slakjdfasdf")) - test_do(GDBMBASE->reorganize()) - test_do(GDBMBASE->sync()) - test_do(GDBMBASE->close()) - test_do(GDBMBASE->create("test.gdbm")) - ]]) - - GDBMTESTS - - test_do(rm("test.gdbm")) -]]) diff --git a/src/modules/gmpmod/.cvsignore b/src/modules/gmpmod/.cvsignore deleted file mode 100644 index 86d2c454d78b5f6cb892b8b8d412dd73b1a01e3e..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.pure -Makefile -config.log -config.status -configure -dependencies -gmp_machine.h -linker_options -stamp-h diff --git a/src/modules/gmpmod/.gitignore b/src/modules/gmpmod/.gitignore deleted file mode 100644 index f201fb660d58c7c381b72ff86872dc61a7ae44dc..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.pure -/Makefile -/config.log -/config.status -/configure -/dependencies -/gmp_machine.h -/linker_options -/stamp-h diff --git a/src/modules/gmpmod/Makefile.in b/src/modules/gmpmod/Makefile.in deleted file mode 100644 index a7c8bf3359a841d71cd7ba63701fc2cfdb09843c..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/Makefile.in +++ /dev/null @@ -1,7 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -MODULE_LDFLAGS=@LIBS@ -OBJS=mpz_glue.o - -@static_module_makefile@ -@dependencies@ diff --git a/src/modules/gmpmod/configure.in b/src/modules/gmpmod/configure.in deleted file mode 100644 index 0df3eec9246412a615eb05ac4a7721ec12630c80..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/configure.in +++ /dev/null @@ -1,16 +0,0 @@ -AC_INIT(mpz_glue.c) -AC_CONFIG_HEADER(gmp_machine.h) -AC_ARG_WITH(gmp, [ --with(out)-gmp Support bignums],[],[with_gmp=yes]) - -sinclude(../module_configure.in) - -if test x$with_gmp = xyes ; then - AC_CHECK_HEADERS(gmp.h) - if test $ac_cv_header_gmp_h = yes ; then - AC_CHECK_LIB(gmp, mpz_set_d) - fi -fi - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/gmpmod/gmp_machine.h.in b/src/modules/gmpmod/gmp_machine.h.in deleted file mode 100644 index f304d6b576f6b85fcce987ff7044b6c9d77386ee..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/gmp_machine.h.in +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GMP_MACHINE_H -#define GMP_MACHINE_H - -/* Define this if you have <gmp.h> */ -#undef HAVE_GMP_H - -/* Define this if you have -lgmp */ -#undef HAVE_LIBGMP - -#endif diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c deleted file mode 100644 index d444a288bd94fb5eeb4e73c1e90e6fcd8de62bc3..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/mpz_glue.c +++ /dev/null @@ -1,666 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#include "global.h" -RCSID("$Id: mpz_glue.c,v 1.14 1997/02/07 00:42:42 hubbe Exp $"); -#include "gmp_machine.h" -#include "types.h" - -#if !defined(HAVE_LIBGMP) -#undef HAVE_GMP_H -#endif - -#ifdef HAVE_GMP_H - -#include "interpret.h" -#include "svalue.h" -#include "stralloc.h" -#include "array.h" -#include "macros.h" -#include "program.h" -#include "stralloc.h" -#include "object.h" -#include "pike_types.h" - -#include <gmp.h> -#include <assert.h> - -#define THIS ((MP_INT *)(fp->current_storage)) -#define OBTOMPZ(o) ((MP_INT *)(o->storage)) - -static struct program *mpzmod_program; - -static void get_mpz_from_digits(MP_INT *tmp, - struct pike_string *digits, - int base) -{ - if(!base || ((base >= 2) && (base <= 36))) - { - if (mpz_set_str(tmp, digits->str, base)) - error("invalid digits, cannot convert to mpz"); - } - else if(base == 256) - { - - INT8 i; - mpz_t digit; - - mpz_init(digit); - mpz_set_ui(tmp, 0); - for (i = 0; i < digits->len; i++) - { - mpz_set_ui(digit, EXTRACT_UCHAR(digits->str + i)); - mpz_mul_2exp(digit, digit, (digits->len - i - 1) * 8); - mpz_ior(tmp, tmp, digit); - } - } - else - { - error("invalid base.\n"); - } -} - -static void get_new_mpz(MP_INT *tmp, struct svalue *s) -{ - switch(s->type) - { - case T_INT: - mpz_set_si(tmp, (signed long int) s->u.integer); - break; - - case T_FLOAT: - mpz_set_d(tmp, (double) s->u.float_number); - break; - - case T_OBJECT: - if(s->u.object->prog != mpzmod_program) - error("Wrong type of object, cannot convert to mpz.\n"); - - mpz_set(tmp, OBTOMPZ(s->u.object)); - break; -#if 0 - case T_STRING: - mpz_set_str(tmp, s->u.string->str, 0); - break; - - case T_ARRAY: /* Experimental */ - if ( (s->u.array->size != 2) - || (ITEM(s->u.array)[0].type != T_STRING) - || (ITEM(s->u.array)[1].type != T_INT)) - error("cannot convert array to mpz.\n"); - get_mpz_from_digits(tmp, ITEM(s->u.array)[0].u.string, - ITEM(s->u.array)[1]); - break; -#endif - default: - error("cannot convert argument to mpz.\n"); - } -} - -static void mpzmod_create(INT32 args) -{ - switch(args) - { - case 1: - if(sp[-args].type == T_STRING) - get_mpz_from_digits(THIS, sp[-args].u.string, 0); - else - get_new_mpz(THIS, sp-args); - break; - - case 2: /* Args are string of digits and integer base */ - if(sp[-args].type != T_STRING) - error("bad argument 1 for Mpz->create()"); - - if (sp[1-args].type != T_INT) - error("wrong type for base in Mpz->create()"); - - get_mpz_from_digits(THIS, sp[-args].u.string, sp[1-args].u.integer); - break; - - default: - error("Too many arguments to Mpz->create()\n"); - - case 0: - break; /* Needed by AIX cc */ - } - pop_n_elems(args); -} - -static void mpzmod_get_int(INT32 args) -{ - pop_n_elems(args); - push_int(mpz_get_si(THIS)); -} - -static void mpzmod_get_float(INT32 args) -{ - pop_n_elems(args); - push_float((float)mpz_get_d(THIS)); -} - -static struct pike_string *low_get_digits(MP_INT *mpz, int base) -{ - struct pike_string *s; - INT32 len; - - if ( (base >= 2) && (base <= 36)) - { - len = mpz_sizeinbase(mpz, base) + 2; - s = begin_shared_string(len); - mpz_get_str(s->str, base, mpz); - /* Find NULL character */ - len-=4; - if (len < 0) len = 0; - while(s->str[len]) len++; - s->len=len; - s=end_shared_string(s); - } - else if (base == 256) - { - INT32 i; - mpz_t tmp; - - if (mpz_sgn(mpz) < 0) - error("only non-negative numbers can be converted to base 256.\n"); - len = (mpz_sizeinbase(mpz, 2) + 7) / 8; - s = begin_shared_string(len); - mpz_init_set(tmp, mpz); - i = len; - while(i--) - { - s->str[i] = mpz_get_ui(tmp) & 0xff; - mpz_tdiv_q_2exp(tmp, tmp, 8); - } - assert(mpz_sgn(tmp) == 0); - mpz_clear(tmp); - s = end_shared_string(s); - } - else - { - error("invalid base.\n"); - return 0; /* Make GCC happy */ - } - - return s; -} - -static void mpzmod_get_string(INT32 args) -{ - pop_n_elems(args); - push_string(low_get_digits(THIS, 10)); -} - -static void mpzmod_digits(INT32 args) -{ - INT32 base; - if (!args) - { - base = 10; - } - else - { - if (sp[-args].type != T_INT) - error("Bad argument 1 for Mpz->digits().\n"); - base = sp[-args].u.integer; - } - pop_n_elems(args); - - push_string(low_get_digits(THIS, base)); -} - -static void mpzmod_size(INT32 args) -{ - int base; - if (!args) - { - /* Default is number of bits */ - base = 2; - } - else - { - if (sp[-args].type != T_INT) - error("bad argument 1 for Mpz->size()\n"); - base = sp[-args].u.integer; - if ((base != 256) && ((base < 2) || (base > 36))) - error("invalid base\n"); - } - pop_n_elems(args); - - if (base == 256) - push_int((mpz_sizeinbase(THIS, 2) + 7) / 8); - else - push_int(mpz_sizeinbase(THIS, base)); -} - -static void mpzmod_cast(INT32 args) -{ - if(args < 1) - error("mpz->cast() called without arguments.\n"); - if(sp[-args].type != T_STRING) - error("Bad argument 1 to mpz->cast().\n"); - - switch(sp[-args].u.string->str[0]) - { - case 'i': - if(!strcmp(sp[-args].u.string->str, "int")) - { - mpzmod_get_int(args); - return; - } - break; - - case 's': - if(!strcmp(sp[-args].u.string->str, "string")) - { - mpzmod_get_string(args); - return; - } - break; - - case 'f': - if(!strcmp(sp[-args].u.string->str, "float")) - { - mpzmod_get_float(args); - return; - } - break; - - case 'o': - if(!strcmp(sp[-args].u.string->str, "object")) - { - pop_n_elems(args); - push_object(this_object()); - } - break; - - case 'm': - if(!strcmp(sp[-args].u.string->str, "mixed")) - { - pop_n_elems(args); - push_object(this_object()); - } - break; - - } - - error("mpz->cast() to other type than string, int or float.\n"); -} - -static MP_INT *get_mpz(struct svalue *s) -{ - struct object *o; - switch(s->type) - { - default: - error("Wrong type of object, cannot convert to mpz.\n"); - return 0; - - case T_INT: - case T_FLOAT: -#if 0 - case T_STRING: - case T_ARRAY: -#endif - o=clone(mpzmod_program,0); - get_new_mpz(OBTOMPZ(o), s); - free_svalue(s); - s->u.object=o; - s->type=T_OBJECT; - return (MP_INT *)o->storage; - - case T_OBJECT: - if(s->u.object->prog != mpzmod_program) - error("Wrong type of object, cannot convert to mpz.\n"); - - return (MP_INT *)s->u.object->storage; - } -} - -/* These two functions are here so we can allocate temporary - * objects without having to worry about them leaking in - * case of errors.. - */ -static struct object *temporary; -MP_INT *get_tmp() -{ - if(!temporary) - temporary=clone(mpzmod_program,0); - - return (MP_INT *)temporary->storage; -} - -static void return_temporary(INT32 args) -{ - pop_n_elems(args); - push_object(temporary); - temporary=0; -} - -#define BINFUN(name, fun) \ -static void name(INT32 args) \ -{ \ - INT32 e; \ - MP_INT *tmp=get_tmp(); \ - mpz_set(tmp, THIS); \ - for(e=0;e<args;e++) \ - fun(tmp, tmp, get_mpz(sp+e-args)); \ - return_temporary(args); \ -} - -BINFUN(mpzmod_add,mpz_add) -BINFUN(mpzmod_mul,mpz_mul) -BINFUN(mpzmod_gcd,mpz_gcd) - -static void mpzmod_sub(INT32 args) -{ - INT32 e; - MP_INT *tmp=get_tmp(); - mpz_set(tmp, THIS); - - if(args) - { - for(e=0;e<args;e++) - mpz_sub(tmp, tmp, get_mpz(sp+e-args)); - }else{ - mpz_neg(tmp, tmp); - } - - return_temporary(args); -} - -static void mpzmod_div(INT32 args) -{ - INT32 e; - MP_INT *tmp=get_tmp(); - mpz_set(tmp, THIS); - - for(e=0;e<args;e++) - { - MP_INT *tmp2; - tmp2=get_mpz(sp+e-args); - if(!mpz_sgn(tmp2)) - error("Division by zero.\n"); - mpz_tdiv_q(tmp, tmp, tmp2); - } - return_temporary(args); -} - -static void mpzmod_mod(INT32 args) -{ - INT32 e; - MP_INT *tmp=get_tmp(); - mpz_set(tmp, THIS); - - for(e=0;e<args;e++) - { - MP_INT *tmp2; - tmp2=get_mpz(sp+e-args); - if(!mpz_sgn(tmp2)) - error("Modulo by zero.\n"); - mpz_tdiv_r(tmp, tmp, tmp2); - } - return_temporary(args); -} - -static void mpzmod_gcdext(INT32 args) -{ - struct object *g, *s, *t; - MP_INT *a; - - a = get_mpz(sp-args); - - g = clone(mpzmod_program, 0); - s = clone(mpzmod_program, 0); - t = clone(mpzmod_program, 0); - - mpz_gcdext(OBTOMPZ(g), OBTOMPZ(s), OBTOMPZ(t), THIS, a); - pop_n_elems(args); - push_object(g); push_object(s); push_object(t); - f_aggregate(3); -} - -static void mpzmod_gcdext2(INT32 args) -{ - struct object *g, *s; - MP_INT *a; - - a = get_mpz(sp-args); - - g = clone(mpzmod_program, 0); - s = clone(mpzmod_program, 0); - - mpz_gcdext(OBTOMPZ(g), OBTOMPZ(s), NULL, THIS, a); - pop_n_elems(args); - push_object(g); push_object(s); - f_aggregate(2); -} - -static void mpzmod_invert(INT32 args) -{ - MP_INT *modulo; - MP_INT *tmp; - - modulo = get_mpz(sp-args); - if (!mpz_sgn(modulo)) - error("divide by zero"); - tmp = get_tmp(); - if (mpz_invert(tmp, THIS, modulo) == 0) - error("not invertible"); - return_temporary(args); -} - -BINFUN(mpzmod_and,mpz_and) -BINFUN(mpzmod_or,mpz_ior) - -static void mpzmod_compl(INT32 args) -{ - struct object *o; - pop_n_elems(args); - o=clone(mpzmod_program,0); - push_object(o); - mpz_com(OBTOMPZ(o), THIS); -} - - -#define CMPFUN(name,cmp) \ -static void name(INT32 args) \ -{ \ - INT32 i; \ - if(!args) error("Comparison with one argument?\n"); \ - i=mpz_cmp(THIS, get_mpz(sp-args)) cmp 0; \ - pop_n_elems(args); \ - push_int(i); \ -} - -CMPFUN(mpzmod_gt, >) -CMPFUN(mpzmod_lt, <) -CMPFUN(mpzmod_ge, >=) -CMPFUN(mpzmod_le, <=) -CMPFUN(mpzmod_eq, ==) -CMPFUN(mpzmod_nq, !=) - -static void mpzmod_probably_prime_p(INT32 args) -{ - pop_n_elems(args); - push_int(mpz_probab_prime_p(THIS, 25)); -} - -static void mpzmod_sgn(INT32 args) -{ - pop_n_elems(args); - push_int(mpz_sgn(THIS)); -} - - -static void mpzmod_sqrt(INT32 args) -{ - struct object *o; - pop_n_elems(args); - if(mpz_sgn(THIS)<0) - error("mpz->sqrt() on negative number.\n"); - - o=clone(mpzmod_program,0); - push_object(o); - mpz_sqrt(OBTOMPZ(o), THIS); -} - -static void mpzmod_sqrtrem(INT32 args) -{ - struct object *root, *rem; - - pop_n_elems(args); - if(mpz_sgn(THIS)<0) - error("mpz->sqrtrem() on negative number.\n"); - - root = clone(mpzmod_program,0); - rem = clone(mpzmod_program,0); - mpz_sqrtrem(OBTOMPZ(root), OBTOMPZ(rem), THIS); - push_object(root); push_object(rem); - f_aggregate(2); -} - -static void mpzmod_lsh(INT32 args) -{ - MP_INT *tmp; - pop_n_elems(args-1); - push_string(int_type_string); - int_type_string->refs++; - f_cast(2); - tmp=get_tmp(); - if(sp[-1].u.integer < 0) - error("mpz->lsh on negative number.\n"); - mpz_mul_2exp(tmp, THIS, sp[-1].u.integer); - return_temporary(1); -} - -static void mpzmod_rsh(INT32 args) -{ - MP_INT *tmp; - pop_n_elems(args-1); - push_string(int_type_string); - int_type_string->refs++; - f_cast(2); - tmp=get_tmp(); - mpz_set_ui(tmp,1); - mpz_mul_2exp(tmp, tmp, sp[-1].u.integer); - mpz_tdiv_q(tmp, THIS, tmp); - return_temporary(1); -} - -static void mpzmod_powm(INT32 args) -{ - MP_INT *tmp; - if(args < 2) - error("Too few arguments to mpzmod->powm()\n"); - - tmp=get_tmp(); - mpz_powm(tmp, THIS, get_mpz(sp-args), get_mpz(sp+1-args)); - return_temporary(args); -} - -static void mpzmod_not(INT32 args) -{ - pop_n_elems(args); - push_int(!mpz_sgn(THIS)); -} - -static void init_mpz_glue(struct object *o) -{ - mpz_init(THIS); -} - -static void exit_mpz_glue(struct object *o) -{ - mpz_clear(THIS); -} -#endif - -void pike_module_exit(void) -{ -#ifdef HAVE_GMP_H - if(temporary) free_object(temporary); - free_program(mpzmod_program); -#endif -} - -void pike_module_init(void) -{ -#ifdef HAVE_GMP_H - start_new_program(); - add_storage(sizeof(MP_INT)); - - add_function("create", mpzmod_create, - "function(void|string|int|float|object:void)" - "|function(string,int:void)", 0); - -#define MPZ_ARG_TYPE "int|float|object" -#define MPZ_BINOP_TYPE ("function(" MPZ_ARG_TYPE "...:object)") - - add_function("`+",mpzmod_add,MPZ_BINOP_TYPE,0); - add_function("`-",mpzmod_sub,MPZ_BINOP_TYPE,0); - add_function("`*",mpzmod_mul,MPZ_BINOP_TYPE,0); - add_function("`/",mpzmod_div,MPZ_BINOP_TYPE,0); - add_function("`%",mpzmod_mod,MPZ_BINOP_TYPE,0); - add_function("`&",mpzmod_and,MPZ_BINOP_TYPE,0); - add_function("`|",mpzmod_or,MPZ_BINOP_TYPE,0); - -#define MPZ_SHIFT_TYPE "function(int|float|object:object)" - add_function("`<<",mpzmod_lsh,MPZ_SHIFT_TYPE,0); - add_function("`>>",mpzmod_rsh,MPZ_SHIFT_TYPE,0); - -#define MPZ_CMPOP_TYPE ("function(" MPZ_ARG_TYPE ":int)") - - add_function("`>", mpzmod_gt,MPZ_CMPOP_TYPE,0); - add_function("`<", mpzmod_lt,MPZ_CMPOP_TYPE,0); - add_function("`>=",mpzmod_ge,MPZ_CMPOP_TYPE,0); - add_function("`<=",mpzmod_le,MPZ_CMPOP_TYPE,0); - - add_function("`==",mpzmod_le,MPZ_CMPOP_TYPE,0); - add_function("`!=",mpzmod_le,MPZ_CMPOP_TYPE,0); - - add_function("`!",mpzmod_not,"function(:int)",0); - - add_function("__hash",mpzmod_get_int,"function(:int)",0); - add_function("cast",mpzmod_cast,"function(string:mixed)",0); - - add_function("digits", mpzmod_digits, "function(void|int:string)", 0); - add_function("size", mpzmod_size, "function(void|int:int)", 0); - - add_function("cast_to_int",mpzmod_get_int,"function(:int)",0); - add_function("cast_to_string",mpzmod_get_string,"function(:string)",0); - add_function("cast_to_float",mpzmod_get_float,"function(:float)",0); - - add_function("probably_prime_p",mpzmod_probably_prime_p,"function(:int)",0); - add_function("gcd",mpzmod_gcd, MPZ_BINOP_TYPE, 0); - add_function("gcdext", mpzmod_gcdext, - "function(" MPZ_ARG_TYPE "," MPZ_ARG_TYPE ":array(object))", 0); - add_function("gcdext2", mpzmod_gcdext2, - "function(" MPZ_ARG_TYPE "," MPZ_ARG_TYPE ":array(object))", 0); - add_function("invert", mpzmod_invert, - "function(" MPZ_ARG_TYPE ":object)", 0); - - add_function("sqrt",mpzmod_gcd,"function(:object)",0); - add_function("sqrtrem", mpzmod_sqrtrem, "function(:array(object))", 0); - add_function("`~",mpzmod_gcd,"function(:object)",0); - add_function("powm",mpzmod_powm, - "function(" MPZ_ARG_TYPE "," MPZ_ARG_TYPE ":object)", 0); -#if 0 - /* These are not implemented yet */ - add_function("squarep", mpzmod_squarep, "function(:int)", 0); - add_function("divmod", mpzmod_divmod, "function(" MPZ_ARG_TYPE ":array(object))", 0); - add_function("pow", mpzmod_pow, "function(int:object)", 0); - add_function("divm", mpzmod_divm, "function(string|int|float|object, string|int|float|object:object)", 0); - add_efun("mpz_pow", mpz_pow, "function(int, int)", 0); - add_efun("mpz_fac", mpz_fac, "function(int|object:object)", 0); -#endif - set_init_callback(init_mpz_glue); - set_exit_callback(exit_mpz_glue); - - mpzmod_program=end_program(); - add_program_constant("mpz",mpzmod_program,0); -#endif -} - diff --git a/src/modules/gmpmod/testsuite.in b/src/modules/gmpmod/testsuite.in deleted file mode 100644 index 39fd5d4ac9bea8960b8526c428ff260a95f76f6a..0000000000000000000000000000000000000000 --- a/src/modules/gmpmod/testsuite.in +++ /dev/null @@ -1,57 +0,0 @@ -// mpz -cond( [[ master()->programs["/precompiled/mpz"] ]], -[[ - define([[MPZ]],[[(program)"/precompiled/mpz"]]) - test_true(programp(MPZ)) - test_false(clone(MPZ)) - test_do(destruct(clone(MPZ))) - - test_eq(Mpz(10),10) - test_eq(Mpz("10"),10) - test_eq(Mpz(10.0),10) - test_eq(Mpz("10",8),8) - test_eq(Mpz("0",256),'0') - - test_eq(clone(MPZ,99)+1,100) - test_eq(clone(MPZ,100)*10,1000) - test_eq(clone(MPZ,"100")*10.0,1000) - test_eq(clone(MPZ,100.0)*clone(MPZ,3),300) - test_eq(clone(MPZ,100.0)/4,25) - test_eq(clone(MPZ,42)%10,2) - test_eq(clone(MPZ,10)<<1,20) - test_eq(clone(MPZ,10)>>1,5) - test_eq(clone(MPZ,66)+11,77) - test_eq(clone(MPZ,66)-11,55) - test_eq(clone(MPZ,17)&18,16) - test_eq(clone(MPZ,17)|7,31) - test_eq(-clone(MPZ,17),17) - test_eq((~clone(MPZ,17)) & 255,0xf0) - test_true(stringp((string)clone(MPZ,17))) - test_eq((string)clone(MPZ,17),"17") - test_true(intp((int)clone(MPZ,17))) - test_eq((int)clone(MPZ,17),17) - test_false(clone(MPZ,0)) - test_true(clone(MPZ,1)) - test_eq(clone(MPZ,17)->powm(2,4711),290) - - define([[mpz_test_cmp]],[[ - test_cmp(clone(MPZ,$1), $2) - test_cmp($1, clone(MPZ,$2)) - test_cmp(clone(MPZ, $1), clone(MPZ, $2)) - ]]) - - define([[mpz_test_type1]],[[ - mpz_test_cmp($1,$2) - mpz_test_cmp($1.0,$2) - ]]) - - define([[mpz_test_type2]],[[ - mpz_test_type1($1,$2) - mpz_test_type1($1,$2.0) - ]]) - - mpz_test_type2(1,2) - mpz_test_type2(-2,1) - -]]); - diff --git a/src/modules/image/.cvsignore b/src/modules/image/.cvsignore deleted file mode 100644 index 47c84b07459ebcb78e36ee8c2e1a30cee7f440ff..0000000000000000000000000000000000000000 --- a/src/modules/image/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.pure -Makefile -config.h -config.log -config.status -configure -dependencies -stamp-h diff --git a/src/modules/image/.gitignore b/src/modules/image/.gitignore deleted file mode 100644 index b27587e1b501d0baa775ec479e1a69e7da31aef0..0000000000000000000000000000000000000000 --- a/src/modules/image/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/.pure -/Makefile -/config.h -/config.log -/config.status -/configure -/dependencies -/stamp-h diff --git a/src/modules/image/Makefile.in b/src/modules/image/Makefile.in deleted file mode 100644 index b28ff0d6bfbe5515768107fb5d5e380598a2ac1b..0000000000000000000000000000000000000000 --- a/src/modules/image/Makefile.in +++ /dev/null @@ -1,16 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -OBJS = image.o font.o quant.o lzw.o togif.o matrix.o pnm.o blit.o \ - pattern.o dct.o operator.o -MODNAME=image - -@dynamic_module_makefile@ - -pike: all - cd ../..; make - -pure: all - cd ../..; make pure - - -@dependencies@ diff --git a/src/modules/image/blit.c b/src/modules/image/blit.c deleted file mode 100644 index ff978a60bbd7ae44f6fdb868472e003e56d7fb18..0000000000000000000000000000000000000000 --- a/src/modules/image/blit.c +++ /dev/null @@ -1,465 +0,0 @@ -/* $Id: blit.c,v 1.10 1997/01/23 20:01:59 grubba Exp $ */ -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "error.h" -#include "threads.h" - -#include "image.h" - -extern struct program *image_program; -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) - -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - -/***************** internals ***********************************/ - -#define testrange(x) max(min((x),255),0) - -#define apply_alpha(x,y,alpha) \ - ((unsigned char)((y*(255L-(alpha))+x*(alpha))/255L)) - -#define set_rgb_group_alpha(dest,src,alpha) \ - (((dest).r=apply_alpha((dest).r,(src).r,alpha)), \ - ((dest).g=apply_alpha((dest).g,(src).g,alpha)), \ - ((dest).b=apply_alpha((dest).b,(src).b,alpha))) - -#define pixel(_img,x,y) ((_img)->img[(x)+(y)*(_img)->xsize]) - -#define setpixel(x,y) \ - (THIS->alpha? \ - set_rgb_group_alpha(THIS->img[(x)+(y)*THIS->xsize],THIS->rgb,THIS->alpha): \ - ((pixel(THIS,x,y)=THIS->rgb),0)) - -#define setpixel_test(x,y) \ - (((x)<0||(y)<0||(x)>=THIS->xsize||(y)>=THIS->ysize)? \ - 0:(setpixel(x,y),0)) - -static INLINE void getrgb(struct image *img, - INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; - img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; - img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; - if (args-args_start>=4) - if (sp[3-args+args_start].type!=T_INT) - error("Illegal alpha argument to %s\n",name); - else - img->alpha=sp[3-args+args_start].u.integer; - else - img->alpha=0; -} - -/*** end internals ***/ - - -void img_clear(rgb_group *dest,rgb_group rgb,INT32 size) -{ - THREADS_ALLOW(); - while (size--) *(dest++)=rgb; - THREADS_DISALLOW(); -} - -void img_box_nocheck(INT32 x1,INT32 y1,INT32 x2,INT32 y2) -{ - INT32 x,mod; - rgb_group *foo,*end,rgb; - struct image *this; - - this=THIS; - - THREADS_ALLOW(); - mod=this->xsize-(x2-x1)-1; - foo=this->img+x1+y1*this->xsize; - end=this->img+x1+y2*this->xsize; - rgb=this->rgb; - - - if (!this->alpha) - for (; foo<=end; foo+=mod) for (x=x1; x<=x2; x++) *(foo++)=rgb; - else - for (; foo<=end; foo+=mod) for (x=x1; x<=x2; x++,foo++) - set_rgb_group_alpha(*foo,rgb,this->alpha); - THREADS_DISALLOW(); -} - - -void img_blit(rgb_group *dest,rgb_group *src,INT32 width, - INT32 lines,INT32 moddest,INT32 modsrc) -{ -CHRONO("image_blit begin"); - - THREADS_ALLOW(); - while (lines--) - { - MEMCPY(dest,src,sizeof(rgb_group)*width); - dest+=moddest; - src+=modsrc; - } - THREADS_DISALLOW(); -CHRONO("image_blit end"); - -} - -void img_crop(struct image *dest, - struct image *img, - INT32 x1,INT32 y1, - INT32 x2,INT32 y2) -{ - rgb_group *new; - INT32 xp,yp,xs,ys; - - if (dest->img) { free(dest->img); dest->img=NULL; } - - if (x1>x2) x1^=x2,x2^=x1,x1^=x2; - if (y1>y2) y1^=y2,y2^=y1,y1^=y2; - - if (x1==0 && y1==0 && - img->xsize-1==x2 && img->ysize-1==y2) - { - *dest=*img; - new=malloc( (x2-x1+1)*(y2-y1+1)*sizeof(rgb_group) + 1); - if (!new) - error("Out of memory.\n"); - THREADS_ALLOW(); - MEMCPY(new,img->img,(x2-x1+1)*(y2-y1+1)*sizeof(rgb_group)); - THREADS_DISALLOW(); - dest->img=new; - return; - } - - new=malloc( (x2-x1+1)*(y2-y1+1)*sizeof(rgb_group) +1); - if (!new) - error("Out of memory.\n"); - - img_clear(new,THIS->rgb,(x2-x1+1)*(y2-y1+1)); - - dest->xsize=x2-x1+1; - dest->ysize=y2-y1+1; - - xp=max(0,-x1); - yp=max(0,-y1); - xs=max(0,x1); - ys=max(0,y1); - - if (x1<0) x1=0; else if (x1>=img->xsize) x1=img->xsize-1; - if (y1<0) y1=0; else if (y1>=img->ysize) y1=img->ysize-1; - if (x2<0) x2=0; else if (x2>=img->xsize) x2=img->xsize-1; - if (y2<0) y2=0; else if (y2>=img->ysize) y2=img->ysize-1; - - img_blit(new+xp+yp*dest->xsize, - img->img+xs+(img->xsize)*ys, - x2-x1+1, - y2-y1+1, - dest->xsize, - img->xsize); - - dest->img=new; -} - -void img_clone(struct image *newimg,struct image *img) -{ - if (newimg->img) free(newimg->img); - newimg->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize +1); - if (!newimg->img) error("Out of memory!\n"); - THREADS_ALLOW(); - MEMCPY(newimg->img,img->img,sizeof(rgb_group)*img->xsize*img->ysize); - THREADS_DISALLOW(); - newimg->xsize=img->xsize; - newimg->ysize=img->ysize; - newimg->rgb=img->rgb; -} - -void image_paste(INT32 args) -{ - struct image *img; - INT32 x1,y1,x2,y2,blitwidth,blitheight; - - if (args<1 - || sp[-args].type!=T_OBJECT - || !sp[-args].u.object - || sp[-args].u.object->prog!=image_program) - error("illegal argument 1 to image->paste()\n"); - if (!THIS->img) return; - - img=(struct image*)sp[-args].u.object->storage; - if (!img) return; - - if (args>=3) - { - if (sp[1-args].type!=T_INT - || sp[2-args].type!=T_INT) - error("illegal arguments to image->paste()\n"); - x1=sp[1-args].u.integer; - y1=sp[2-args].u.integer; - } - else x1=y1=0; - - x2=x1+img->xsize-1; - y2=y1+img->ysize-1; - - blitwidth=min(x2,THIS->xsize-1)-max(x1,0)+1; - blitheight=min(y2,THIS->ysize-1)-max(y1,0)+1; - - img_blit(THIS->img+max(0,x1)+(THIS->xsize)*max(0,y1), - img->img+max(0,-x1)+(x2-x1+1)*max(0,-y1), - blitwidth, - blitheight, - THIS->xsize, - img->xsize); - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_paste_alpha(INT32 args) -{ - struct image *img; - INT32 x1,y1,x,y; - - if (args<2 - || sp[-args].type!=T_OBJECT - || !sp[-args].u.object - || sp[-args].u.object->prog!=image_program - || sp[1-args].type!=T_INT) - error("illegal arguments to image->paste_alpha()\n"); - if (!THIS->img) return; - - img=(struct image*)sp[-args].u.object->storage; - if (!img) return; - THIS->alpha=(unsigned char)(sp[1-args].u.integer); - - if (args>=4) - { - if (sp[2-args].type!=T_INT - || sp[3-args].type!=T_INT) - error("illegal arguments to image->paste_alpha()\n"); - x1=sp[2-args].u.integer; - y1=sp[3-args].u.integer; - } - else x1=y1=0; - -/* tr�da h�r n�ndag */ - - for (x=0; x<img->xsize; x++) - for (y=0; y<img->ysize; y++) - { - THIS->rgb=pixel(img,x,y); - setpixel_test(x1+x,y1+y); - } - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_paste_mask(INT32 args) -{ - struct image *img,*mask; - INT32 x1,y1,x,y,x2,y2,smod,dmod,mmod; - rgb_group *s,*d,*m; - float q; - -CHRONO("image_paste_mask init"); - - if (args<2) - error("illegal number of arguments to image->paste_mask()\n"); - if (sp[-args].type!=T_OBJECT - || !sp[-args].u.object - || sp[-args].u.object->prog!=image_program) - error("illegal argument 1 to image->paste_mask()\n"); - if (sp[1-args].type!=T_OBJECT - || !sp[1-args].u.object - || sp[1-args].u.object->prog!=image_program) - error("illegal argument 2 to image->paste_mask()\n"); - if (!THIS->img) return; - - img=(struct image*)sp[-args].u.object->storage; - mask=(struct image*)sp[1-args].u.object->storage; - if ((!img)||(!img->img)) error("argument 1 has no image\n"); - if ((!mask)||(!mask->img)) error("argument 2 (alpha) has no image\n"); - - if (args>=4) - { - if (sp[2-args].type!=T_INT - || sp[3-args].type!=T_INT) - error("illegal coordinate arguments to image->paste_mask()\n"); - x1=sp[2-args].u.integer; - y1=sp[3-args].u.integer; - } - else x1=y1=0; - - x2=min(THIS->xsize-x1,min(img->xsize,mask->xsize)); - y2=min(THIS->ysize-y1,min(img->ysize,mask->ysize)); - -CHRONO("image_paste_mask begin"); - - s=img->img+max(0,-x1)+max(0,-y1)*img->xsize; - m=mask->img+max(0,-x1)+max(0,-y1)*mask->xsize; - d=THIS->img+max(0,-x1)+x1+(y1+max(0,-y1))*THIS->xsize; - x=max(0,-x1); - smod=img->xsize-(x2-x); - mmod=mask->xsize-(x2-x); - dmod=THIS->xsize-(x2-x); - - q=1.0/255; - - THREADS_ALLOW(); - for (y=max(0,-y1); y<y2; y++) - { - for (x=max(0,-x1); x<x2; x++) - { - if (m->r==255) d->r=s->r; - else if (m->r==0) d->r=d->r; - else d->r=(unsigned char)(((d->r*(255-m->r))+(s->r*m->r))*q); - if (m->g==255) d->g=s->g; - else if (m->g==0) d->g=d->g; - else d->g=(unsigned char)(((d->g*(255-m->g))+(s->g*m->g))*q); - if (m->b==255) d->b=s->b; - else if (m->b==0) d->b=d->b; - else d->b=(unsigned char)(((d->b*(255-m->b))+(s->b*m->b))*q); - s++; m++; d++; - } - s+=smod; m+=mmod; d+=dmod; - } - THREADS_DISALLOW(); -CHRONO("image_paste_mask end"); - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_paste_alpha_color(INT32 args) -{ - struct image *img,*mask; - INT32 x1,y1,x,y,x2,y2; - rgb_group rgb,*d,*m; - INT32 mmod,dmod; - float q; - - if (args!=1 && args!=4 && args!=6 && args!=3) - error("illegal number of arguments to image->paste_alpha_color()\n"); - if (sp[-args].type!=T_OBJECT - || !sp[-args].u.object - || sp[-args].u.object->prog!=image_program) - error("illegal argument 1 to image->paste_alpha_color()\n"); - if (!THIS->img) return; - - if (args==6 || args==4) /* colors at arg 2..4 */ - getrgb(THIS,1,args,"image->paste_alpha_color()\n"); - if (args==3) /* coords at 2..3 */ - { - if (sp[1-args].type!=T_INT - || sp[2-args].type!=T_INT) - error("illegal coordinate arguments to image->paste_alpha_color()\n"); - x1=sp[1-args].u.integer; - y1=sp[2-args].u.integer; - } - else if (args==6) /* at 5..6 */ - { - if (sp[4-args].type!=T_INT - || sp[5-args].type!=T_INT) - error("illegal coordinate arguments to image->paste_alpha_color()\n"); - x1=sp[4-args].u.integer; - y1=sp[5-args].u.integer; - } - else x1=y1=0; - - mask=(struct image*)sp[-args].u.object->storage; - if (!mask||!mask->img) error("argument 2 (alpha) has no image\n"); - - x2=min(THIS->xsize-x1,mask->xsize); - y2=min(THIS->ysize-y1,mask->ysize); - -CHRONO("image_paste_alpha_color begin"); - - m=mask->img+max(0,-x1)+max(0,-y1)*mask->xsize; - d=THIS->img+max(0,-x1)+x1+(y1+max(0,-y1))*THIS->xsize; - x=max(0,-x1); - mmod=mask->xsize-(x2-x); - dmod=THIS->xsize-(x2-x); - - q=1.0/255; - - rgb=THIS->rgb; - - THREADS_ALLOW(); - for (y=max(0,-y1); y<y2; y++) - { - for (x=max(0,-x1); x<x2; x++) - { - if (m->r==255) d->r=rgb.r; - else if (m->r==0) ; - else d->r=(unsigned char)(((d->r*(255-m->r))+(rgb.r*m->r))*q); - if (m->g==255) d->g=rgb.g; - else if (m->g==0) ; - else d->g=(unsigned char)(((d->g*(255-m->g))+(rgb.g*m->g))*q); - if (m->b==255) d->b=rgb.b; - else if (m->b==0) ; - else d->b=(unsigned char)(((d->b*(255-m->b))+(rgb.b*m->b))*q); - m++; d++; - } - m+=mmod; d+=dmod; - } - THREADS_DISALLOW(); -CHRONO("image_paste_alpha_color end"); - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void img_box(INT32 x1,INT32 y1,INT32 x2,INT32 y2) -{ - if (x1>x2) x1^=x2,x2^=x1,x1^=x2; - if (y1>y2) y1^=y2,y2^=y1,y1^=y2; - if (x2<0||y2<0||x1>=THIS->xsize||y1>=THIS->ysize) return; - img_box_nocheck(max(x1,0),max(y1,0),min(x2,THIS->xsize-1),min(y2,THIS->ysize-1)); -} - - - diff --git a/src/modules/image/config.h.in b/src/modules/image/config.h.in deleted file mode 100644 index 573e31d4ca89134b34b9caaabc21aaf9f392fcad..0000000000000000000000000000000000000000 --- a/src/modules/image/config.h.in +++ /dev/null @@ -1,19 +0,0 @@ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define if you have the getpagesize function. */ -#undef HAVE_GETPAGESIZE - -/* Define if you have the <fcntl.h> header file. */ -#undef HAVE_FCNTL_H - -/* Define if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define if you have the <sys/fcntl.h> header file. */ -#undef HAVE_SYS_FCNTL_H - -/* Define if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H diff --git a/src/modules/image/configure.in b/src/modules/image/configure.in deleted file mode 100644 index 4df99cce8ce80f712f8a1b3dc45eefb9111abc27..0000000000000000000000000000000000000000 --- a/src/modules/image/configure.in +++ /dev/null @@ -1,14 +0,0 @@ -AC_INIT(image.c) -AC_CONFIG_HEADER(config.h) - -sinclude(../module_configure.in) - -AC_FUNC_MMAP - -AC_CHECK_HEADERS(sys/fcntl.h fcntl.h stdlib.h) - -AC_SUBST(RANLIB) - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/image/dct.c b/src/modules/image/dct.c deleted file mode 100644 index 718d5673439c867db5fbacc242486d1cadfe2a14..0000000000000000000000000000000000000000 --- a/src/modules/image/dct.c +++ /dev/null @@ -1,165 +0,0 @@ -/* $Id: dct.c,v 1.3 1997/01/23 20:02:01 grubba Exp $ */ - -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "error.h" - -#include "image.h" - -extern struct program *image_program; -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) -#define testrange(x) max(min((x),255),0) - -static const double c0=0.70710678118654752440; -static const double pi=3.14159265358979323846; - -void image_dct(INT32 args) -{ - rgbd_group *area,*val; - struct object *o; - struct image *img; - INT32 x,y,u,v; - double xsz2,ysz2,enh,xp,yp,dx,dy; - double *costbl; - rgb_group *pix; - - if (!THIS->img) error("no image\n"); - - fprintf(stderr,"%d bytes, %d bytes\n", - sizeof(rgbd_group)*THIS->xsize*THIS->ysize, - sizeof(rgb_group)*THIS->xsize*THIS->ysize+1); - - if (!(area=malloc(sizeof(rgbd_group)*THIS->xsize*THIS->ysize+1))) - error("Out of memory\n"); - - if (!(costbl=malloc(sizeof(double)*THIS->xsize+1))) - { - free(area); - error("Out of memory\n"); - } - - o=clone(image_program,0); - img=(struct image*)(o->storage); - *img=*THIS; - - if (args>=2 - && sp[-args].type==T_INT - && sp[1-args].type==T_INT) - { - img->xsize=max(1,sp[-args].u.integer); - img->ysize=max(1,sp[1-args].u.integer); - } - else error("Illegal arguments to image->dct()\n"); - - if (!(img->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize+1))) - { - free(area); - free(costbl); - free_object(o); - error("Out of memory\n"); - } - - xsz2=THIS->xsize*2.0; - ysz2=THIS->ysize*2.0; - - enh=(8.0/THIS->xsize)*(8.0/THIS->ysize); - - for (u=0; u<THIS->xsize; u++) - { - double d,z0; - rgbd_group sum; - - for (v=0; v<THIS->ysize; v++) - { - d=(u?1:c0)*(v?1:c0)/4.0; - sum.r=sum.g=sum.b=0; - pix=THIS->img; - - for (x=0; x<THIS->xsize; x++) - costbl[x]=cos( (2*x+1)*u*pi/xsz2 ); - - for (y=0; y<THIS->ysize; y++) - { - z0=cos( (2*y+1)*v*pi/ysz2 ); - for (x=0; x<THIS->xsize; x++) - { - double z; - z = costbl[x] * z0; - sum.r+=pix->r*z; - sum.g+=pix->g*z; - sum.b+=pix->b*z; - pix++; - } - } - sum.r*=d; - sum.g*=d; - sum.b*=d; - area[u+v*THIS->xsize]=sum; - } - fprintf(stderr,"."); fflush(stderr); - } - fprintf(stderr,"\n"); - - dx=((double)(THIS->xsize-1))/(img->xsize); - dy=((double)(THIS->ysize-1))/(img->ysize); - - pix=img->img; - for (y=0,yp=0; y<img->ysize; y++,yp+=dy) - { - double z0; - rgbd_group sum; - - for (x=0,xp=0; x<img->xsize; x++,xp+=dx) - { - sum.r=sum.g=sum.b=0; - val=area; - - for (u=0; u<THIS->xsize; u++) - costbl[u]=cos( (2*xp+1)*u*pi/xsz2 ); - - for (v=0; v<THIS->ysize; v++) - { - z0=cos( (2*yp+1)*v*pi/ysz2 )*(v?1:c0)/4.0; - for (u=0; u<THIS->xsize; u++) - { - double z; - z = (u?1:c0) * costbl[u] * z0; - sum.r+=val->r*z; - sum.g+=val->g*z; - sum.b+=val->b*z; - val++; - } - } - sum.r*=enh; - sum.g*=enh; - sum.b*=enh; - pix->r=testrange(((int)(sum.r+0.5))); - pix->g=testrange(((int)(sum.g+0.5))); - pix->b=testrange(((int)(sum.b+0.5))); - pix++; - } - fprintf(stderr,"."); fflush(stderr); - } - - free(area); - free(costbl); - - pop_n_elems(args); - push_object(o); -} diff --git a/src/modules/image/doc.txt b/src/modules/image/doc.txt deleted file mode 100644 index 3f3cc2b2c97015454379ad1abd3bfff16f6abec5..0000000000000000000000000000000000000000 --- a/src/modules/image/doc.txt +++ /dev/null @@ -1,487 +0,0 @@ - Pike module: - - image - - Pontus Hagland law@infovav.se - Per Hedbor per@infovav.se - David K�gedal kg@infovav.se ----------------------------------------------------------------------------- -This package adds two Pike progams: - - * "precompiled/image" and - * "precompiled/font". - ----------------------------------------------------------------------------- - -methods in precompiled/image: - -Methods resulting in a new object: -object clone( [int xsize,int ysize [,int r,int g,int b] ] ); - -object copy( [int x1,int y1,int x2,int y2 [,int r,int g,int b] ] ); -object autocrop( [int border_width [,int left,int right,int top,int bottom] -[,int r,int g,int b] ] ); - -object gray(); -object color(int r,int g,int b); -object invert(); - -object mirrorx(void); -object mirrory(void); -object rotate_cw(void); -object rotate_ccw(void); -object threshold([int r,int g,int b]); -object apply_matrix(array(array(int)) matrix,[int r,int g,int b[,int div]]); - -object scale(float factor); -object scale(float factorx,float factory); -object scale(int newx|0,int newy|0); - -Methods operating on current object: -string toppm(void); -string|object fromppm(string s); -string togif( [int r,inr g,int b] ); - -object paste(object img [,int x,int y]) -object paste_alpha(object img, int alpha [,int x, int y]); -object paste_mask(object img, object alpha_mask [,int x,int y]); - -object setcolor(int r,int g,int b); -object setpixel(int x,int y [,int r,int g,int b] ); -object line(int x1,int y1,int x2,int y2 [,int r,int g,int b] ); -object box(int x1,int y1,int x2,int y2 [,int r,int g,int b] ); -object circle(int x,int y,int radx,int rady [,int r,int b,int g] ); -object tuned_box(int x1,int y1,int x2,int y2,array(array(int)) corner_rgb); - -Information giving methods: -object xsize(); -object ysize(); ----------------------------------------------------------------------------- - -METHOD - object apply_matrix(array(array(int)) matrix,[int r,int g,int b[,int - div]]); -DESCRIPTION - This method applies a matrix on the image. Each surrounding pixel is - multiplied with the value of the matrix element in that point, these - values are added and divided by the total sum of the matrix values (and - the div argument) and stored on the pixel (eventually added to the - r,g,b argument given as 'mean' value). - - It is possible to use a matrix of RGB groups (ie an array of three - integers) instead of the simple values, this making it possible to - apply different matrices on red, green and blue channel. -RETURN VALUE - the new object -EXAMPLE - A 'blur' operation (3x3, gaussian): - - blurred=image->apply_matrix( ({ ({1,2,1}), ({2,3,2}), ({1,2,1}) }) ); - - A 'Emboss' operation (3x3): - - emossed=image->apply_matrix(({ ({0,1,8}), ({-1,0,1}), ({-8,-1,0}) }), 128,128,128, 15 ); - - Here i'm using 128,128,128 (gray) as a mean, because i get negative - values. - A division by 15 is good to give 'normal' edges. -BUGS - not known - ----------------------------------------------------------------------------- - -METHOD - object autocrop( [int border_width [,int left,int right,int top,int - bottom] [,int r,int g,int b] ] ); -DESCRIPTION - Crops away unneccesary borders from the image. The border argument is - to define the new thickness of the surrounding border and the r,g,b is - the newly created border color. - - The left, right, ... arguments is used to tell which edges should be - autocropped. -RETURN VALUE - the new object -EXAMPLE - - cropped=image->autocrop(); - -BUGS - now known - ----------------------------------------------------------------------------- - -METHOD - object box(int x1,int y1,int x2,int y2 [,int r,int g,int b] ); -DESCRIPTION - Draw a box of the default or specified color. -RETURN VALUE - the image object -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - object circle(int x,int y,int radx,int rady [,int r,int b,int g] ); -DESCRIPTION - Draw a circle. The coordinates given are the center of the image and - the radius in x (horisontal) and y (vertical), this making it possible - to draw an ellipse too. :-) -RETURN VALUE - the image object -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - object clone( [int xsize,int ysize [,int r,int g,int b] ] ); -DESCRIPTION - make a new object and return it - o no arguments -> old image is copied - o size is given -> old image is copied cropped - o color is given -> new default color -RETURN VALUE - the new object -SEE ALSO - copy, clear -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - object color(int r,int g,int b); -DESCRIPTION - Apply a color filter on the image. -RETURN VALUE - the new object -EXAMPLE - - cyan=image->color(64,255,192); - - This function is most usable on a image that has been grayed first. -BUGS - ----------------------------------------------------------------------------- - -METHOD - object copy( [int x1,int y1,int x2,int y2 [,int r,int g,int b] ] ); -DESCRIPTION - Make a copy, or a copy of a part of the image. It is possible to copy - more then the image, to extend the image, this area is filled with the - current (or given) color. -RETURN VALUE - the new image object -EXAMPLE - - copy=image->copy(); - - copy=image->copy(-10,-10,image->xsize()+9,image->ysize()+9); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - string|object fromppm(string s); -DESCRIPTION - Import a ppm image. -RETURN VALUE - 0 (object) upon success, else the error message (string). -EXAMPLE - - image=clone( (program)"precompiled/image" ); - image->fromppm(read_bytes("my_image.ppm",0,10000000)); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object gray([int r,int g,int b]); -DESCRIPTION - Make this image gray (each r,g,b gets the same value). - If a color is given, that specifies the amount of r, g, and b that is - used to compute the gray level. Default is 87,127,41. -RETURN VALUE - the new object -EXAMPLE - - gray=image->gray() - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object invert(); -DESCRIPTION - Invert the image. -RETURN VALUE - the new object -EXAMPLE - - inverted=image->invert() - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object line(int x1,int y1,int x2,int y2 [,int r,int g,int b] ); -DESCRIPTION - Draw a line from x1,y1 to x2,y2. -RETURN VALUE - the image object -EXAMPLE - - image->line(17,100,42,1000); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object mirrorx(void); - object mirrory(void); -DESCRIPTION - Mirrors the image, horisontally or vertically. -RETURN VALUE - the new image object -EXAMPLE - - mirrored=image->mirrorx(); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object rotate_cw(void); - object rotate_ccw(void); -DESCRIPTION - Rotate the image, clockwise or counterclockwise, 90 degrees. - This operation is very fast compared to rotating any angle. -RETURN VALUE - the new image object -EXAMPLE - - snurr=image->rotate_cw(); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object paste(object img [,int x,int y]) - object paste_alpha(object img, int alpha [,int x, int y]); - object paste_mask(object img, object alpha_mask [,int x,int y]); -DESCRIPTION - Paste an image on this image. Use the specified alpha channel value or - the second specified image as an alpha channel. - The first argument is the image that will be pasted. -RETURN VALUE - the image object this function doesn't return anything -EXAMPLE - - image->paste(other_smaller_image,17,42); - - image->paste_mask(other_image,alpha_channel_image); - - Paste a dog on a landscape: - - landscape->paste(dog,dog_alpha_channel,xpos,ypos); - - Write some text: - - text=font->write("some text"); - foreground=text->clear(255,255,255); // white - background->paste(foreground,text,xpos,ypos); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object scale(float factor); (1 - object scale(float factorx,float factory); (2 - object scale(int newx|0,int newy|0); (3 -DESCRIPTION - Scale this image. - 1. scale the image with a (line scale) factor - 2. scale the image with different factors on x and y - 3. scale the image to a new size - with newx or newy set to zero, just scale the image to fit the x - or y size and keep proportions. -RETURN VALUE - the new object this function doesn't return anything -EXAMPLE -BUGS - ----------------------------------------------------------------------------- -METHOD - object setcolor(int r,int g,int b); -DESCRIPTION - set the default color used for drawing lines, etc -RETURN VALUE - the image object -EXAMPLE -BUGS - ----------------------------------------------------------------------------- -METHOD - object setpixel(int x,int y [,int r,int g,int b] ); -DESCRIPTION - set the color of the specified pixel -RETURN VALUE - the image object -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - object threshold([int r,int g,int b]); -DESCRIPTION - make image black-and-white using the given value as the threshold -RETURN VALUE - the new object -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - string togif( [int r,inr g,int b] ); -DESCRIPTION - export gif - if the color are given, this is the transparent color -RETURN VALUE - the gifimage as a string -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - string toppm(object); -DESCRIPTION - export ppm -RETURN VALUE - the ppm image as a string -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - object tuned_box(int x1,int y1,int x2,int y2,array(array(int)) - corner_rgb); -DESCRIPTION - draw a box with the specified corner colours, and shade the colors - between -RETURN VALUE - the image object -EXAMPLE - - image->tuned_box(0,0,img->xsize()-1,img->ysize()-1, - ({({0,0,64}),({16,16,128}), - ({16,16,128}),({192,160,128})})); - -BUGS - ----------------------------------------------------------------------------- - -METHOD - object xsize(); - object ysize(); -DESCRIPTION -RETURN VALUE - Gives the x- or the y-size (horisontal or vertical size) of the image. -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -methods in precompiled/font: - -int load(string file_name); -object write(string line, ...); ----------------------------------------------------------------------------- - -METHOD - int load(string file_name); -DESCRIPTION - load this font object with the font from the specified file -RETURN VALUE - true on success -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -METHOD - object write(string line, ...); -DESCRIPTION - make a new image object from the specified text, each argument - representing a line -RETURN VALUE - the new image object -EXAMPLE -BUGS - ----------------------------------------------------------------------------- - -Example program: - -(pike) - -int main() -{ - object txt,o,shad,font; - int i; - - txt = - (font=clone((program)"/precompiled/font")) - ->load("/usr/local/lib/pike/fonts/64/helvetica_bold_r") - ->write("The Image Module") - ->autocrop(20,0,0,0); - - shad=txt->mirrory()->scale(1.0,0.3)->color(64,64,64); - - o=clone((program)"/precompiled/image", - txt->xsize(),txt->ysize(), 0,0,100) - ->tuned_box(0,0,txt->xsize(),txt->ysize(), - ({({0,0,0}),({0,0,0}), - ({0,0,255}),({128,128,0})})); - - o->setcolor(255,255,255,200); - for (i=0; i<30; i++) - if (random(2)) - o->line(random(o->xsize()),o->ysize()-10-random(20+i*3), - o->xsize()-1-random(30),o->ysize()-1); - else - o->line(random(o->xsize()),o->ysize()-10-random(20+i), - random(30),o->ysize()-1); - - for (i=0; i<10; i++) - o->box(random(o->xsize()),random(o->ysize()), - random(o->xsize()),random(o->ysize()), - random(256),random(256),random(256),220); - - o -> paste_mask(txt->clear(0,255,0), - shad,0,(int)(font->baseline()*0.7)+shad->ysize()-10) - -> paste_mask(txt->clear(255,255,0), - txt->apply_matrix(({({1,2,1}),({2,4,2}),({1,2,1})})) - ->apply_matrix(({({1,2,1}),({2,4,2}),({1,2,1})})) - ->modify_by_intensity(1,0,0, 0,255,255,255,255,255)) - -> paste_mask(txt->clone() - ->tuned_box(0,0,txt->xsize()-1,txt->ysize()-1, - ({({128,128,128}),({64,128,0}), - ({64,128,0}),({255,255,0})})), - txt); - write(o->togif_fs()); - return 0; -} diff --git a/src/modules/image/font.c b/src/modules/image/font.c deleted file mode 100644 index 9f398f7c6c21c5593ffeb6446e858c75ecd5cf1d..0000000000000000000000000000000000000000 --- a/src/modules/image/font.c +++ /dev/null @@ -1,572 +0,0 @@ -#include <config.h> - -/* $Id: font.c,v 1.14 1997/02/07 01:41:42 hubbe Exp $ */ - -#include "global.h" - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#ifdef HAVE_SYS_FCNTL_H -#include <sys/fcntl.h> -#endif - -#include <netinet/in.h> -#include <errno.h> - -#include "config.h" - -#include "stralloc.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "threads.h" - -#include "image.h" -#ifdef HAVE_MMAP -#include <sys/mman.h> -#endif - - -static struct program *font_program; -extern struct program *image_program; - -#define THIS (*(struct font **)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -struct font -{ - unsigned long height; /* height of character rectangles */ - unsigned long baseline; /* baseline of characters */ -#ifdef HAVE_MMAP - unsigned long mmaped_size; /* if 0 - not mmaped: just free() mem */ -#endif - void *mem; /* pointer to mmaped/malloced memory */ - unsigned long chars; /* number of characters */ - float xspacing_scale; /* Fraction of spacing to use */ - float yspacing_scale; /* Fraction of spacing to use */ - enum { - J_LEFT, - J_RIGHT, - J_CENTER - } justification; - struct _char - { - unsigned long width; /* character rectangle has this width in pixels */ - unsigned long spacing; /* pixels to next character */ - unsigned char *pixels; /* character rectangle */ - } charinfo [1]; /* many!! */ -}; - -/***************** init & exit *********************************/ - -static inline void free_font_struct(struct font *font) -{ - if (font) - { - if (font->mem) - { -#ifdef HAVE_MMAP - munmap(font->mem,font->mmaped_size); -#else - free(font->mem); -#endif - } - free(font); - } -} - -static void init_font_struct(struct object *o) -{ - THIS=NULL; -} - -static void exit_font_struct(struct object *obj) -{ - free_font_struct(THIS); - THIS=NULL; -} - -/***************** internals ***********************************/ - - -static inline int my_read(int from, char *buf, int towrite) -{ - int res; - while((res = read(from, buf, towrite)) < 0) - { - switch(errno) - { - case EAGAIN: case EINTR: - continue; - - default: - res = 0; - return 0; - } - } - return res; -} - -static inline long file_size(int fd) -{ - struct stat tmp; - int res; - if(!fstat(fd, &tmp)) return res = tmp.st_size; - return -1; -} - -static inline write_char(struct _char *ci, - rgb_group *pos, - INT32 xsize, - INT32 height) -{ - rgb_group *nl; - INT32 x,y; - unsigned char *p; - - p=ci->pixels; - - for (y=height; y>0; y--) - { - nl=pos+xsize; - for (x=(INT32)ci->width; x>0; x--) - { - register char c; - c=255-*p; - if (pos->r==0) - pos->r=pos->g=pos->b=c; - else if (pos->r+c>255) - pos->r=pos->g=pos->b=255; - else - { - pos->r+=c; - pos->g+=c; - pos->b+=c; - } - pos++; - p++; - } - pos=nl; - } -} - -/***************** methods *************************************/ - - -void font_load(INT32 args) -{ - int fd; - - if (args<1 - || sp[-args].type!=T_STRING) - error("font->read: illegal or wrong number of arguments\n"); - - if (THIS) - { - free_font_struct(THIS); - THIS=NULL; - } - do - { -#ifdef FONT_DEBUG - fprintf(stderr,"FONT open '%s'\n",sp[-args].u.string->str); -#endif - fd = open(sp[-args].u.string->str,O_RDONLY); - } while(fd < 0 && errno == EINTR); - - if (fd >= 0) - { - long size; - struct font *new; - - size = file_size(fd); - if (size > 0) - { - new=THIS=(struct font *)xalloc(sizeof(struct font)); - - THREADS_ALLOW(); -#ifdef HAVE_MMAP - new->mem = - mmap(0,size,PROT_READ,MAP_SHARED,fd,0); - new->mmaped_size=size; -#else - new->mem = malloc(size); - if ((new->mem) && (!my_read(fd,new->mem,size))) { - free(new->mem); - new->mem = NULL; - } -#endif - THREADS_DISALLOW(); - - if (THIS->mem) - { - int i; - - struct file_head - { - unsigned INT32 cookie; - unsigned INT32 version; - unsigned INT32 chars; - unsigned INT32 height; - unsigned INT32 baseline; - unsigned INT32 o[1]; - } *fh; - struct char_head - { - unsigned INT32 width; - unsigned INT32 spacing; - unsigned char data[1]; - } *ch; - -#ifdef FONT_DEBUG - fprintf(stderr,"FONT mapped ok\n"); -#endif - - fh=(struct file_head*)THIS->mem; - - if (ntohl(fh->cookie)==0x464f4e54) /* "FONT" */ - { -#ifdef FONT_DEBUG - fprintf(stderr,"FONT cookie ok\n"); -#endif - if (ntohl(fh->version)==1) - { - unsigned long i; - -#ifdef FONT_DEBUG - fprintf(stderr,"FONT version 1\n"); -#endif - - THIS->chars=ntohl(fh->chars); - - new=malloc(sizeof(struct font)+ - sizeof(struct _char)*(THIS->chars-1)); - new->mem=THIS->mem; -#ifdef HAVE_MMAP - new->mmaped_size=THIS->mmaped_size; -#endif - new->chars=THIS->chars; - new->xspacing_scale = 1.0; - new->yspacing_scale = 1.0; - new->justification = J_LEFT; - free(THIS); - THIS=new; - - THIS->height=ntohl(fh->height); - THIS->baseline=ntohl(fh->baseline); - - for (i=0; i<THIS->chars; i++) - { - if (i*sizeof(INT32)<(unsigned long)size - && ntohl(fh->o[i])<(unsigned long)size - && ! ( ntohl(fh->o[i]) % 4) ) /* must be aligned */ - { - ch=(struct char_head*) - ((char *)(THIS->mem)+ntohl(fh->o[i])); - THIS->charinfo[i].width = ntohl(ch->width); - THIS->charinfo[i].spacing = ntohl(ch->spacing); - THIS->charinfo[i].pixels = ch->data; - } - else /* illegal <tm> offset or illegal align */ - { -#ifdef FONT_DEBUG - fprintf(stderr,"FONT failed on char %02xh %d '%c'\n", - i,i,i); -#endif - free_font_struct(new); - THIS=NULL; - pop_n_elems(args); - push_int(0); - return; - } - - } - - close(fd); - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); /* success */ -#ifdef FONT_DEBUG - fprintf(stderr,"FONT successfully loaded\n"); -#endif - return; - } /* wrong version */ -#ifdef FONT_DEBUG - else fprintf(stderr,"FONT unknown version\n"); -#endif - } /* wrong cookie */ -#ifdef FONT_DEBUG - else fprintf(stderr,"FONT wrong cookie\n"); -#endif - } /* mem failure */ -#ifdef FONT_DEBUG - else fprintf(stderr,"FONT mem failure\n"); -#endif - free_font_struct(THIS); - THIS=NULL; - } /* size failure */ -#ifdef FONT_DEBUG - else fprintf(stderr,"FONT size failure\n"); -#endif - close(fd); - } /* fd failure */ -#ifdef FONT_DEBUG - else fprintf(stderr,"FONT fd failure\n"); -#endif - - pop_n_elems(args); - push_int(0); - return; -} - -void font_write(INT32 args) -{ - struct object *o; - struct image *img; - INT32 xsize=0,i,maxwidth,c,maxwidth2,j; - int *width_of; - - if (!THIS) - error("font->write: no font loaded\n"); - - maxwidth2=0; - - width_of=(int *)malloc((args+1)*sizeof(int)); - if(!width_of) - error("Out of memory\n"); - for (j=0; j<args; j++) - { - if (sp[j-args].type!=T_STRING) - error("font->write: illegal argument(s)\n"); - - xsize = 0; - maxwidth = 0; - - for (i = 0; i < sp[j-args].u.string->len; i++) - { - c=EXTRACT_UCHAR(sp[j-args].u.string->str+i); - if (c < (INT32)THIS->chars) - { - if (xsize + (signed long)THIS->charinfo[c].width > maxwidth) - maxwidth = xsize + THIS->charinfo[c].width; - xsize+=(signed long)((float)THIS->charinfo[c].spacing - *(float)THIS->xspacing_scale); - } - } - if (xsize>maxwidth) maxwidth=xsize; - width_of[j]=maxwidth; - if (maxwidth>maxwidth2) maxwidth2=maxwidth; - } - - o = clone(image_program,0); - img = ((struct image*)o->storage); - img->xsize = maxwidth2; - if(args>1) - img->ysize = THIS->height+((double)THIS->height*(double)(args-1)*(double)THIS->yspacing_scale)+1; - else - img->ysize = THIS->height+1; - img->rgb.r=img->rgb.g=img->rgb.b=255; - img->img=malloc(img->xsize*img->ysize*sizeof(rgb_group)); - - if (!img) { free_object(o); free(width_of); error("Out of memory\n"); } - - MEMSET(img->img,0,img->xsize*img->ysize*sizeof(rgb_group)); - - for (j=0; j<args; j++) - { - switch(THIS->justification) - { - case J_LEFT: xsize = 0; break; - case J_RIGHT: xsize = img->xsize-width_of[j]-1; break; - case J_CENTER: xsize = img->xsize/2-width_of[j]/2-1; break; - } - if(xsize<0) xsize=0; - for (i = 0; i < (int)sp[j-args].u.string->len; i++) - { - c=EXTRACT_UCHAR(sp[j-args].u.string->str+i); - if ( c < (INT32)THIS->chars) - { - write_char(THIS->charinfo+c, - (img->img+xsize)+(img->xsize*(int)(j*THIS->height - *THIS->yspacing_scale)), - img->xsize, - THIS->height); - xsize += THIS->charinfo[c].spacing*THIS->xspacing_scale; - } - } - } - free(width_of); - pop_n_elems(args); - push_object(o); -} - -void font_height(INT32 args) -{ - pop_n_elems(args); - if (THIS) - push_int(THIS->height); - else - push_int(0); -} - -void font_text_extents(INT32 args) -{ - INT32 xsize,i,maxwidth,c,maxwidth2,j; - - if (!THIS) - error("font->text_extents: no font loaded\n"); - - maxwidth2=0; - - for (j=0; j<args; j++) - { - if (sp[j-args].type!=T_STRING) - error("font->text_extents: illegal argument(s)\n"); - - xsize = 0; - maxwidth = 0; - - for (i = 0; i < sp[j-args].u.string->len; i++) - { - c=EXTRACT_UCHAR(sp[j-args].u.string->str+i); - if (c < (INT32)THIS->chars) - { - if (xsize + (signed long)THIS->charinfo[c].width > maxwidth) - maxwidth = xsize + THIS->charinfo[c].width; - xsize += THIS->charinfo[c].spacing*THIS->xspacing_scale; - } - } - - if (xsize>maxwidth) maxwidth=xsize; - if (maxwidth>maxwidth2) maxwidth2=maxwidth; - } - push_int(maxwidth2); - push_int(args * THIS->height * THIS->yspacing_scale); -} - - -void font_set_xspacing_scale(INT32 args) -{ - if(!THIS) error("font->set_xspacing_scale(FLOAT): No font loaded.\n"); - if(!args) error("font->set_xspacing_scale(FLOAT): No argument!\n"); - if(sp[-args].type!=T_FLOAT) - error("font->set_xspacing_scale(FLOAT): Wrong type of argument!\n"); - - THIS->xspacing_scale = (double)sp[-args].u.float_number; -/*fprintf(stderr, "Setting xspacing to %f\n", THIS->xspacing_scale);*/ - if(THIS->xspacing_scale < 0.0) - THIS->xspacing_scale=0.1; - pop_stack(); -} - - -void font_set_yspacing_scale(INT32 args) -{ - if(!THIS) error("font->set_yspacing_scale(FLOAT): No font loaded.\n"); - if(!args) error("font->set_yspacing_scale(FLOAT): No argument!\n"); - if(sp[-args].type!=T_FLOAT) - error("font->set_yspacing_scale(FLOAT): Wrong type of argument!\n"); - - THIS->yspacing_scale = (double)sp[-args].u.float_number; -/*fprintf(stderr, "Setting yspacing to %f\n", THIS->yspacing_scale);*/ - if(THIS->yspacing_scale <= 0.0) - THIS->yspacing_scale=0.1; - pop_stack(); -} - -void font_baseline(INT32 args) -{ - pop_n_elems(args); - if (THIS) - push_int(THIS->baseline); - else - push_int(0); -} - -void font_set_center(INT32 args) -{ - pop_n_elems(args); - if(THIS) THIS->justification=J_CENTER; -} - -void font_set_right(INT32 args) -{ - pop_n_elems(args); - if(THIS) THIS->justification=J_RIGHT; -} - -void font_set_left(INT32 args) -{ - pop_n_elems(args); - if(THIS) THIS->justification=J_LEFT; -} - - -/***************** global init etc *****************************/ - -/* - -int load(string filename); // load font file, true is success -object write(string text); // new image object -int height(); // font heigth -int baseline(); // font baseline - -*/ - -void init_font_programs(void) -{ - start_new_program(); - add_storage(sizeof(struct font*)); - - add_function("load",font_load, - "function(string:int)",0); - - add_function("write",font_write, - "function(string:object)",0); - - add_function("height",font_height, - "function(:int)",0); - - add_function("baseline",font_baseline, - "function(:int)",0); - - add_function("extents",font_text_extents, - "function(string ...:array(int))",0); - - add_function("set_x_spacing",font_set_xspacing_scale, - "function(float:void)",0); - - add_function("set_y_spacing",font_set_yspacing_scale, - "function(float:void)",0); - - add_function("center", font_set_center, "function(void:void)", 0); - add_function("left", font_set_left, "function(void:void)", 0); - add_function("right", font_set_right, "function(void:void)", 0); - - - set_init_callback(init_font_struct); - set_exit_callback(exit_font_struct); - - font_program=end_program(); - add_program_constant("font",font_program, 0); -} - -void exit_font(void) -{ - if(font_program) - { - free_program(font_program); - font_program=0; - } -} - - diff --git a/src/modules/image/image.c b/src/modules/image/image.c deleted file mode 100644 index 03d346d4f323eeeaa4d9c8720a9e162d45e6798d..0000000000000000000000000000000000000000 --- a/src/modules/image/image.c +++ /dev/null @@ -1,1805 +0,0 @@ -/* $Id: image.c,v 1.40 1997/02/07 01:41:42 hubbe Exp $ */ - -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -RCSID("$Id: image.c,v 1.40 1997/02/07 01:41:42 hubbe Exp $"); -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "threads.h" -#include "array.h" -#include "error.h" - -#include "image.h" -#include "builtin_functions.h" - -struct program *image_program; -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) -#define testrange(x) max(min((x),255),0) - -#define sq(x) ((x)*(x)) - -#define CIRCLE_STEPS 128 -static INT32 circle_sin_table[CIRCLE_STEPS]; -#define circle_sin(x) circle_sin_table[((x)+CIRCLE_STEPS)%CIRCLE_STEPS] -#define circle_cos(x) circle_sin((x)-CIRCLE_STEPS/4) - -#define circle_sin_mul(x,y) ((circle_sin(x)*(y))/4096) -#define circle_cos_mul(x,y) ((circle_cos(x)*(y))/4096) - - - -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - - -/***************** init & exit *********************************/ - -static int obj_counter=0; - -static void init_image_struct(struct object *obj) -{ - THIS->img=NULL; - THIS->rgb.r=0; - THIS->rgb.g=0; - THIS->rgb.b=0; -/* fprintf(stderr,"init %lx (%d)\n",obj,++obj_counter);*/ -} - -static void exit_image_struct(struct object *obj) -{ - if (THIS->img) { free(THIS->img); THIS->img=NULL; } -/* - fprintf(stderr,"exit %lx (%d) %dx%d=%.1fKb\n",obj,--obj_counter, - THIS->xsize,THIS->ysize, - (THIS->xsize*THIS->ysize*3+sizeof(struct image))/1024.0); - */ -} - -/***************** internals ***********************************/ - -#define apply_alpha(x,y,alpha) \ - ((unsigned char)((y*(255L-(alpha))+x*(alpha))/255L)) - -#define set_rgb_group_alpha(dest,src,alpha) \ - ((dest).r=apply_alpha((dest).r,(src).r,alpha), \ - (dest).g=apply_alpha((dest).g,(src).g,alpha), \ - (dest).b=apply_alpha((dest).b,(src).b,alpha)) - -#define pixel(_img,x,y) ((_img)->img[(x)+(y)*(_img)->xsize]) - -#define setpixel(x,y) \ - (THIS->alpha? \ - set_rgb_group_alpha(THIS->img[(x)+(y)*THIS->xsize],THIS->rgb,THIS->alpha): \ - ((pixel(THIS,x,y)=THIS->rgb),0)) - -#define setpixel_test(x,y) \ - (((x)<0||(y)<0||(x)>=THIS->xsize||(y)>=THIS->ysize)? \ - 0:(setpixel(x,y),0)) - -static INLINE void getrgb(struct image *img, - INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; - img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; - img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; - if (args-args_start>=4) - if (sp[3-args+args_start].type!=T_INT) - error("Illegal alpha argument to %s\n",name); - else - img->alpha=sp[3-args+args_start].u.integer; - else - img->alpha=0; -} - -static INLINE void getrgbl(rgbl_group *rgb,INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - rgb->r=sp[-args+args_start].u.integer; - rgb->g=sp[1-args+args_start].u.integer; - rgb->b=sp[2-args+args_start].u.integer; -} - -static INLINE void img_line(INT32 x1,INT32 y1,INT32 x2,INT32 y2) -{ - INT32 pixelstep,pos; - if (x1==x2) - { - if (y1>y2) y1^=y2,y2^=y1,y1^=y2; - if (x1<0||x1>=THIS->xsize|| - y2<0||y1>=THIS->ysize) return; - if (y1<0) y1=0; - if (y2>=THIS->ysize) y2=THIS->ysize-1; - for (;y1<=y2;y1++) setpixel_test(x1,y1); - return; - } - else if (y1==y2) - { - if (x1>x2) x1^=x2,x2^=x1,x1^=x2; - if (y1<0||y1>=THIS->ysize|| - x2<0||x1>=THIS->xsize) return; - if (x1<0) x1=0; - if (x2>=THIS->xsize) x2=THIS->xsize-1; - for (;x1<=x2;x1++) setpixel_test(x1,y1); - return; - } - else if (abs(x2-x1)<abs(y2-y1)) /* mostly vertical line */ - { - if (y1>y2) y1^=y2,y2^=y1,y1^=y2, - x1^=x2,x2^=x1,x1^=x2; - pixelstep=((x2-x1)*1024)/(y2-y1); - pos=x1*1024; - for (;y1<=y2;y1++) - { - setpixel_test((pos+512)/1024,y1); - pos+=pixelstep; - } - } - else /* mostly horisontal line */ - { - if (x1>x2) y1^=y2,y2^=y1,y1^=y2, - x1^=x2,x2^=x1,x1^=x2; - pixelstep=((y2-y1)*1024)/(x2-x1); - pos=y1*1024; - for (;x1<=x2;x1++) - { - setpixel_test(x1,(pos+512)/1024); - pos+=pixelstep; - } - } -} - -static INLINE rgb_group _pixel_apply_matrix(struct image *img, - int x,int y, - int width,int height, - rgbd_group *matrix, - rgb_group default_rgb, - double div) -{ - rgb_group res; - int i,j,bx,by,xp,yp; - int sumr,sumg,sumb,r,g,b; - float qdiv=1.0/div; - - sumr=sumg=sumb=0; - r=g=b=0; - - bx=width/2; - by=height/2; - - for (xp=x-bx,i=0; i<width; i++,xp++) - for (yp=y-by,j=0; j<height; j++,yp++) - if (xp>=0 && xp<img->xsize && yp>=0 && yp<img->ysize) - { - r+=matrix[i+j*width].r*img->img[xp+yp*img->xsize].r; - g+=matrix[i+j*width].g*img->img[xp+yp*img->xsize].g; - b+=matrix[i+j*width].b*img->img[xp+yp*img->xsize].b; -#ifdef MATRIX_DEBUG - fprintf(stderr,"%d,%d %d,%d->%d,%d,%d\n", - i,j,xp,yp, - img->img[x+i+(y+j)*img->xsize].r, - img->img[x+i+(y+j)*img->xsize].g, - img->img[x+i+(y+j)*img->xsize].b); -#endif - sumr+=matrix[i+j*width].r; - sumg+=matrix[i+j*width].g; - sumb+=matrix[i+j*width].b; - } - if (sumr) res.r=testrange(default_rgb.r+r/(sumr*div)); - else res.r=testrange(r*qdiv+default_rgb.r); - if (sumg) res.g=testrange(default_rgb.g+g/(sumg*div)); - else res.g=testrange(g*qdiv+default_rgb.g); - if (sumb) res.b=testrange(default_rgb.g+b/(sumb*div)); - else res.b=testrange(b*qdiv+default_rgb.b); -#ifdef MATRIX_DEBUG - fprintf(stderr,"->%d,%d,%d\n",res.r,res.g,res.b); -#endif - return res; -} - - -void img_apply_matrix(struct image *dest, - struct image *img, - int width,int height, - rgbd_group *matrix, - rgb_group default_rgb, - double div) -{ - rgb_group *d,*ip,*dp; - rgbd_group *mp; - int i,j,x,y,bx,by,ex,ey,xp,yp; - int sumr,sumg,sumb; - double qr,qg,qb; - register double r=0,g=0,b=0; - -THREADS_ALLOW(); - - sumr=sumg=sumb=0; - for (i=0; i<width; i++) - for (j=0; j<height; j++) - { - sumr+=matrix[i+j*width].r; - sumg+=matrix[i+j*width].g; - sumb+=matrix[i+j*width].b; - } - - if (!sumr) sumr=1; sumr*=div; qr=1.0/sumr; - if (!sumg) sumg=1; sumg*=div; qg=1.0/sumg; - if (!sumb) sumb=1; sumb*=div; qb=1.0/sumb; - - bx=width/2; - by=height/2; - ex=width-bx; - ey=height-by; - - d=malloc(sizeof(rgb_group)*img->xsize*img->ysize +1); - - if(!d) error("Out of memory.\n"); - -CHRONO("apply_matrix, one"); - - for (y=by; y<img->ysize-ey; y++) - { - dp=d+y*img->xsize+by; - for (x=bx; x<img->xsize-ex; x++) - { - r=g=b=0; - mp=matrix; - for (yp=y-by,j=0; j<height; j++,yp++) - { - ip=img->img+(x-bx)+yp*img->xsize; - for (i=0; i<width; i++) - { - r+=ip->r*mp->r; - g+=ip->g*mp->g; - b+=ip->b*mp->b; -#ifdef MATRIX_DEBUG - fprintf(stderr,"%d,%d ->%d,%d,%d\n", - i,j, - img->img[x+i+(y+j)*img->xsize].r, - img->img[x+i+(y+j)*img->xsize].g, - img->img[x+i+(y+j)*img->xsize].b); -#endif - mp++; - ip++; - } - } -#ifdef MATRIX_DEBUG - fprintf(stderr,"->%d,%d,%d\n",r/sumr,g/sumg,b/sumb); -#endif - r=default_rgb.r+(int)(r*qr+0.5); dp->r=testrange(r); - g=default_rgb.g+(int)(g*qg+0.5); dp->g=testrange(g); - b=default_rgb.b+(int)(b*qb+0.5); dp->b=testrange(b); - dp++; - } - } - -CHRONO("apply_matrix, two"); - - for (y=0; y<img->ysize; y++) - { - for (x=0; x<bx; x++) - d[x+y*img->xsize]=_pixel_apply_matrix(img,x,y,width,height, - matrix,default_rgb,div); - for (x=img->xsize-ex; x<img->xsize; x++) - d[x+y*img->xsize]=_pixel_apply_matrix(img,x,y,width,height, - matrix,default_rgb,div); - } - - for (x=0; x<img->xsize; x++) - { - for (y=0; y<by; y++) - d[x+y*img->xsize]=_pixel_apply_matrix(img,x,y,width,height, - matrix,default_rgb,div); - for (y=img->ysize-ey; y<img->ysize; y++) - d[x+y*img->xsize]=_pixel_apply_matrix(img,x,y,width,height, - matrix,default_rgb,div); - } - -CHRONO("apply_matrix, three"); - - if (dest->img) free(dest->img); - *dest=*img; - dest->img=d; - -THREADS_DISALLOW(); -} - -/***************** methods *************************************/ - -void image_create(INT32 args) -{ - if (args<2) return; - if (sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT) - error("Illegal arguments to image->clone()\n"); - - getrgb(THIS,2,args,"image->create()"); - - if (THIS->img) free(THIS->img); - - THIS->xsize=sp[-args].u.integer; - THIS->ysize=sp[1-args].u.integer; - if (THIS->xsize<0) THIS->xsize=0; - if (THIS->ysize<0) THIS->ysize=0; - - THIS->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize +1); - if (!THIS->img) - error("out of memory\n"); - - - img_clear(THIS->img,THIS->rgb,THIS->xsize*THIS->ysize); - pop_n_elems(args); -} - -void image_clone(INT32 args) -{ - struct object *o; - struct image *img; - - if (args) - if (args<2|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT) - error("Illegal arguments to image->clone()\n"); - - o=clone(image_program,0); - img=(struct image*)(o->storage); - *img=*THIS; - - if (args) - { - if(sp[-args].u.integer < 0 || - sp[1-args].u.integer < 0) - error("Illegal size to image->clone()\n"); - img->xsize=sp[-args].u.integer; - img->ysize=sp[1-args].u.integer; - } - - getrgb(img,2,args,"image->clone()"); - - if (img->xsize<0) img->xsize=1; - if (img->ysize<0) img->ysize=1; - - img->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize +1); - if (THIS->img) - { - if (!img->img) - { - free_object(o); - error("out of memory\n"); - } - if (img->xsize==THIS->xsize - && img->ysize==THIS->ysize) - MEMCPY(img->img,THIS->img,sizeof(rgb_group)*img->xsize*img->ysize); - else - img_crop(img,THIS, - 0,0,img->xsize-1,img->ysize-1); - - } - else - img_clear(img->img,img->rgb,img->xsize*img->ysize); - - pop_n_elems(args); - push_object(o); -} - -void image_clear(INT32 args) -{ - struct object *o; - struct image *img; - - o=clone(image_program,0); - img=(struct image*)(o->storage); - *img=*THIS; - - getrgb(img,0,args,"image->clear()"); - - img->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize +1); - if (!img->img) - { - free_object(o); - error("out of memory\n"); - } - - img_clear(img->img,img->rgb,img->xsize*img->ysize); - - pop_n_elems(args); - push_object(o); -} - -void image_copy(INT32 args) -{ - struct object *o; - struct image *img; - - if (!args) - { - o=clone(image_program,0); - if (THIS->img) img_clone((struct image*)o->storage,THIS); - pop_n_elems(args); - push_object(o); - return; - } - if (args<4|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT|| - sp[2-args].type!=T_INT|| - sp[3-args].type!=T_INT) - error("illegal arguments to image->copy()\n"); - - if (!THIS->img) error("no image\n"); - - getrgb(THIS,2,args,"image->crop()"); - - o=clone(image_program,0); - img=(struct image*)(o->storage); - - img_crop(img,THIS, - sp[-args].u.integer,sp[1-args].u.integer, - sp[2-args].u.integer,sp[3-args].u.integer); - - pop_n_elems(args); - push_object(o); -} - -static void image_change_color(INT32 args) - -{ - /* ->change_color([int from-r,g,b,] int to-r,g,b); */ - rgb_group from,to,*s,*d; - INT32 left; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - if (args<3) error("too few arguments to image->change_color()\n"); - - if (args<6) - { - to=THIS->rgb; - getrgb(THIS,0,args,"image->change_color()"); - from=THIS->rgb; - } - else - { - getrgb(THIS,0,args,"image->change_color()"); - from=THIS->rgb; - getrgb(THIS,3,args,"image->change_color()"); - to=THIS->rgb; - } - - o=clone(image_program,0); - img=(struct image*)(o->storage); - *img=*THIS; - - if (!(img->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize +1))) - { - free_object(o); - error("out of memory\n"); - } - - left=THIS->xsize*THIS->ysize; - s=THIS->img; - d=img->img; - while (left--) - { - if (s->r==from.r && s->g==from.g && s->b==from.b) - *d=to; - else - *d=*s; - d++; s++; - } - - pop_n_elems(args); - push_object(o); -} - -static INLINE int try_autocrop_vertical(INT32 x,INT32 y,INT32 y2, - INT32 rgb_set,rgb_group *rgb) -{ - if (!rgb_set) *rgb=pixel(THIS,x,y); - for (;y<=y2; y++) - if (pixel(THIS,x,y).r!=rgb->r || - pixel(THIS,x,y).g!=rgb->g || - pixel(THIS,x,y).b!=rgb->b) return 0; - return 1; -} - -static INLINE int try_autocrop_horisontal(INT32 y,INT32 x,INT32 x2, - INT32 rgb_set,rgb_group *rgb) -{ - if (!rgb_set) *rgb=pixel(THIS,x,y); - for (;x<=x2; x++) - if (pixel(THIS,x,y).r!=rgb->r || - pixel(THIS,x,y).g!=rgb->g || - pixel(THIS,x,y).b!=rgb->b) return 0; - return 1; -} - -void image_autocrop(INT32 args) -{ - INT32 border=0,x1,y1,x2,y2; - rgb_group rgb; - int rgb_set=0,done; - struct object *o; - struct image *img; - int left=1,right=1,top=1,bottom=1; - - if (args) - if (sp[-args].type!=T_INT) - error("Illegal argument to image->autocrop()\n"); - else - border=sp[-args].u.integer; - - if (args>=5) - { - left=!(sp[1-args].type==T_INT && sp[1-args].u.integer==0); - right=!(sp[2-args].type==T_INT && sp[2-args].u.integer==0); - top=!(sp[3-args].type==T_INT && sp[3-args].u.integer==0); - bottom=!(sp[4-args].type==T_INT && sp[4-args].u.integer==0); - getrgb(THIS,5,args,"image->autocrop()"); - } - else getrgb(THIS,1,args,"image->autocrop()"); - - if (!THIS->img) - { - error("no image\n"); - return; - } - - x1=y1=0; - x2=THIS->xsize-1; - y2=THIS->ysize-1; - - while (x2>x1 && y2>y1) - { - done=0; - if (left && - try_autocrop_vertical(x1,y1,y2,rgb_set,&rgb)) x1++,done=rgb_set=1; - if (right && - x2>x1 && - try_autocrop_vertical(x2,y1,y2,rgb_set,&rgb)) x2--,done=rgb_set=1; - if (top && - try_autocrop_horisontal(y1,x1,x2,rgb_set,&rgb)) y1++,done=rgb_set=1; - if (bottom && - y2>y1 && - try_autocrop_horisontal(y2,x1,x2,rgb_set,&rgb)) y2--,done=rgb_set=1; - if (!done) break; - } - - o=clone(image_program,0); - img=(struct image*)(o->storage); - - img_crop(img,THIS,x1-border,y1-border,x2+border,y2+border); - - pop_n_elems(args); - push_object(o); -} - - -void image_setcolor(INT32 args) -{ - if (args<3) - error("illegal arguments to image->setcolor()\n"); - getrgb(THIS,0,args,"image->setcolor()"); - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_setpixel(INT32 args) -{ - INT32 x,y; - if (args<2|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT) - error("Illegal arguments to image->setpixel()\n"); - getrgb(THIS,2,args,"image->setpixel()"); - if (!THIS->img) return; - x=sp[-args].u.integer; - y=sp[1-args].u.integer; - if (!THIS->img) return; - setpixel_test(x,y); - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_getpixel(INT32 args) -{ - INT32 x,y; - rgb_group rgb; - - if (args<2|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT) - error("Illegal arguments to image->getpixel()\n"); - - if (!THIS->img) error("No image.\n"); - - x=sp[-args].u.integer; - y=sp[1-args].u.integer; - if (!THIS->img) return; - if(x<0||y<0||x>=THIS->xsize||y>=THIS->ysize) - rgb=THIS->rgb; - else - rgb=pixel(THIS,x,y); - - pop_n_elems(args); - push_int(rgb.r); - push_int(rgb.g); - push_int(rgb.b); - f_aggregate(3); -} - -void image_line(INT32 args) -{ - if (args<4|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT|| - sp[2-args].type!=T_INT|| - sp[3-args].type!=T_INT) - error("Illegal arguments to image->line()\n"); - getrgb(THIS,4,args,"image->line()"); - if (!THIS->img) return; - - img_line(sp[-args].u.integer, - sp[1-args].u.integer, - sp[2-args].u.integer, - sp[3-args].u.integer); - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_box(INT32 args) -{ - if (args<4|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT|| - sp[2-args].type!=T_INT|| - sp[3-args].type!=T_INT) - error("Illegal arguments to image->box()\n"); - getrgb(THIS,4,args,"image->box()"); - if (!THIS->img) return; - - img_box(sp[-args].u.integer, - sp[1-args].u.integer, - sp[2-args].u.integer, - sp[3-args].u.integer); - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_circle(INT32 args) -{ - INT32 x,y,rx,ry; - INT32 i; - - if (args<4|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT|| - sp[2-args].type!=T_INT|| - sp[3-args].type!=T_INT) - error("illegal arguments to image->circle()\n"); - getrgb(THIS,4,args,"image->circle()"); - if (!THIS->img) return; - - x=sp[-args].u.integer; - y=sp[1-args].u.integer; - rx=sp[2-args].u.integer; - ry=sp[3-args].u.integer; - - for (i=0; i<CIRCLE_STEPS; i++) - img_line(x+circle_sin_mul(i,rx), - y+circle_cos_mul(i,ry), - x+circle_sin_mul(i+1,rx), - y+circle_cos_mul(i+1,ry)); - THISOBJ->refs++; - push_object(THISOBJ); -} - -static INLINE void get_rgba_group_from_array_index(rgba_group *rgba,struct array *v,INT32 index) -{ - struct svalue s,s2; - array_index_no_free(&s,v,index); - if (s.type!=T_ARRAY|| - s.u.array->size<3) - rgba->r=rgba->b=rgba->g=rgba->alpha=0; - else - { - array_index_no_free(&s2,s.u.array,0); - if (s2.type!=T_INT) rgba->r=0; else rgba->r=s2.u.integer; - array_index(&s2,s.u.array,1); - if (s2.type!=T_INT) rgba->g=0; else rgba->g=s2.u.integer; - array_index(&s2,s.u.array,2); - if (s2.type!=T_INT) rgba->b=0; else rgba->b=s2.u.integer; - if (s.u.array->size>=4) - { - array_index(&s2,s.u.array,3); - if (s2.type!=T_INT) rgba->alpha=0; else rgba->alpha=s2.u.integer; - } - else rgba->alpha=0; - free_svalue(&s2); - } - free_svalue(&s); - return; -} - -static INLINE void - add_to_rgba_sum_with_factor(rgba_group *sum, - rgba_group rgba, - float factor) -{ - sum->r=testrange(sum->r+(INT32)(rgba.r*factor+0.5)); - sum->g=testrange(sum->g+(INT32)(rgba.g*factor+0.5)); - sum->b=testrange(sum->b+(INT32)(rgba.b*factor+0.5)); - sum->alpha=testrange(sum->alpha+(INT32)(rgba.alpha*factor+0.5)); -} - -static INLINE void - add_to_rgb_sum_with_factor(rgb_group *sum, - rgba_group rgba, - float factor) -{ - sum->r=testrange(sum->r+(INT32)(rgba.r*factor+0.5)); - sum->g=testrange(sum->g+(INT32)(rgba.g*factor+0.5)); - sum->b=testrange(sum->b+(INT32)(rgba.b*factor+0.5)); -} - -void image_tuned_box(INT32 args) -{ - INT32 x1,y1,x2,y2,xw,yw,x,y; - rgba_group topleft,topright,bottomleft,bottomright,sum,sumzero={0,0,0,0}; - rgb_group *img; - struct image *this; - - if (args<5|| - sp[-args].type!=T_INT|| - sp[1-args].type!=T_INT|| - sp[2-args].type!=T_INT|| - sp[3-args].type!=T_INT|| - sp[4-args].type!=T_ARRAY|| - sp[4-args].u.array->size<4) - error("Illegal number of arguments to image->tuned_box()\n"); - - if (!THIS->img) - error("no image\n"); - - x1=sp[-args].u.integer; - y1=sp[1-args].u.integer; - x2=sp[2-args].u.integer; - y2=sp[3-args].u.integer; - - get_rgba_group_from_array_index(&topleft,sp[4-args].u.array,0); - get_rgba_group_from_array_index(&topright,sp[4-args].u.array,1); - get_rgba_group_from_array_index(&bottomleft,sp[4-args].u.array,2); - get_rgba_group_from_array_index(&bottomright,sp[4-args].u.array,3); - - if (x1>x2) x1^=x2,x2^=x1,x1^=x2, - sum=topleft,topleft=topright,topright=sum, - sum=bottomleft,bottomleft=bottomright,bottomright=sum; - if (y1>y2) y1^=y2,y2^=y1,y1^=y2, - sum=topleft,topleft=bottomleft,bottomleft=sum, - sum=topright,topright=bottomright,bottomright=sum; - if (x2<0||y2<0||x1>=THIS->xsize||y1>=THIS->ysize) return; - - xw=x2-x1; - yw=y2-y1; - - this=THIS; - THREADS_ALLOW(); - - for (x=max(0,-x1); x<=xw && x+x1<THIS->xsize; x++) - { -#define tune_factor(a,aw) (1.0-((float)(a)/(aw))) - INT32 ymax; - float tfx1=tune_factor(x,xw); - float tfx2=tune_factor(xw-x,xw); - - ymax=min(yw,this->ysize-y1); - img=this->img+x+x1+this->xsize*max(0,y1); - if (topleft.alpha||topright.alpha||bottomleft.alpha||bottomright.alpha) - for (y=max(0,-y1); y<ymax; y++) - { - float tfy; - sum=sumzero; - - add_to_rgba_sum_with_factor(&sum,topleft,(tfy=tune_factor(y,yw))*tfx1); - add_to_rgba_sum_with_factor(&sum,topright,tfy*tfx2); - add_to_rgba_sum_with_factor(&sum,bottomleft,(tfy=tune_factor(yw-y,yw))*tfx1); - add_to_rgba_sum_with_factor(&sum,bottomright,tfy*tfx2); - - set_rgb_group_alpha(*img, sum,sum.alpha); - img+=this->xsize; - } - else - for (y=max(0,-y1); y<ymax; y++) - { - float tfy; - rgb_group sum={0,0,0}; - - add_to_rgb_sum_with_factor(&sum,topleft,(tfy=tune_factor(y,yw))*tfx1); - add_to_rgb_sum_with_factor(&sum,topright,tfy*tfx2); - add_to_rgb_sum_with_factor(&sum,bottomleft,(tfy=tune_factor(yw-y,yw))*tfx1); - add_to_rgb_sum_with_factor(&sum,bottomright,tfy*tfx2); - - *img=sum; - img+=this->xsize; - } - - } - THREADS_DISALLOW(); - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -void image_xsize(INT32 args) -{ - pop_n_elems(args); - if (THIS->img) push_int(THIS->xsize); else push_int(0); -} - -void image_ysize(INT32 args) -{ - pop_n_elems(args); - if (THIS->img) push_int(THIS->ysize); else push_int(0); -} - -void image_gray(INT32 args) -{ - INT32 x,y,div; - rgbl_group rgb; - rgb_group *d,*s; - struct object *o; - struct image *img; - - if (args<3) - { - rgb.r=87; - rgb.g=127; - rgb.b=41; - } - else - getrgbl(&rgb,0,args,"image->gray()"); - div=rgb.r+rgb.g+rgb.b; - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - d=img->img; - s=THIS->img; - x=THIS->xsize*THIS->ysize; - THREADS_ALLOW(); - while (x--) - { - d->r=d->g=d->b= - testrange( ((((long)s->r)*rgb.r+ - ((long)s->g)*rgb.g+ - ((long)s->b)*rgb.b)/div) ); - d++; - s++; - } - THREADS_DISALLOW(); - pop_n_elems(args); - push_object(o); -} - -void image_color(INT32 args) -{ - INT32 x,y; - rgbl_group rgb; - rgb_group *s,*d; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - if (args<3) - { - if (args>0 && sp[-args].type==T_INT) - rgb.r=rgb.b=rgb.g=sp[-args].u.integer; - else - rgb.r=THIS->rgb.r, - rgb.g=THIS->rgb.g, - rgb.b=THIS->rgb.b; - } - else - getrgbl(&rgb,0,args,"image->color()"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - d=img->img; - s=THIS->img; - - x=THIS->xsize*THIS->ysize; - - THREADS_ALLOW(); - while (x--) - { - d->r=testrange( (((long)rgb.r*s->r)/255) ); - d->g=testrange( (((long)rgb.g*s->g)/255) ); - d->b=testrange( (((long)rgb.b*s->b)/255) ); - d++; - s++; - } - THREADS_DISALLOW(); - - pop_n_elems(args); - push_object(o); -} - -void image_invert(INT32 args) -{ - INT32 x,y; - rgb_group *s,*d; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - d=img->img; - s=THIS->img; - - x=THIS->xsize*THIS->ysize; - THREADS_ALLOW(); - while (x--) - { - d->r=testrange( 255-s->r ); - d->g=testrange( 255-s->g ); - d->b=testrange( 255-s->b ); - d++; - s++; - } - THREADS_DISALLOW(); - - pop_n_elems(args); - push_object(o); -} - -void image_threshold(INT32 args) -{ - INT32 x,y; - rgb_group *s,*d,rgb; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - - getrgb(THIS,0,args,"image->threshold()"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - d=img->img; - s=THIS->img; - rgb=THIS->rgb; - - x=THIS->xsize*THIS->ysize; - THREADS_ALLOW(); - while (x--) - { - if (s->r>=rgb.r && - s->g>=rgb.g && - s->b>=rgb.b) - d->r=d->g=d->b=255; - else - d->r=d->g=d->b=0; - - d++; - s++; - } - THREADS_DISALLOW(); - - pop_n_elems(args); - push_object(o); -} - -void image_distancesq(INT32 args) -{ - INT32 i; - rgb_group *s,*d,rgb; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - - getrgb(THIS,0,args,"image->threshold()"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - d=img->img; - s=THIS->img; - rgb=THIS->rgb; - - THREADS_ALLOW(); - i=img->xsize*img->ysize; - while (i--) - { -#define DISTANCE(A,B) \ - (sq((long)(A).r-(B).r)+sq((long)(A).g-(B).g)+sq((long)(A).b-(B).b)) - d->r=d->g=d->b=testrange(DISTANCE(*s,rgb)>>8); - d++; s++; - } - THREADS_DISALLOW(); - - pop_n_elems(args); - push_object(o); -} - -/*#define DEBUG_ISF*/ -#define ISF_LEFT 4 -#define ISF_RIGHT 8 - -void isf_seek(int mode,int ydir,INT32 low_limit,INT32 x1,INT32 x2,INT32 y, - rgb_group *src,rgb_group *dest,INT32 xsize,INT32 ysize, - rgb_group rgb,int reclvl) -{ - INT32 x,xr; - INT32 j; - -#ifdef DEBUG_ISF - fprintf(stderr,"isf_seek reclvl=%d mode=%d, ydir=%d, low_limit=%d, x1=%d, x2=%d, y=%d, src=%lx, dest=%lx, xsize=%d, ysize=%d, rgb=%d,%d,%d\n",reclvl, - mode,ydir,low_limit,x1,x2,y,src,dest,xsize,ysize,rgb.r,rgb.g,rgb.b); -#endif - -#define MARK_DISTANCE(_dest,_value) \ - ((_dest).r=(_dest).g=(_dest).b=(max(1,255-(_value>>8)))) - if ( mode&ISF_LEFT ) /* scan left from x1 */ - { - x=x1; - while (x>0) - { - x--; -#ifdef DEBUG_ISF -fprintf(stderr,"<-- %d (",DISTANCE(rgb,src[x+y*xsize])); -fprintf(stderr," %d,%d,%d)\n",src[x+y*xsize].r,src[x+y*xsize].g,src[x+y*xsize].b); -#endif - if ( (j=DISTANCE(rgb,src[x+y*xsize])) >low_limit) - { - x++; - break; - } - else - { - if (dest[x+y*xsize].r) { x++; break; } /* been there */ - MARK_DISTANCE(dest[x+y*xsize],j); - } - } - if (x1>x) - { - isf_seek(ISF_LEFT,-ydir,low_limit, - x,x1-1,y,src,dest,xsize,ysize,rgb,reclvl+1); - } - x1=x; - } - if ( mode&ISF_RIGHT ) /* scan right from x2 */ - { - x=x2; - while (x<xsize-1) - { - x++; -#ifdef DEBUG_ISF -fprintf(stderr,"--> %d (",DISTANCE(rgb,src[x+y*xsize])); -fprintf(stderr," %d,%d,%d)\n",src[x+y*xsize].r,src[x+y*xsize].g,src[x+y*xsize].b); -#endif - if ( (j=DISTANCE(rgb,src[x+y*xsize])) >low_limit) - { - x--; - break; - } - else - { - if (dest[x+y*xsize].r) { x--; break; } /* done that */ - MARK_DISTANCE(dest[x+y*xsize],j); - } - } - if (x2<x) - { - isf_seek(ISF_RIGHT,-ydir,low_limit, - x2+1,x,y,src,dest,xsize,ysize,rgb,reclvl+1); - } - x2=x; - } - xr=x=x1; - y+=ydir; - if (y<0 || y>=ysize) return; - while (x<=x2) - { -#ifdef DEBUG_ISF -fprintf(stderr,"==> %d (",DISTANCE(rgb,src[x+y*xsize])); -fprintf(stderr," %d,%d,%d)\n",src[x+y*xsize].r,src[x+y*xsize].g,src[x+y*xsize].b); -#endif - if ( dest[x+y*xsize].r || /* seen that */ - (j=DISTANCE(rgb,src[x+y*xsize])) >low_limit) - { - if (xr<x) - isf_seek(ISF_LEFT*(xr==x1),ydir,low_limit, - xr,x-1,y,src,dest,xsize,ysize,rgb,reclvl+1); - while (++x<=x2) - if ( (j=DISTANCE(rgb,src[x+y*xsize])) <=low_limit) break; - xr=x; -/* x++; hokuspokus /law */ -/* n�n dag ska jag f�rs�ka begripa varf�r... */ - if (x>x2) return; - continue; - } - MARK_DISTANCE(dest[x+y*xsize],j); - x++; - } - if (x>xr) - isf_seek((ISF_LEFT*(xr==x1))|ISF_RIGHT,ydir,low_limit, - xr,x-1,y,src,dest,xsize,ysize,rgb,reclvl+1); -} - -void image_select_from(INT32 args) -{ - struct object *o; - struct image *img; - INT32 low_limit=0; - - if (!THIS->img) error("no image\n"); - - if (args<2 - || sp[-args].type!=T_INT - || sp[1-args].type!=T_INT) - error("Illegal argument(s) to image->select_from()\n"); - - if (args>=3) - if (sp[2-args].type!=T_INT) - error("Illegal argument 3 (edge type) to image->select_from()\n"); - else - low_limit=max(0,sp[2-args].u.integer); - else - low_limit=30; - low_limit=low_limit*low_limit; - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - MEMSET(img->img,0,sizeof(rgb_group)*img->xsize*img->ysize); - - if (sp[-args].u.integer>=0 && sp[-args].u.integer<img->xsize - && sp[1-args].u.integer>=0 && sp[1-args].u.integer<img->ysize) - { - isf_seek(ISF_LEFT|ISF_RIGHT,1,low_limit, - sp[-args].u.integer,sp[-args].u.integer, - sp[1-args].u.integer, - THIS->img,img->img,img->xsize,img->ysize, - pixel(THIS,sp[-args].u.integer,sp[1-args].u.integer),0); - isf_seek(ISF_LEFT|ISF_RIGHT,-1,low_limit, - sp[-args].u.integer,sp[-args].u.integer, - sp[1-args].u.integer, - THIS->img,img->img,img->xsize,img->ysize, - pixel(THIS,sp[-args].u.integer,sp[1-args].u.integer),0); - } - - pop_n_elems(args); - push_object(o); -} - -void image_apply_matrix(INT32 args) -{ - int width,height,i,j; - rgbd_group *matrix; - rgb_group default_rgb; - struct object *o; - double div; - -CHRONO("apply_matrix"); - - if (args<1 || - sp[-args].type!=T_ARRAY) - error("Illegal arguments to image->apply_matrix()\n"); - - if (args>3) - if (sp[1-args].type!=T_INT || - sp[2-args].type!=T_INT || - sp[3-args].type!=T_INT) - error("Illegal argument(s) (2,3,4) to image->apply_matrix()\n"); - else - { - default_rgb.r=sp[1-args].u.integer; - default_rgb.g=sp[1-args].u.integer; - default_rgb.b=sp[1-args].u.integer; - } - else - { - default_rgb.r=0; - default_rgb.g=0; - default_rgb.b=0; - } - - if (args>4 - && sp[4-args].type==T_INT) - { - div=sp[4-args].u.integer; - if (!div) div=1; - } - else if (args>4 - && sp[4-args].type==T_FLOAT) - { - div=sp[4-args].u.float_number; - if (!div) div=1; - } - else div=1; - - height=sp[-args].u.array->size; - width=-1; - for (i=0; i<height; i++) - { - struct svalue s; - array_index_no_free(&s,sp[-args].u.array,i); - if (s.type!=T_ARRAY) - error("Illegal contents of (root) array (image->apply_matrix)\n"); - if (width==-1) - width=s.u.array->size; - else - if (width!=s.u.array->size) - error("Arrays has different size (image->apply_matrix)\n"); - free_svalue(&s); - } - if (width==-1) width=0; - - matrix=malloc(sizeof(rgbd_group)*width*height+1); - if (!matrix) error("Out of memory"); - - for (i=0; i<height; i++) - { - struct svalue s,s2; - array_index_no_free(&s,sp[-args].u.array,i); - for (j=0; j<width; j++) - { - array_index_no_free(&s2,s.u.array,j); - if (s2.type==T_ARRAY && s2.u.array->size == 3) - { - struct svalue s3; - array_index_no_free(&s3,s2.u.array,0); - if (s3.type==T_INT) matrix[j+i*width].r=s3.u.integer; - else matrix[j+i*width].r=0; - free_svalue(&s3); - array_index_no_free(&s3,s2.u.array,1); - if (s3.type==T_INT) matrix[j+i*width].g=s3.u.integer; - else matrix[j+i*width].g=0; - free_svalue(&s3); - array_index_no_free(&s3,s2.u.array,2); - if (s3.type==T_INT) matrix[j+i*width].b=s3.u.integer; - else matrix[j+i*width].b=0; - free_svalue(&s3); - } - else if (s2.type==T_INT) - matrix[j+i*width].r=matrix[j+i*width].g= - matrix[j+i*width].b=s2.u.integer; - else - matrix[j+i*width].r=matrix[j+i*width].g= - matrix[j+i*width].b=0; - free_svalue(&s2); - } - free_svalue(&s2); - } - - o=clone(image_program,0); - -CHRONO("apply_matrix, begin"); - - if (THIS->img) - img_apply_matrix((struct image*)o->storage,THIS, - width,height,matrix,default_rgb,div); - -CHRONO("apply_matrix, end"); - - free(matrix); - - pop_n_elems(args); - push_object(o); -} - -void image_modify_by_intensity(INT32 args) -{ - INT32 x,y,i; - rgbl_group rgb; - rgb_group *list; - rgb_group *s,*d; - struct object *o; - struct image *img; - long div; - - if (!THIS->img) error("no image\n"); - if (args<5) - error("too few arguments to image->modify_by_intensity()\n"); - - getrgbl(&rgb,0,args,"image->modify_by_intensity()"); - div=rgb.r+rgb.g+rgb.b; - if (!div) div=1; - - s=malloc(sizeof(rgb_group)*(args-3)+1); - if (!s) error("Out of memory\n"); - - for (x=0; x<args-3; x++) - { - if (sp[3-args+x].type==T_INT) - s[x].r=s[x].g=s[x].b=testrange( sp[3-args+x].u.integer ); - else if (sp[3-args+x].type==T_ARRAY && - sp[3-args+x].u.array->size >= 3) - { - struct svalue sv; - array_index_no_free(&sv,sp[3-args+x].u.array,0); - if (sv.type==T_INT) s[x].r=testrange( sv.u.integer ); - else s[x].r=0; - array_index(&sv,sp[3-args+x].u.array,1); - if (sv.type==T_INT) s[x].g=testrange( sv.u.integer ); - else s[x].g=0; - array_index(&sv,sp[3-args+x].u.array,2); - if (sv.type==T_INT) s[x].b=testrange( sv.u.integer ); - else s[x].b=0; - free_svalue(&sv); - } - else s[x].r=s[x].g=s[x].b=0; - } - - list=malloc(sizeof(rgb_group)*256+1); - if (!list) - { - free(s); - error("out of memory\n"); - } - for (x=0; x<args-4; x++) - { - INT32 p1,p2,r; - p1=(255L*x)/(args-4); - p2=(255L*(x+1))/(args-4); - r=p2-p1; - for (y=0; y<r; y++) - { - list[y+p1].r=(((long)s[x].r)*(r-y)+((long)s[x+1].r)*(y))/r; - list[y+p1].g=(((long)s[x].g)*(r-y)+((long)s[x+1].g)*(y))/r; - list[y+p1].b=(((long)s[x].b)*(r-y)+((long)s[x+1].b)*(y))/r; - } - } - list[255]=s[x]; - free(s); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - d=img->img; - s=THIS->img; - - - x=THIS->xsize*THIS->ysize; - THREADS_ALLOW(); - while (x--) - { - i= testrange( ((((long)s->r)*rgb.r+ - ((long)s->g)*rgb.g+ - ((long)s->b)*rgb.b)/div) ); - *d=list[i]; - d++; - s++; - } - THREADS_DISALLOW(); - - free(list); - - pop_n_elems(args); - push_object(o); -} - -static void image_map_closest(INT32 args) -{ - struct colortable *ct; - long i; - rgb_group *d,*s; - struct object *o; - - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to image->map_closest()\n"); - - push_int(THIS->xsize); - push_int(THIS->ysize); - o=clone(image_program,2); - - ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); - pop_n_elems(args); - - i=THIS->xsize*THIS->ysize; - s=THIS->img; - d=((struct image*)(o->storage))->img; - THREADS_ALLOW(); - while (i--) - { - *d=ct->clut[colortable_rgb_nearest(ct,*s)]; - d++; *s++; - } - THREADS_DISALLOW(); - - colortable_free(ct); - push_object(o); -} - -static void image_map_fast(INT32 args) -{ - struct colortable *ct; - long i; - rgb_group *d,*s; - struct object *o; - - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to image->map_closest()\n"); - - push_int(THIS->xsize); - push_int(THIS->ysize); - o=clone(image_program,2); - - ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); - pop_n_elems(args); - - i=THIS->xsize*THIS->ysize; - s=THIS->img; - d=((struct image*)(o->storage))->img; - THREADS_ALLOW(); - while (i--) - { - *d=ct->clut[colortable_rgb(ct,*s)]; - d++; *s++; - } - THREADS_DISALLOW(); - - colortable_free(ct); - push_object(o); -} - -static void image_map_fs(INT32 args) -{ - struct colortable *ct; - INT32 i,j,xs; - rgb_group *d,*s; - struct object *o; - int *res,w; - rgbl_group *errb; - - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to image->map_fs()\n"); - - push_int(THIS->xsize); - push_int(THIS->ysize); - o=clone(image_program,2); - - res=(int*)xalloc(sizeof(int)*THIS->xsize); - errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*THIS->xsize); - - ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); - pop_n_elems(args); - - for (i=0; i<THIS->xsize; i++) - errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; - - i=THIS->ysize; - s=THIS->img; - d=((struct image*)(o->storage))->img; - w=0; - xs=THIS->xsize; - THREADS_ALLOW(); - while (i--) - { - image_floyd_steinberg(s,xs,errb,w=!w,res,ct); - for (j=0; j<THIS->xsize; j++) - *(d++)=ct->clut[res[j]]; - s+=xs; - } - THREADS_DISALLOW(); - - free(errb); - free(res); - colortable_free(ct); - push_object(o); -} - -void image_select_colors(INT32 args) -{ - struct colortable *ct; - int colors,i; - - if (args<1 - || sp[-args].type!=T_INT) - error("Illegal argument to image->select_colors()\n"); - - colors=sp[-args].u.integer; - pop_n_elems(args); - if (!THIS->img) { error("no image\n"); return; } - - ct=colortable_quant(THIS,colors); - for (i=0; i<colors; i++) - { - push_int(ct->clut[i].r); - push_int(ct->clut[i].g); - push_int(ct->clut[i].b); - f_aggregate(3); - } - f_aggregate(colors); - colortable_free(ct); -} - -/***************** global init etc *****************************/ - -#define RGB_TYPE "int|void,int|void,int|void,int|void" - -void init_font_programs(void); -void exit_font(void); - -void pike_module_init() -{ - int i; - - image_noise_init(); - - start_new_program(); - add_storage(sizeof(struct image)); - - add_function("create",image_create, - "function(int,int,"RGB_TYPE":void)",0); - add_function("clone",image_clone, - "function(int,int,"RGB_TYPE":object)",0); - add_function("new",image_clone, /* alias */ - "function(int,int,"RGB_TYPE":object)",0); - add_function("clear",image_clear, - "function("RGB_TYPE":object)",0); - add_function("toppm",image_toppm, - "function(:string)",0); - add_function("frompnm",image_frompnm, - "function(string:object|string)",0); - add_function("fromppm",image_frompnm, - "function(string:object|string)",0); - add_function("fromgif",image_fromgif, - "function(string:object)",0); - add_function("togif",image_togif, - "function(:string)",0); - add_function("togif_fs",image_togif_fs, - "function(:string)",0); - add_function("gif_begin",image_gif_begin, - "function(int:string)",0); - add_function("gif_add",image_gif_add, - "function(int|void,int|void:string)",0); - add_function("gif_add_fs",image_gif_add_fs, - "function(int|void,int|void:string)",0); - add_function("gif_add_nomap",image_gif_add_nomap, - "function(int|void,int|void:string)",0); - add_function("gif_add_fs_nomap",image_gif_add_fs_nomap, - "function(int|void,int|void:string)",0); - add_function("gif_end",image_gif_end, - "function(:string)",0); - add_function("gif_netscape_loop",image_gif_netscape_loop, - "function(:string)",0); - - add_function("copy",image_copy, - "function(void|int,void|int,void|int,void|int,"RGB_TYPE":object)",0); - add_function("autocrop",image_autocrop, - "function(void|int ...:object)",0); - add_function("scale",image_scale, - "function(int|float,int|float|void:object)",0); - add_function("translate",image_translate, - "function(int|float,int|float:object)",0); - add_function("translate_expand",image_translate_expand, - "function(int|float,int|float:object)",0); - - add_function("paste",image_paste, - "function(object,int|void,int|void:object)",0); - add_function("paste_alpha",image_paste_alpha, - "function(object,int,int|void,int|void:object)",0); - add_function("paste_mask",image_paste_mask, - "function(object,object,int|void,int|void:object)",0); - add_function("paste_alpha_color",image_paste_alpha_color, - "function(object,void|int,void|int,void|int,int|void,int|void:object)",0); - - add_function("setcolor",image_setcolor, - "function(int,int,int:object)",0); - add_function("setpixel",image_setpixel, - "function(int,int,"RGB_TYPE":object)",0); - add_function("getpixel",image_getpixel, - "function(int,int:array(int))",0); - add_function("line",image_line, - "function(int,int,int,int,"RGB_TYPE":object)",0); - add_function("circle",image_circle, - "function(int,int,int,int,"RGB_TYPE":object)",0); - add_function("box",image_box, - "function(int,int,int,int,"RGB_TYPE":object)",0); - add_function("tuned_box",image_tuned_box, - "function(int,int,int,int,array:object)",0); - - add_function("gray",image_gray, - "function("RGB_TYPE":object)",0); - add_function("color",image_color, - "function("RGB_TYPE":object)",0); - add_function("change_color",image_change_color, - "function(int,int,int,"RGB_TYPE":object)",0); - add_function("invert",image_invert, - "function("RGB_TYPE":object)",0); - add_function("threshold",image_threshold, - "function("RGB_TYPE":object)",0); - add_function("distancesq",image_distancesq, - "function("RGB_TYPE":object)",0); - add_function("select_from",image_select_from, - "function(int,int:object)",0); - - add_function("apply_matrix",image_apply_matrix, - "function(array(array(int|array(int))), void|int ...:object)",0); - add_function("modify_by_intensity",image_modify_by_intensity, - "function(int,int,int,int,int:object)",0); - - add_function("rotate_ccw",image_ccw, - "function(:object)",0); - add_function("rotate_cw",image_cw, - "function(:object)",0); - add_function("mirrorx",image_mirrorx, - "function(:object)",0); - add_function("mirrory",image_mirrory, - "function(:object)",0); - add_function("skewx",image_skewx, - "function(int|float,"RGB_TYPE":object)",0); - add_function("skewy",image_skewy, - "function(int|float,"RGB_TYPE":object)",0); - add_function("skewx_expand",image_skewx_expand, - "function(int|float,"RGB_TYPE":object)",0); - add_function("skewy_expand",image_skewy_expand, - "function(int|float,"RGB_TYPE":object)",0); - - add_function("rotate",image_rotate, - "function(int|float,"RGB_TYPE":object)",0); - add_function("rotate_expand",image_rotate_expand, - "function(int|float,"RGB_TYPE":object)",0); - - add_function("xsize",image_xsize, - "function(:int)",0); - add_function("ysize",image_ysize, - "function(:int)",0); - - add_function("map_closest",image_map_closest, - "function(:object)",0); - add_function("map_fast",image_map_fast, - "function(:object)",0); - add_function("map_fs",image_map_fs, - "function(:object)",0); - add_function("select_colors",image_select_colors, - "function(int:array(array(int)))",0); - - add_function("noise",image_noise, - "function(array(float|int|array(int)),float|void,float|void,float|void,float|void:object)",0); - add_function("turbulence",image_turbulence, - "function(array(float|int|array(int)),int|void,float|void,float|void,float|void,float|void:object)",0); - - add_function("dct",image_dct, - "function(:object)",0); - - add_function("`-",image_operator_minus, - "function(object|array(int):object)",0); - add_function("`+",image_operator_plus, - "function(object|array(int):object)",0); - add_function("`*",image_operator_multiply, - "function(object|array(int):object)",0); - add_function("`&",image_operator_minimum, - "function(object|array(int):object)",0); - add_function("`|",image_operator_maximum, - "function(object|array(int):object)",0); - - set_init_callback(init_image_struct); - set_exit_callback(exit_image_struct); - - image_program=end_program(); - add_program_constant("image",image_program, 0); - - for (i=0; i<CIRCLE_STEPS; i++) - circle_sin_table[i]=(INT32)4096*sin(((double)i)*2.0*3.141592653589793/(double)CIRCLE_STEPS); - - init_font_programs(); -} - -void pike_module_exit(void) -{ - if(image_program) - { - free_program(image_program); - image_program=0; - } - exit_font(); -} - - diff --git a/src/modules/image/image.h b/src/modules/image/image.h deleted file mode 100644 index bd62410980dc5689d27d2297a6ed132b31b40c6f..0000000000000000000000000000000000000000 --- a/src/modules/image/image.h +++ /dev/null @@ -1,148 +0,0 @@ -/* $Id: image.h,v 1.17 1996/12/10 00:40:06 law Exp $ */ - -#define MAX_NUMCOL 32768 - -#define QUANT_SELECT_CACHE 6 - -#define COLOURTYPE unsigned char - -#define FS_SCALE 1024 - -typedef struct -{ - COLOURTYPE r,g,b; -} rgb_group; - -typedef struct -{ - unsigned char r,g,b,alpha; -} rgba_group; - -typedef struct -{ - INT32 r,g,b; -} rgbl_group; - -typedef struct -{ - float r,g,b; -} rgbd_group; /* use float, it gets so big otherwise... */ - -struct image -{ - rgb_group *img; - INT32 xsize,ysize; - rgb_group rgb; - unsigned char alpha; -}; - -struct colortable -{ - int numcol; - struct rgb_cache - { - rgb_group index; - int value; - } cache[QUANT_SELECT_CACHE]; - unsigned long *rgb_node; -/* bit - 31..30 29..22 21..0 - 0=color split value - 1=split red on this - 2=split green =x <=x >x - 3=split blue value value+1 - It will fail for more than 2097152 colors. Sorry... *grin* - */ - rgb_group clut[1]; -}; /* rgb_node follows, 2*numcol */ - - -/* colortable declarations - from quant */ - -struct colortable *colortable_quant(struct image *img,int numcol); -int colortable_rgb(struct colortable *ct,rgb_group rgb); -int colortable_rgb_nearest(struct colortable *ct,rgb_group rgb); -void colortable_free(struct colortable *ct); -struct colortable *colortable_from_array(struct array *arr,char *from); - -/* encoding of a gif - from togif */ - -struct pike_string * - image_encode_gif(struct image *img,struct colortable *ct, - rgb_group *transparent, - int floyd_steinberg); -void image_floyd_steinberg(rgb_group *rgb,int xsize, - rgbl_group *errl, - int way,int *res, - struct colortable *ct); - -int image_decode_gif(struct image *dest,struct image *dest_alpha, - unsigned char *src,unsigned long len); - -void image_togif(INT32 args); -void image_togif_fs(INT32 args); -void image_fromgif(INT32 args); -void image_gif_begin(INT32 args); -void image_gif_add(INT32 args); -void image_gif_add_fs(INT32 args); -void image_gif_add_nomap(INT32 args); -void image_gif_add_fs_nomap(INT32 args); -void image_gif_end(INT32 args); -void image_gif_netscape_loop(INT32 args); - -/* blit.c */ - -void img_clear(rgb_group *dest,rgb_group rgb,INT32 size); -void img_box_nocheck(INT32 x1,INT32 y1,INT32 x2,INT32 y2); -void img_box(INT32 x1,INT32 y1,INT32 x2,INT32 y2); -void img_blit(rgb_group *dest,rgb_group *src,INT32 width, - INT32 lines,INT32 moddest,INT32 modsrc); -void img_crop(struct image *dest, - struct image *img, - INT32 x1,INT32 y1, - INT32 x2,INT32 y2); -void img_clone(struct image *newimg,struct image *img); -void image_paste(INT32 args); -void image_paste_alpha(INT32 args); -void image_paste_mask(INT32 args); -void image_paste_alpha_color(INT32 args); - -/* matrix.c */ - -void image_scale(INT32 args); -void image_translate(INT32 args); -void image_translate_expand(INT32 args); -void image_skewx(INT32 args); -void image_skewy(INT32 args); -void image_skewx_expand(INT32 args); -void image_skewy_expand(INT32 args); -void image_rotate(INT32 args); -void image_rotate_expand(INT32 args); -void image_cw(INT32 args); -void image_ccw(INT32 args); -void image_ccw(INT32 args); -void image_mirrorx(INT32 args); -void image_mirrory(INT32 args); - -/* pnm.c */ - -void image_toppm(INT32 args); -void image_frompnm(INT32 args); - -/* pattern.c */ - -void image_noise(INT32 args); -void image_turbulence(INT32 args); -void image_noise_init(void); - -/* dct.c */ - -void image_dct(INT32 args); - -/* operator.c */ - -void image_operator_minus(INT32 args); -void image_operator_plus(INT32 args); -void image_operator_multiply(INT32 args); -void image_operator_maximum(INT32 args); -void image_operator_minimum(INT32 args); diff --git a/src/modules/image/lzw.c b/src/modules/image/lzw.c deleted file mode 100644 index f53905f721cf31423b9233246d7501ae77a806f1..0000000000000000000000000000000000000000 --- a/src/modules/image/lzw.c +++ /dev/null @@ -1,368 +0,0 @@ -/* $Id: lzw.c,v 1.9 1997/01/07 00:41:42 law Exp $ */ - -/* - -lzw, used by togif - -Pontus Hagland, law@infovav.se - -this file can be used generally for lzw algoritms, -the existanse of #define GIF_LZW is for that purpose. :-) -/Pontus - -*/ - -#include "global.h" - -#include "lzw.h" - -#define DEFAULT_OUTBYTES 16384 -#ifndef GIF_LZW -#define STDLZWCODES 8192 -#endif - -static INLINE void lzw_output(struct lzw *lzw,lzwcode_t codeno) -{ - int bits,bitp; - unsigned char c; - -/* - fprintf(stderr,"%03x bits=%d codes %d %c\n", - codeno,lzw->codebits,lzw->codes+1, - (codeno==lzw->codes+1) ? '=' : ' '); - */ -#if 0 - fprintf(stderr,"\nwrote %4d<'",codeno); - lzw_recurse_find_code(lzw,codeno); - fprintf(stderr,"' "); -#endif - - if (lzw->outpos+4>=lzw->outlen) - lzw->out=realloc(lzw->out,lzw->outlen*=2); - - bitp=lzw->outbit; - c=lzw->lastout; - bits=lzw->codebits; -#ifdef GIF_LZW - if (bits>12) bits=12; -#endif - - while (bits) - { - c|=(codeno<<bitp); - if (bits+bitp>=8) - { - bits-=8-bitp; - codeno>>=8-bitp; - bitp=0; - lzw->out[lzw->outpos++]=c; - c=0; - } - else - { - lzw->outbit=bitp+bits; - lzw->lastout=c; - return; - } - } - lzw->lastout=0; - lzw->outbit=0; -} - - -void lzw_init(struct lzw *lzw,int bits) -{ - unsigned long i; -#ifdef GIF_LZW - lzw->codes=(1L<<bits)+2; -#else - lzw->codes=(1L<<bits); -#endif - lzw->bits=bits; - lzw->codebits=bits+1; - lzw->code=(struct lzwc*) malloc(sizeof(struct lzwc)* -#ifdef GIF_LZW - 4096 -#else - (lzw->alloced=STDLZWCODES) -#endif - ); - - for (i=0; i<lzw->codes; i++) - { - lzw->code[i].c=(unsigned char)i; - lzw->code[i].firstchild=LZWCNULL; - lzw->code[i].next=LZWCNULL; - } - lzw->out=malloc(DEFAULT_OUTBYTES); - lzw->outlen=DEFAULT_OUTBYTES; - lzw->outpos=0; - lzw->current=LZWCNULL; - lzw->outbit=0; - lzw->lastout=0; -#ifdef GIF_LZW - lzw_output(lzw,1L<<bits); -#endif -} - -void lzw_quit(struct lzw *lzw) -{ - int i; - - free(lzw->code); - free(lzw->out); -} - -#if 0 -static void lzw_recurse_find_code(struct lzw *lzw,lzwcode_t codeno) -{ - lzwcode_t i; - if (codeno<(1L<<lzw->bits)) - fprintf(stderr,"%c",codeno); - else if (codeno==(1L<<lzw->bits)) - fprintf(stderr,"(clear)"); - else if (codeno==(1L<<lzw->bits)+1) - fprintf(stderr,"(end)"); - else for (;;) - { - /* direct child? */ - for (i=0; i<lzw->codes; i++) - if (lzw->code[i].firstchild==codeno) - { - lzw_recurse_find_code(lzw,i); - fprintf(stderr,"%c",lzw->code[codeno].c); - return; - } - for (i=0; i<lzw->codes; i++) - if (lzw->code[i].next==codeno) codeno=i; - } -} -#endif - -void lzw_write_last(struct lzw *lzw) -{ - if (lzw->current) - lzw_output(lzw,lzw->current); -#ifdef GIF_LZW - lzw_output( lzw, (1L<<lzw->bits)+1 ); /* GIF end code */ -#endif - if (lzw->outbit) - lzw->out[lzw->outpos++]=lzw->lastout; -} - -void lzw_add(struct lzw *lzw,int c) -{ - lzwcode_t lno,lno2; - struct lzwc *l; - - if (lzw->current==LZWCNULL) /* no current, load */ - { - lzw->current=c; - return; - } - - lno=lzw->code[lzw->current].firstchild; /* check if we have this sequence */ - while (lno!=LZWCNULL) - { - if (lzw->code[lno].c==c && lno!=lzw->codes-1 ) - { - lzw->current=lno; - return; - } - lno=lzw->code[lno].next; - } - - -#ifdef GIF_LZW - if (lzw->codes==4096) /* needs more than 12 bits */ - { - int i; - - lzw_output(lzw,lzw->current); - - for (i=0; i<(1L<<lzw->bits); i++) - lzw->code[i].firstchild=LZWCNULL; - lzw->codes=(1L<<lzw->bits)+2; - - /* output clearcode, 1000... (bits) */ - lzw_output(lzw,1L<<lzw->bits); - - lzw->codebits=lzw->bits+1; - lzw->current=c; - return; - } -#else - if (lzw->codes==MAXLZWCODES) - realloc lzwc->code... move lzw->current -#endif - - /* output current code no, make new & reset */ - - lzw_output(lzw,lzw->current); - - lno=lzw->code[lzw->current].firstchild; - lno2=lzw->codes; - l=lzw->code+lno2; - l->next=lno; - l->firstchild=LZWCNULL; - l->c=c; - lzw->code[lzw->current].firstchild=lno2; - - lzw->codes++; - if (lzw->codes>(unsigned long)(1L<<lzw->codebits)) lzw->codebits++; - - lzw->current=c; -} - -#undef UNPACK_DEBUG - -#ifdef GIF_LZW -unsigned long lzw_unpack(unsigned char *dest,unsigned long destlen, - unsigned char *src,unsigned long srclen, - int bits) -{ - struct lzwuc - { - unsigned char c; - lzwcode_t parent; - lzwcode_t len; /* no string is longer then that ... */ - } *code; - - static unsigned short mask[16]={0,1,3,7,017,037,077,0177,0377,0777,01777, - 03777,07777,01777,03777,07777}; - - unsigned long wrote=0; - int i,cbits,cbit,clear=(1<<bits),end=(1<<bits)+1; - lzwcode_t current,last,used,nextlast; - unsigned long store; - unsigned char *srcend=src+srclen,*destend=dest+destlen; - unsigned char first=0; - - code=malloc(sizeof(struct lzwuc)*4096); - if (!code) return 0; - - for (i=0; i<(1<<bits); i++) - { - code[i].c=i; - code[i].parent=LZWCNULL; - code[i].len=1; - } - - cbit=0; - cbits=bits+1; - store=0; - last=LZWCNULL; - used=end+1; - - while (src!=srcend) - { - if (cbit>cbits) - { - current=store>>(32-cbits); - cbit-=cbits; - } - else - { - while (cbits-cbit>=8) - { - store=(store>>8)|((*(src++))<<24); - cbit+=8; - if (src==srcend) { free(code); return wrote; } - } - store=(store>>8)|((*(src++))<<24); - cbit+=8; - current=(store>>(32-(cbit)))&mask[cbits]; - cbit-=cbits; - } - -#ifdef UNPACK_DEBUG - fprintf(stderr,"%03x ",current); -#endif - - if (current==clear) /* clear tree */ - { - for (i=0; i<end-2; i++) - code[i].parent=LZWCNULL; - last=LZWCNULL; - used=end+1; - if (cbits!=bits+1) - { - cbits=bits+1; - cbit++; - } - } - else if (current==end) /* end of data */ - break; - else if (last==LZWCNULL) - { - last=current; - if (last>end) break; - *(dest++)=(unsigned char)current; - wrote++; - first=current; - } - else - { - lzwcode_t n; - unsigned char *dest2; - - if (code[current].len+dest>destend) /* no space, cancel */ - break; - - nextlast=current; - - if (current>=used) - { - *(dest++)=(unsigned char)first; - wrote++; - current=last; - } - - dest+=code[current].len; - wrote+=code[current].len; - - dest2=dest; - n=current; - *--dest2=code[n].c; - while (n>end) - { - n=code[n].parent; - *--dest2=code[n].c; - } - - -/* - *dest=0; - fprintf(stderr,"read %4d>'",current); - for (i=0; i<code[current].len; i++) - fprintf(stderr,"%c",(dest-code[current].len)[i]); - fprintf(stderr,"' == "); - for (i=0; i<code[current].len; i++) - fprintf(stderr,"%02x",(dest-code[current].len)[i]); - fprintf(stderr,"\n"); -*/ - - if (used<4096) - { - code[used].c=code[n].c; - code[used].parent=last; - code[used].len=code[last].len+1; - used++; - - if (used>=(1<<cbits)) - { - cbits++; -#ifdef UNPACK_DEBUG - fprintf(stderr,"[%d bits]",cbits); -#endif - } - } - - last=nextlast; - } - } - free(code); - return wrote; -} -#endif - diff --git a/src/modules/image/lzw.h b/src/modules/image/lzw.h deleted file mode 100644 index 0f6909dc930e216c06787a3b17074597fb448240..0000000000000000000000000000000000000000 --- a/src/modules/image/lzw.h +++ /dev/null @@ -1,40 +0,0 @@ -/* $Id: lzw.h,v 1.3 1996/11/14 12:35:01 law Exp $ */ - -#define GIF_LZW - -#ifdef GIF_LZW -typedef unsigned short lzwcode_t; /* no more than 12 bits used */ -#else -typedef unsigned long lzwcode_t; -#endif - -struct lzw -{ - unsigned long codes; - unsigned long bits; /* initial encoding bits */ - unsigned long codebits; /* current encoding bits */ - unsigned long outlen,outpos,outbit; - unsigned char *out,lastout; - struct lzwc - { - unsigned char c; - lzwcode_t firstchild; - lzwcode_t next; - } *code; - lzwcode_t current,firstfree; -#ifndef GIF_LZW - unsigned long alloced; -#endif -}; - -#define LZWCNULL ((lzwcode_t)(~0)) - -void lzw_add(struct lzw *lzw,int c); -void lzw_quit(struct lzw *lzw); -void lzw_init(struct lzw *lzw,int bits); -unsigned long lzw_unpack(unsigned char *dest,unsigned long destlen, - unsigned char *src,unsigned long srclen, - int bits); - - - diff --git a/src/modules/image/matrix.c b/src/modules/image/matrix.c deleted file mode 100644 index 0dd452ecb4ac4e90670136b61b8567b17c0fb11a..0000000000000000000000000000000000000000 --- a/src/modules/image/matrix.c +++ /dev/null @@ -1,977 +0,0 @@ -/* $Id: matrix.c,v 1.11 1997/01/23 20:02:03 grubba Exp $ */ - -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "threads.h" -#include "error.h" - -#include "image.h" - -extern struct program *image_program; -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) - -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - -/***************** internals ***********************************/ - -#define apply_alpha(x,y,alpha) \ - ((unsigned char)((y*(255L-(alpha))+x*(alpha))/255L)) - -#define set_rgb_group_alpha(dest,src,alpha) \ - ((dest).r=apply_alpha((dest).r,(src).r,alpha), \ - (dest).g=apply_alpha((dest).g,(src).g,alpha), \ - (dest).b=apply_alpha((dest).b,(src).b,alpha)) - -#define pixel(_img,x,y) ((_img)->img[(x)+(y)*(_img)->xsize]) - -#define setpixel(x,y) \ - (THIS->alpha? \ - set_rgb_group_alpha(THIS->img[(x)+(y)*THIS->xsize],THIS->rgb,THIS->alpha): \ - ((pixel(THIS,x,y)=THIS->rgb),0)) - -#define setpixel_test(x,y) \ - (((x)<0||(y)<0||(x)>=THIS->xsize||(y)>=THIS->ysize)? \ - 0:(setpixel(x,y),0)) - -static INLINE int getrgb(struct image *img, - INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return 0; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; - img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; - img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; - if (args-args_start>=4) - if (sp[3-args+args_start].type!=T_INT) - error("Illegal alpha argument to %s\n",name); - else - img->alpha=sp[3-args+args_start].u.integer; - else - img->alpha=0; - return 1; -} - -static INLINE int getrgbl(rgbl_group *rgb,INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return 0; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - rgb->r=sp[-args+args_start].u.integer; - rgb->g=sp[1-args+args_start].u.integer; - rgb->b=sp[2-args+args_start].u.integer; - return 1; -} - -/** end internals **/ - - -#define decimals(x) ((x)-(int)(x)) -#define testrange(x) max(min((x),255),0) -#define _scale_add_rgb(dest,src,factor) \ - ((dest)->r+=(src)->r*(factor), \ - (dest)->g+=(src)->g*(factor), \ - (dest)->b+=(src)->b*(factor)) -#define scale_add_pixel(dest,dx,src,sx,factor) \ - _scale_add_rgb(dest,src,factor) - -static INLINE void scale_add_line(rgbd_group *new,INT32 yn,INT32 newx, - rgb_group *img,INT32 y,INT32 xsize, - double py,double dx) -{ - INT32 x,xd; - double xn,xndxd; - new=new+yn*newx; - img=img+y*xsize; - for (x=0,xn=0; x<xsize; img++,x++,xn+=dx) - { - if ((INT32)xn<(INT32)(xn+dx)) - { - xndxd=py*(1.0-decimals(xn)); - if (xndxd) - scale_add_pixel(new,(INT32)xn,img,x,xndxd); - if (dx>=1.0 && (xd=(INT32)(xn+dx)-(INT32)(xn))>1) - while (--xd) - { - new++; - scale_add_pixel(new,(INT32)(xn+xd),img,x,py); - } - xndxd=py*decimals(xn+dx); - new++; - if (xndxd) - scale_add_pixel(new,(INT32)(xn+dx),img,x,xndxd); - } - else - scale_add_pixel(new,(int)xn,img,x,py*dx); - } -} - -void img_scale(struct image *dest, - struct image *source, - INT32 newx,INT32 newy) -{ - rgbd_group *new,*s; - rgb_group *d; - INT32 y,yd; - double yn,dx,dy; - -CHRONO("scale begin"); - - if (dest->img) { free(dest->img); dest->img=NULL; } - - if (!THIS->img || newx<=0 || newy<=0) return; /* no way */ - - THREADS_ALLOW(); - new=malloc(newx*newy*sizeof(rgbd_group) +1); - if (!new) error("Out of memory!\n"); - - for (y=0; y<newx*newy; y++) - new[y].r=new[y].g=new[y].b=0.0; - - dx=((double)newx-0.000001)/source->xsize; - dy=((double)newy-0.000001)/source->ysize; - - for (y=0,yn=0; y<source->ysize; y++,yn+=dy) - { - if ((INT32)yn<(INT32)(yn+dy)) - { - if (1.0-decimals(yn)) - scale_add_line(new,(INT32)(yn),newx,source->img,y,source->xsize, - (1.0-decimals(yn)),dx); - if ((yd=(INT32)(yn+dy)-(INT32)(yn))>1) - while (--yd) - scale_add_line(new,(INT32)yn+yd,newx,source->img,y,source->xsize, - 1.0,dx); - if (decimals(yn+dy)) - scale_add_line(new,(INT32)(yn+dy),newx,source->img,y,source->xsize, - (decimals(yn+dy)),dx); - } - else - scale_add_line(new,(INT32)yn,newx,source->img,y,source->xsize, - dy,dx); - } - - dest->img=d=malloc(newx*newy*sizeof(rgb_group) +1); - if (!d) { free(new); error("Out of memory!\n"); } - -CHRONO("transfer begin"); - - s=new; - y=newx*newy; - while (y--) - { - d->r=min((int)(s->r+0.5),255); - d->g=min((int)(s->g+0.5),255); - d->b=min((int)(s->b+0.5),255); - d++; s++; - } - - dest->xsize=newx; - dest->ysize=newy; - - free(new); - -CHRONO("scale end"); - THREADS_DISALLOW(); -} - -/* Special, faster, case for scale=1/2 */ -void img_scale2(struct image *dest, struct image *source) -{ - rgb_group *new; - INT32 x, y, newx, newy; - newx = source->xsize >> 1; - newy = source->ysize >> 1; - - if (dest->img) { free(dest->img); dest->img=NULL; } - if (!THIS->img || newx<=0 || newy<=0) return; /* no way */ - - THREADS_ALLOW(); - new=malloc(newx*newy*sizeof(rgb_group) +1); - if (!new) error("Out of memory\n"); - MEMSET(new,0,newx*newy*sizeof(rgb_group)); - - dest->img=new; - dest->xsize=newx; - dest->ysize=newy; - for (y = 0; y < newy; y++) - for (x = 0; x < newx; x++) { - pixel(dest,x,y).r = (COLOURTYPE) - (((INT32) pixel(source,2*x+0,2*y+0).r+ - (INT32) pixel(source,2*x+1,2*y+0).r+ - (INT32) pixel(source,2*x+0,2*y+1).r+ - (INT32) pixel(source,2*x+1,2*y+1).r) >> 2); - pixel(dest,x,y).g = (COLOURTYPE) - (((INT32) pixel(source,2*x+0,2*y+0).g+ - (INT32) pixel(source,2*x+1,2*y+0).g+ - (INT32) pixel(source,2*x+0,2*y+1).g+ - (INT32) pixel(source,2*x+1,2*y+1).g) >> 2); - pixel(dest,x,y).b = (COLOURTYPE) - (((INT32) pixel(source,2*x+0,2*y+0).b+ - (INT32) pixel(source,2*x+1,2*y+0).b+ - (INT32) pixel(source,2*x+0,2*y+1).b+ - (INT32) pixel(source,2*x+1,2*y+1).b) >> 2); - } - THREADS_DISALLOW(); -} - - - -void image_scale(INT32 args) -{ - float factor; - struct object *o; - struct image *newimg; - - o=clone(image_program,0); - newimg=(struct image*)(o->storage); - - if (args==1 && sp[-args].type==T_FLOAT) { - if (sp[-args].u.float_number == 0.5) - img_scale2(newimg,THIS); - else - img_scale(newimg,THIS, - (INT32)(THIS->xsize*sp[-args].u.float_number), - (INT32)(THIS->ysize*sp[-args].u.float_number)); - } - else if (args>=2 && - sp[-args].type==T_INT && sp[-args].u.integer==0 && - sp[1-args].type==T_INT) - { - factor=((float)sp[1-args].u.integer)/THIS->ysize; - img_scale(newimg,THIS, - (INT32)(THIS->xsize*factor), - sp[1-args].u.integer); - } - else if (args>=2 && - sp[1-args].type==T_INT && sp[1-args].u.integer==0 && - sp[-args].type==T_INT) - { - factor=((float)sp[-args].u.integer)/THIS->xsize; - img_scale(newimg,THIS, - sp[-args].u.integer, - (INT32)(THIS->ysize*factor)); - } - else if (args>=2 && - sp[-args].type==T_FLOAT && - sp[1-args].type==T_FLOAT) - img_scale(newimg,THIS, - (INT32)(THIS->xsize*sp[-args].u.float_number), - (INT32)(THIS->ysize*sp[1-args].u.float_number)); - else if (args>=2 && - sp[-args].type==T_INT && - sp[1-args].type==T_INT) - img_scale(newimg,THIS, - sp[-args].u.integer, - sp[1-args].u.integer); - else - { - free_object(o); - error("illegal arguments to image->scale()\n"); - } - pop_n_elems(args); - push_object(o); -} - -void image_ccw(INT32 args) -{ - INT32 i,j,xs,ys; - rgb_group *src,*dest; - struct object *o; - struct image *img; - - pop_n_elems(args); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - img->xsize=THIS->ysize; - img->ysize=THIS->xsize; - i=xs=THIS->xsize; - ys=THIS->ysize; - src=THIS->img+THIS->xsize-1; - dest=img->img; - - THREADS_ALLOW(); - while (i--) - { - j=ys; - while (j--) *(dest++)=*(src),src+=xs; - src--; - src-=xs*ys; - } - THREADS_DISALLOW(); - - push_object(o); -} - -static void img_cw(struct image *is,struct image *id) -{ - INT32 i,j; - rgb_group *src,*dest; - - if (id->img) free(id->img); - *id=*is; - if (!(id->img=malloc(sizeof(rgb_group)*is->xsize*is->ysize+1))) - error("Out of memory\n"); - - id->xsize=is->ysize; - id->ysize=is->xsize; - i=is->xsize; - src=is->img+is->xsize-1; - dest=id->img; - THREADS_ALLOW(); - while (i--) - { - j=is->ysize; - while (j--) *(dest++)=*(src),src+=is->xsize; - src--; - src-=is->xsize*is->ysize; - } - THREADS_DISALLOW(); -} - -void img_ccw(struct image *is,struct image *id) -{ - INT32 i,j; - rgb_group *src,*dest; - - if (id->img) free(id->img); - *id=*is; - if (!(id->img=malloc(sizeof(rgb_group)*is->xsize*is->ysize+1))) - error("Out of memory\n"); - - id->xsize=is->ysize; - id->ysize=is->xsize; - i=is->xsize; - src=is->img+is->xsize-1; - dest=id->img+is->xsize*is->ysize; - THREADS_ALLOW(); - while (i--) - { - j=is->ysize; - while (j--) *(--dest)=*(src),src+=is->xsize; - src--; - src-=is->xsize*is->ysize; - } - THREADS_DISALLOW(); -} - -void image_cw(INT32 args) -{ - INT32 i,j,xs,ys; - rgb_group *src,*dest; - struct object *o; - struct image *img; - - pop_n_elems(args); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - ys=img->xsize=THIS->ysize; - i=xs=img->ysize=THIS->xsize; - - src=THIS->img+THIS->xsize-1; - dest=img->img+THIS->xsize*THIS->ysize; - THREADS_ALLOW(); - while (i--) - { - j=ys; - while (j--) *(--dest)=*(src),src+=xs; - src--; - src-=xs*ys; - } - THREADS_DISALLOW(); - - push_object(o); -} - -void image_mirrorx(INT32 args) -{ - rgb_group *src,*dest; - struct object *o; - struct image *img; - INT32 i,j,xs; - - pop_n_elems(args); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - i=THIS->ysize; - src=THIS->img+THIS->xsize-1; - dest=img->img; - xs=THIS->xsize; - THREADS_ALLOW(); - while (i--) - { - j=xs; - while (j--) *(dest++)=*(src--); - src+=xs*2; - } - THREADS_DISALLOW(); - - push_object(o); -} - -void image_mirrory(INT32 args) -{ - rgb_group *src,*dest; - struct object *o; - struct image *img; - INT32 i,j,xs; - - pop_n_elems(args); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - i=THIS->ysize; - src=THIS->img+THIS->xsize*(THIS->ysize-1); - dest=img->img; - xs=THIS->xsize; - THREADS_ALLOW(); - while (i--) - { - j=xs; - while (j--) *(dest++)=*(src++); - src-=xs*2; - } - THREADS_DISALLOW(); - - push_object(o); - -} - - -#define ROUND(X) ((unsigned char)((X)+0.5)) - -static void img_skewx(struct image *src, - struct image *dest, - float diff, - int xpn) /* expand pixel for use with alpha instead */ -{ - double x0,xmod,xm; - INT32 y,x,len; - rgb_group *s,*d; - rgb_group rgb; - - if (dest->img) free(dest->img); - if (diff<0) - dest->xsize=ceil(-diff)+src->xsize,x0=-diff; - else - dest->xsize=ceil(diff)+src->xsize,x0=0; - dest->ysize=src->ysize; - len=src->xsize; - - d=dest->img=malloc(sizeof(rgb_group)*dest->xsize*dest->ysize); - if (!d) return; - s=src->img; - - THREADS_ALLOW(); - xmod=diff/src->ysize; - rgb=dest->rgb; - - CHRONO("skewx begin\n"); - - y=src->ysize; - while (y--) - { - int j; - if (xpn) rgb=*s; - for (j=x0; j--;) *(d++)=rgb; - if (!(xm=(x0-floor(x0)))) - { - for (j=len; j--;) *(d++)=*(s++); - j=dest->xsize-x0-len; - } - else - { - float xn=1-xm; - if (xpn) - *d=*s; - else - d->r=ROUND(rgb.r*xm+s->r*xn), - d->g=ROUND(rgb.g*xm+s->g*xn), - d->b=ROUND(rgb.b*xm+s->b*xn); - d++; - for (j=len-1; j--;) - { - d->r=ROUND(s->r*xm+s[1].r*xn), - d->g=ROUND(s->g*xm+s[1].g*xn), - d->b=ROUND(s->b*xm+s[1].b*xn); - d++; - s++; - } - if (xpn) - *d=*s; - else - d->r=ROUND(rgb.r*xn+s->r*xm), - d->g=ROUND(rgb.g*xn+s->g*xm), - d->b=ROUND(rgb.b*xn+s->b*xm); - d++; - s++; - j=dest->xsize-x0-len; - } - if (xpn) rgb=s[-1]; - while (j--) *(d++)=rgb; - x0+=xmod; - } - THREADS_DISALLOW(); - - CHRONO("skewx end\n"); -} - -static void img_skewy(struct image *src, - struct image *dest, - float diff, - int xpn) /* expand pixel for use with alpha instead */ -{ - double y0,ymod,ym; - INT32 y,x,len,xsz; - rgb_group *s,*d; - rgb_group rgb; - - if (dest->img) free(dest->img); - if (diff<0) - dest->ysize=ceil(-diff)+src->ysize,y0=-diff; - else - dest->ysize=ceil(diff)+src->ysize,y0=0; - xsz=dest->xsize=src->xsize; - len=src->ysize; - - d=dest->img=malloc(sizeof(rgb_group)*dest->ysize*dest->xsize); - if (!d) return; - s=src->img; - - THREADS_ALLOW(); - ymod=diff/src->xsize; - rgb=dest->rgb; - -CHRONO("skewy begin\n"); - - x=src->xsize; - while (x--) - { - int j; - if (xpn) rgb=*s; - for (j=y0; j--;) *d=rgb,d+=xsz; - if (!(ym=(y0-floor(y0)))) - { - for (j=len; j--;) *d=*s,d+=xsz,s+=xsz; - j=dest->ysize-y0-len; - } - else - { - float yn=1-ym; - if (xpn) - *d=*s; - else - d->r=ROUND(rgb.r*ym+s->r*yn), - d->g=ROUND(rgb.g*ym+s->g*yn), - d->b=ROUND(rgb.b*ym+s->b*yn); - d+=xsz; - for (j=len-1; j--;) - { - d->r=ROUND(s->r*ym+s[xsz].r*yn), - d->g=ROUND(s->g*ym+s[xsz].g*yn), - d->b=ROUND(s->b*ym+s[xsz].b*yn); - d+=xsz; - s+=xsz; - } - if (xpn) - *d=*s; - else - d->r=ROUND(rgb.r*yn+s->r*ym), - d->g=ROUND(rgb.g*yn+s->g*ym), - d->b=ROUND(rgb.b*yn+s->b*ym); - d+=xsz; - s+=xsz; - j=dest->ysize-y0-len; - } - if (xpn) rgb=s[-xsz]; - while (j--) *d=rgb,d+=xsz; - s-=len*xsz-1; - d-=dest->ysize*xsz-1; - y0+=ymod; - } - THREADS_DISALLOW(); - -CHRONO("skewy end\n"); - -} - -void image_skewx(INT32 args) -{ - float diff=0; - struct object *o; - - if (args<1) - error("too few arguments to image->skewx()\n"); - else if (sp[-args].type==T_FLOAT) - diff=THIS->ysize*sp[-args].u.float_number; - else if (sp[-args].type==T_INT) - diff=sp[-args].u.integer; - else - error("illegal argument to image->skewx()\n"); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - - if (!getrgb((struct image*)(o->storage),1,args,"image->skewx()")) - ((struct image*)(o->storage))->rgb=THIS->rgb; - - img_skewx(THIS,(struct image*)(o->storage),diff,0); - - pop_n_elems(args); - push_object(o); -} - -void image_skewy(INT32 args) -{ - float diff=0; - struct object *o; - - if (args<1) - error("too few arguments to image->skewy()\n"); - else if (sp[-args].type==T_FLOAT) - diff=THIS->xsize*sp[-args].u.float_number; - else if (sp[-args].type==T_INT) - diff=sp[-args].u.integer; - else - error("illegal argument to image->skewx()\n"); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - - if (!getrgb((struct image*)(o->storage),1,args,"image->skewy()")) - ((struct image*)(o->storage))->rgb=THIS->rgb; - - img_skewy(THIS,(struct image*)(o->storage),diff,0); - - pop_n_elems(args); - push_object(o); -} - -void image_skewx_expand(INT32 args) -{ - float diff=0; - struct object *o; - - if (args<1) - error("too few arguments to image->skewx()\n"); - else if (sp[-args].type==T_FLOAT) - diff=THIS->ysize*sp[-args].u.float_number; - else if (sp[-args].type==T_INT) - diff=sp[-args].u.integer; - else - error("illegal argument to image->skewx()\n"); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - - if (!getrgb((struct image*)(o->storage),1,args,"image->skewx()")) - ((struct image*)(o->storage))->rgb=THIS->rgb; - - img_skewx(THIS,(struct image*)(o->storage),diff,1); - - pop_n_elems(args); - push_object(o); -} - -void image_skewy_expand(INT32 args) -{ - float diff=0; - struct object *o; - - if (args<1) - error("too few arguments to image->skewy()\n"); - else if (sp[-args].type==T_FLOAT) - diff=THIS->xsize*sp[-args].u.float_number; - else if (sp[-args].type==T_INT) - diff=sp[-args].u.integer; - else - error("illegal argument to image->skewx()\n"); - - if (!THIS->img) error("no image\n"); - - o=clone(image_program,0); - - if (!getrgb((struct image*)(o->storage),1,args,"image->skewy()")) - ((struct image*)(o->storage))->rgb=THIS->rgb; - - img_skewy(THIS,(struct image*)(o->storage),diff,1); - - pop_n_elems(args); - push_object(o); -} - - - -void img_rotate(INT32 args,int xpn) -{ - float angle=0; - struct object *o; - struct image *dest,d0,dest2; - - if (args<1) - error("too few arguments to image->rotate()\n"); - else if (sp[-args].type==T_FLOAT) - angle=sp[-args].u.float_number; - else if (sp[-args].type==T_INT) - angle=sp[-args].u.integer; - else - error("illegal argument to image->rotate()\n"); - - if (!THIS->img) error("no image\n"); - - dest2.img=d0.img=NULL; - - if (angle<-135) angle-=360*(int)((angle-225)/360); - else if (angle>225) angle-=360*(int)((angle+135)/360); - if (angle<-45) - { - img_ccw(THIS,&dest2); - angle+=90; - } - else if (angle>135) - { - img_ccw(THIS,&d0); - img_ccw(&d0,&dest2); - angle-=180; - } - else if (angle>45) - { - img_cw(THIS,&dest2); - angle-=90; - } - else dest2=*THIS; - - angle=(angle/180.0)*3.141592653589793; - - o=clone(image_program,0); - - dest=(struct image*)(o->storage); - if (!getrgb(dest,1,args,"image->rotate()")) - (dest)->rgb=THIS->rgb; - d0.rgb=dest2.rgb=dest->rgb; - - img_skewy(&dest2,dest,-tan(angle/2)*dest2.xsize,xpn); - img_skewx(dest,&d0,sin(angle)*dest->ysize,xpn); - img_skewy(&d0,dest,-tan(angle/2)*d0.xsize,xpn); - - if (dest2.img!=THIS->img) free(dest2.img); - free(d0.img); - - pop_n_elems(args); - push_object(o); -} - -void image_rotate(INT32 args) -{ - img_rotate(args,0); -} - -void image_rotate_expand(INT32 args) -{ - img_rotate(args,1); -} - -void img_translate(INT32 args,int expand) -{ - float xt,yt; - int y,x; - struct object *o; - struct image *img; - rgb_group *s,*d; - - if (args<2) error("illegal number of arguments to image->translate()\n"); - - if (sp[-args].type==T_FLOAT) xt=sp[-args].u.float_number; - else if (sp[-args].type==T_INT) xt=sp[-args].u.integer; - else error("illegal argument 1 to image->translate()\n"); - - if (sp[1-args].type==T_FLOAT) yt=sp[1-args].u.float_number; - else if (sp[1-args].type==T_INT) yt=sp[1-args].u.integer; - else error("illegal argument 2 to image->translate()\n"); - - getrgb(THIS,2,args,"image->translate()\n"); - - xt-=floor(xt); - yt-=floor(yt); - - o=clone(image_program,0); - img=(struct image*)o->storage; - - img->xsize=THIS->xsize+(xt!=0); - img->ysize=THIS->ysize+(xt!=0); - - if (!(img->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - if (!xt) - { - memcpy(img->img,THIS->img,sizeof(rgb_group)*THIS->xsize*THIS->ysize); - } - else - { - float xn=1-xt; - - d=img->img; - s=THIS->img; - - for (y=0; y<img->ysize; y++) - { - x=THIS->xsize-1; - if (!expand) - d->r=ROUND(THIS->rgb.r*xt+s->r*xn), - d->g=ROUND(THIS->rgb.g*xt+s->g*xn), - d->b=ROUND(THIS->rgb.b*xt+s->b*xn); - else - d->r=s->r, d->g=s->g, d->b=s->b; - d++; s++; - while (x--) - { - d->r=ROUND(s->r*xn+s[1].r*xt), - d->g=ROUND(s->g*xn+s[1].g*xt), - d->b=ROUND(s->b*xn+s[1].b*xt); - d++; s++; - } - if (!expand) - d->r=ROUND(s->r*xn+THIS->rgb.r*xt), - d->g=ROUND(s->g*xn+THIS->rgb.g*xt), - d->b=ROUND(s->b*xn+THIS->rgb.b*xt); - else - d->r=s->r, d->g=s->g, d->b=s->b; - d++; - } - } - - if (yt) - { - float yn=1-yt; - int xsz=img->xsize; - - d=s=img->img; - - for (x=0; x<img->xsize; x++) - { - y=THIS->ysize-1; - if (!expand) - d->r=ROUND(THIS->rgb.r*yt+s->r*yn), - d->g=ROUND(THIS->rgb.g*yt+s->g*yn), - d->b=ROUND(THIS->rgb.b*yt+s->b*yn); - else - d->r=s->r, d->g=s->g, d->b=s->b; - d+=xsz; s+=xsz; - while (y--) - { - d->r=ROUND(s->r*yn+s[xsz].r*yt), - d->g=ROUND(s->g*yn+s[xsz].g*yt), - d->b=ROUND(s->b*yn+s[xsz].b*yt); - d+=xsz; s+=xsz; - } - if (!expand) - d->r=ROUND(s->r*yn+THIS->rgb.r*yt), - d->g=ROUND(s->g*yn+THIS->rgb.g*yt), - d->b=ROUND(s->b*yn+THIS->rgb.b*yt); - else - d->r=s->r, d->g=s->g, d->b=s->b; - d-=xsz*(img->ysize-1)-1; - s-=xsz*THIS->ysize-1; - } - } - - pop_n_elems(args); - push_object(o); -} - - -void image_translate_expand(INT32 args) -{ - img_translate(args,1); -} - -void image_translate(INT32 args) -{ - img_translate(args,0); -} diff --git a/src/modules/image/operator.c b/src/modules/image/operator.c deleted file mode 100644 index 657950e27a9ac2e7f3c7afac044e6b722a45813e..0000000000000000000000000000000000000000 --- a/src/modules/image/operator.c +++ /dev/null @@ -1,186 +0,0 @@ -/* $Id: operator.c,v 1.5 1997/01/23 20:02:04 grubba Exp $ */ -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "error.h" -#include "threads.h" - -#include "image.h" - -extern struct program *image_program; -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#define absdiff(a,b) ((a)<(b)?((b)-(a)):((a)-(b))) -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) - -#define STANDARD_OPERATOR_HEADER(what) \ - struct object *o; \ - struct image *img,*oper; \ - rgb_group *s1,*s2,*d,rgb; \ - INT32 i; \ - \ - if (!THIS->img) error("no image\n"); \ - \ - if (args && sp[-args].type==T_ARRAY \ - && sp[-args].u.array->size>=3 \ - && sp[-args].u.array->item[0].type==T_INT \ - && sp[-args].u.array->item[1].type==T_INT \ - && sp[-args].u.array->item[2].type==T_INT) \ - { \ - rgb.r=sp[-args].u.array->item[0].u.integer; \ - rgb.g=sp[-args].u.array->item[1].u.integer; \ - rgb.b=sp[-args].u.array->item[2].u.integer; \ - oper=NULL; \ - } \ - else \ - { \ - if (args<1 || sp[-args].type!=T_OBJECT \ - || !sp[-args].u.object \ - || sp[-args].u.object->prog!=image_program) \ - error("illegal arguments to image->"what"()\n"); \ - \ - oper=(struct image*)sp[-args].u.object->storage; \ - if (!oper->img) error("no image (operand)\n"); \ - if (oper->xsize!=THIS->xsize \ - || oper->ysize!=THIS->ysize) \ - error("operands differ in size (image->"what")"); \ - } \ - \ - push_int(THIS->xsize); \ - push_int(THIS->ysize); \ - o=clone(image_program,2); \ - img=(struct image*)o->storage; \ - if (!img->img) { free_object(o); error("out of memory\n"); } \ - \ - pop_n_elems(args); \ - push_object(o); \ - \ - s1=THIS->img; \ - if (oper) s2=oper->img; else s2=NULL; \ - d=img->img; \ - \ - i=img->xsize*img->ysize; \ - THREADS_ALLOW(); \ - if (oper) - - -void image_operator_minus(INT32 args) -{ -STANDARD_OPERATOR_HEADER("'-") - while (i--) - { - d->r=absdiff(s1->r,s2->r); - d->g=absdiff(s1->g,s2->g); - d->b=absdiff(s1->b,s2->b); - s1++; s2++; d++; - } - else - while (i--) - { - d->r=absdiff(s1->r,rgb.r); - d->g=absdiff(s1->g,rgb.g); - d->b=absdiff(s1->b,rgb.b); - s1++; d++; - } - THREADS_DISALLOW(); -} - -void image_operator_plus(INT32 args) -{ -STANDARD_OPERATOR_HEADER("'+") - while (i--) - { - d->r=max(s1->r+s2->r,255); - d->g=max(s1->g+s2->g,255); - d->b=max(s1->b+s2->b,255); - s1++; s2++; d++; - } - else - while (i--) - { - d->r=max(s1->r+rgb.r,255); - d->g=max(s1->g+rgb.g,255); - d->b=max(s1->b+rgb.b,255); - s1++; d++; - } - THREADS_DISALLOW(); -} - -void image_operator_multiply(INT32 args) -{ - double q=1/255.0; -STANDARD_OPERATOR_HEADER("'+") - while (i--) - { - d->r=floor(s1->r*s2->r*q+0.5); - d->g=floor(s1->g*s2->g*q+0.5); - d->b=floor(s1->b*s2->b*q+0.5); - s1++; s2++; d++; - } - else - while (i--) - { - d->r=floor(s1->r*rgb.r*q+0.5); - d->g=floor(s1->g*rgb.g*q+0.5); - d->b=floor(s1->b*rgb.b*q+0.5); - s1++; d++; - } - THREADS_DISALLOW(); -} - -void image_operator_maximum(INT32 args) -{ -STANDARD_OPERATOR_HEADER("'| 'maximum'") - while (i--) - { - d->r=max(s1->r,s2->r); - d->g=max(s1->g,s2->g); - d->b=max(s1->b,s2->b); - s1++; s2++; d++; - } - else - while (i--) - { - d->r=max(s1->r,rgb.r); - d->g=max(s1->g,rgb.g); - d->b=max(s1->b,rgb.b); - s1++; s2++; d++; - } - THREADS_DISALLOW(); -} - -void image_operator_minimum(INT32 args) -{ -STANDARD_OPERATOR_HEADER("'& 'minimum'") - while (i--) - { - d->r=min(s1->r,s2->r); - d->g=min(s1->g,s2->g); - d->b=min(s1->b,s2->b); - s1++; s2++; d++; - } - else - while (i--) - { - d->r=min(s1->r,rgb.r); - d->g=min(s1->g,rgb.g); - d->b=min(s1->b,rgb.b); - s1++; d++; - } - THREADS_DISALLOW(); -} - - diff --git a/src/modules/image/pattern.c b/src/modules/image/pattern.c deleted file mode 100644 index 458073a409e40bb0a5520e743594aec6716521a4..0000000000000000000000000000000000000000 --- a/src/modules/image/pattern.c +++ /dev/null @@ -1,309 +0,0 @@ -/* $Id: pattern.c,v 1.6 1997/01/23 20:02:05 grubba Exp $ */ - -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "error.h" - -#include "image.h" - -extern struct program *image_program; -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) -#define testrange(x) max(min((x),255),0) - -/**************** noise ************************/ - -#define NOISE_PTS 512 -#define NOISE_PX 173 -#define NOISE_PY 263 -#define NOISE_PZ 337 -#define NOISE_PHI 0.6180339 -static unsigned short noise_p1[NOISE_PTS],noise_p2[NOISE_PTS]; - -#define COLORRANGE_LEVELS 1024 - -#define FRAC(X) ((X)-floor(X)) - -static INLINE double noise(double Vx,double Vy,unsigned short *noise_p) -{ - int Ax[3],Ay[3]; - int n,i,j; - double Sx[3],Sy[3]; - double sum,dsum,f,fx,fy; - - fx=floor(Vx); - fy=floor(Vy); - - for (n=0; n<3; n++) - { - Ax[n]=(int)floor(NOISE_PX*FRAC( (fx+n)*NOISE_PHI )); - Ay[n]=(int)floor(NOISE_PY*FRAC( (fy+n)*NOISE_PHI )); - } - - f=FRAC(Vx); - Sx[0]=0.5-f+0.5*f*f; - Sx[1]=0.5+f-f*f; - Sx[2]=0.5*f*f; - - f=FRAC(Vy); - Sy[0]=0.5-f+0.5*f*f; - Sy[1]=0.5+f-f*f; - Sy[2]=0.5*f*f; - - sum=0; - for (i=0; i<3; i++) - { - for (j=0,dsum=0; j<3; j++) - dsum+=Sy[j]*noise_p[ (Ax[i]+Ay[j]) & (NOISE_PTS-1) ]; - sum+=Sx[i]*dsum; - } - return sum; -} - -static INLINE double turbulence(double x,double y,int octaves) -{ - double t=0; - double mul=1; - while (octaves-->0) - { - t+=noise(x*mul,y*mul,noise_p1)*mul; - mul*=0.5; - } - return t; -} - -static void init_colorrange(rgb_group *cr,struct svalue *s,char *where) -{ - float *v,*vp; - int i,n,k; - struct svalue s2,s3; - rgbd_group lrgb,*rgbp,*rgb; - float fr,fg,fb,q; - int b; - - if (s->type!=T_ARRAY) - error("Illegal colorrange to %s\n",where); - else if (s->u.array->size<2) - error("Colorrange array too small (meaningless) (to %s)\n",where); - - s2.type=T_INT; - s3.type=T_INT; /* don't free these */ - - vp=v=(void*)xalloc(sizeof(float)*(s->u.array->size/2+1)); - rgbp=rgb=(void*)xalloc(sizeof(rgbd_group)*(s->u.array->size/2+1)); - - for (i=0; i<s->u.array->size-1; i+=2) - { - array_index(&s2,s->u.array,i); - if (s2.type==T_INT) *vp=s2.u.integer; - else if (s2.type==T_FLOAT) *vp=s2.u.float_number; - else *vp=0; - if (*vp>1) *vp=1; - else if (*vp<0) *vp=0; - vp++; - - array_index(&s2,s->u.array,i+1); - - if (s2.type==T_INT) - rgbp->r=rgbp->g=rgbp->b=testrange( s2.u.integer ); - else if ( s2.type==T_ARRAY - && s2.u.array->size>=3 ) - { - array_index(&s3,s2.u.array,0); - if (s3.type==T_INT) rgbp->r=testrange( s3.u.integer ); - else rgbp->r=0; - array_index(&s3,s2.u.array,1); - if (s3.type==T_INT) rgbp->g=testrange( s3.u.integer ); - else rgbp->g=0; - array_index(&s3,s2.u.array,2); - if (s3.type==T_INT) rgbp->b=testrange( s3.u.integer ); - else rgbp->b=0; - } - else - rgbp->r=rgbp->g=rgbp->b=0; - rgbp++; - } - *vp=v[0]+1+1.0/(COLORRANGE_LEVELS-1); - lrgb=*rgbp=rgb[0]; /* back to original color */ - - for (k=1,i=v[0]*(COLORRANGE_LEVELS-1); k<=s->u.array->size/2; k++) - { - n=v[k]*(COLORRANGE_LEVELS-1); - - if (n>i) - { - q=1/((float)(n-i)); - - fr=(rgb[k].r-lrgb.r)*q; - fg=(rgb[k].g-lrgb.g)*q; - fb=(rgb[k].b-lrgb.b)*q; - - for (b=0;i<n;i++,b++) - { - cr[i&(COLORRANGE_LEVELS-1)].r=(unsigned char)(lrgb.r+fr*b); - cr[i&(COLORRANGE_LEVELS-1)].g=(unsigned char)(lrgb.g+fg*b); - cr[i&(COLORRANGE_LEVELS-1)].b=(unsigned char)(lrgb.b+fb*b); - } - } - lrgb=rgb[k]; - } - - free_svalue(&s3); - free_svalue(&s2); - free(v); - free(rgb); -} - -#define GET_FLOAT_ARG(sp,args,n,def,where) \ - ( (args>n) \ - ? ( (sp[n-args].type==T_INT) ? (double)(sp[n-args].u.integer) \ - : ( (sp[n-args].type==T_FLOAT) ? sp[n-args].u.float_number \ - : ( error("illegal argument(s) to "where"\n"), 0.0 ) ) ) \ - : def ) -#define GET_INT_ARG(sp,args,n,def,where) \ - ( (args>n) \ - ? ( (sp[n-args].type==T_INT) ? sp[n-args].u.integer \ - : ( (sp[n-args].type==T_FLOAT) ? (int)(sp[n-args].u.float_number) \ - : ( error("illegal argument(s) to "where"\n"), 0.0 ) ) ) \ - : def ) - -void image_noise(INT32 args) -{ -/* parametrar: array(float|int|array(int)) colorrange, - float scale=0.1, - float xdiff=0, - float ydiff=0, - float cscale=1 -*/ - int x,y; - rgb_group cr[COLORRANGE_LEVELS]; - double scale,xdiff,ydiff,cscale,xp,yp; - rgb_group *d; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - - if (args<1) error("too few arguments to image->noise()\n"); - - scale=GET_FLOAT_ARG(sp,args,1,0.1,"image->noise"); - xdiff=GET_FLOAT_ARG(sp,args,2,0,"image->noise"); - ydiff=GET_FLOAT_ARG(sp,args,3,0,"image->noise"); - cscale=GET_FLOAT_ARG(sp,args,4,1,"image->noise"); - - init_colorrange(cr,sp-args,"image->noise()"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - cscale=(32768*cscale)/COLORRANGE_LEVELS; - - d=img->img; - for (y=THIS->ysize,xp=xdiff; y--; xp+=1.0) - for (x=THIS->xsize,yp=ydiff; x--; yp+=1.0) - { - *(d++)= - cr[(int)((noise((double)x*scale,(double)y*scale,noise_p1) - +noise((double)(x*0.5+y*0.8660254037844386)*scale, - (double)(-y*0.5+x*0.8660254037844386)*scale, - noise_p2)) - *cscale)&(COLORRANGE_LEVELS-1)]; - } - - pop_n_elems(args); - push_object(o); -} - -void image_turbulence(INT32 args) -{ -/* parametrar: array(float|int|array(int)) colorrange, - int octaves=3, - float scale=0.1, - float xdiff=0, - float ydiff=0, - float cscale=0.001 -*/ - int x,y,octaves; - rgb_group cr[COLORRANGE_LEVELS]; - double scale,xdiff,ydiff,cscale,xp,yp; - rgb_group *d; - struct object *o; - struct image *img; - - if (!THIS->img) error("no image\n"); - - if (args<1) error("too few arguments to image->turbulence()\n"); - - octaves=GET_INT_ARG(sp,args,1,3,"image->turbulence"); - scale=GET_FLOAT_ARG(sp,args,2,0.1,"image->turbulence"); - xdiff=GET_FLOAT_ARG(sp,args,3,0,"image->turbulence"); - ydiff=GET_FLOAT_ARG(sp,args,4,0,"image->turbulence"); - cscale=GET_FLOAT_ARG(sp,args,5,0.001,"image->turbulence"); - - init_colorrange(cr,sp-args,"image->turbulence()"); - - o=clone(image_program,0); - img=(struct image*)o->storage; - *img=*THIS; - if (!(img->img=malloc(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1))) - { - free_object(o); - error("Out of memory\n"); - } - - cscale=(32768*cscale)/COLORRANGE_LEVELS; - - d=img->img; - for (y=THIS->ysize,xp=xdiff; y--; xp+=1.0) - for (x=THIS->xsize,yp=ydiff; x--; yp+=1.0) - { -#if 0 - if (y==0 && x<10) - { - fprintf(stderr,"%g*%g=%d => %d\n", - turbulence(xp*scale,yp*scale,octaves), - cscale, - (INT32)(turbulence(xp*scale,yp*scale,octaves)*cscale), - (INT32)(turbulence(xp*scale,yp*scale,octaves)*cscale)&(COLORRANGE_LEVELS)-1 ); - } -#endif - *(d++)= - cr[(INT32)(turbulence(xp*scale,yp*scale,octaves)*cscale) - & (COLORRANGE_LEVELS-1)]; - } - - pop_n_elems(args); - push_object(o); -} - - -void image_noise_init(void) -{ - int n; - for (n=0; n<NOISE_PTS; n++) - { - noise_p1[n]=(unsigned short)(rand()&32767); - noise_p2[n]=(unsigned short)(rand()&32767); - } -} diff --git a/src/modules/image/pnm.c b/src/modules/image/pnm.c deleted file mode 100644 index b0a04af5f1d1348b0db2449ebcd8051c7c0324da..0000000000000000000000000000000000000000 --- a/src/modules/image/pnm.c +++ /dev/null @@ -1,172 +0,0 @@ -/* $Id: pnm.c,v 1.2 1996/11/14 12:35:03 law Exp $ */ - -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "error.h" - -#include "image.h" - -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) -#define pixel(_img,x,y) ((_img)->img[(x)+(y)*(_img)->xsize]) - - -static INLINE unsigned char getnext(struct pike_string *s,INT32 *pos) -{ - if (*pos>=s->len) return 0; - if (s->str[(*pos)]=='#') - for (;*pos<s->len && ISSPACE(s->str[*pos]);(*pos)++); - return s->str[(*pos)++]; -} - -static INLINE void skip_to_eol(struct pike_string *s,INT32 *pos) -{ - for (;*pos<s->len && s->str[*pos]!=10;(*pos)++); -} - -static INLINE unsigned char getnext_skip_comment(struct pike_string *s,INT32 *pos) -{ - unsigned char c; - while ((c=getnext(s,pos))=='#') - skip_to_eol(s,pos); - return c; -} - -static INLINE void skipwhite(struct pike_string *s,INT32 *pos) -{ - while (*pos<s->len && - ( ISSPACE(s->str[*pos]) || - s->str[*pos]=='#')) - getnext_skip_comment(s,pos); -} - -static INLINE INT32 getnextnum(struct pike_string *s,INT32 *pos) -{ - INT32 i; - skipwhite(s,pos); - i=0; - while (*pos<s->len && - s->str[*pos]>='0' && s->str[*pos]<='9') - { - i=(i*10)+s->str[*pos]-'0'; - getnext(s,pos); - } - return i; -} - -static char* img_frompnm(struct pike_string *s) -{ - struct image new; - INT32 type,c=0,maxval=255; - INT32 pos=0,x,y,i; - - skipwhite(s,&pos); - if (getnext(s,&pos)!='P') return "not pnm"; /* not pnm */ - type=getnext(s,&pos); - if (type<'1'||type>'6') return "unknown type"; /* unknown type */ - new.xsize=getnextnum(s,&pos); - new.ysize=getnextnum(s,&pos); - if (new.xsize<=0||new.ysize<=0) return "illegal size"; /* illegal size */ - if (type=='3'||type=='2'||type=='6'||type=='5') - maxval=getnextnum(s,&pos); - new.img=malloc(new.xsize*new.ysize*sizeof(rgb_group)+1); - if (!new.img) error("Out of memory.\n"); - - if (type=='1'||type=='2'||type=='3') - { - skipwhite(s,&pos); - } - else - { - skip_to_eol(s,&pos); - pos++; - } - for (y=0; y<new.ysize; y++) - { - for (i=0,x=0; x<new.xsize; x++) - { - switch (type) - { - case '1': - c=getnextnum(s,&pos); - pixel(&new,x,y).r=pixel(&new,x,y).g=pixel(&new,x,y).b= - (unsigned char)~(c*255); - break; - case '2': - c=getnextnum(s,&pos); - pixel(&new,x,y).r=pixel(&new,x,y).g=pixel(&new,x,y).b= - (unsigned char)((c*255L)/maxval); - break; - case '3': - pixel(&new,x,y).r=(unsigned char)((getnextnum(s,&pos)*255L)/maxval); - pixel(&new,x,y).g=(unsigned char)((getnextnum(s,&pos)*255L)/maxval); - pixel(&new,x,y).b=(unsigned char)((getnextnum(s,&pos)*255L)/maxval); - break; - case '4': - if (!i) c=getnext(s,&pos),i=8; - pixel(&new,x,y).r=pixel(&new,x,y).g=pixel(&new,x,y).b= - (unsigned char)~(((c>>7)&1)*255); - c<<=1; - i--; - break; - case '5': - c=getnext(s,&pos); - pixel(&new,x,y).r=pixel(&new,x,y).g=pixel(&new,x,y).b= - (unsigned char)((c*255L)/maxval); - break; - case '6': - pixel(&new,x,y).r=(unsigned char)((getnext(s,&pos)*255L)/maxval); - pixel(&new,x,y).g=(unsigned char)((getnext(s,&pos)*255L)/maxval); - pixel(&new,x,y).b=(unsigned char)((getnext(s,&pos)*255L)/maxval); - break; - } - } - } - if (THIS->img) free(THIS->img); - THIS->xsize=new.xsize; - THIS->ysize=new.ysize; - THIS->img=new.img; - return NULL; -} - -void image_toppm(INT32 args) -{ - char buf[80]; - struct pike_string *a,*b; - - pop_n_elems(args); - if (!THIS->img) { error("no image\n"); return; } - sprintf(buf,"P6\n%d %d\n255\n",THIS->xsize,THIS->ysize); - a=make_shared_string(buf); - b=make_shared_binary_string((char*)THIS->img, - THIS->xsize*THIS->ysize*3); - push_string(add_shared_strings(a,b)); - free_string(a); - free_string(b); -} - - -void image_frompnm(INT32 args) -{ - char *s; - if (args<1|| - sp[-args].type!=T_STRING) - error("Illegal argument to image->frompnm()\n"); - s=img_frompnm(sp[-args].u.string); - pop_n_elems(args); - if (!s) { push_object(THISOBJ); THISOBJ->refs++; } - else push_string(make_shared_string(s)); -} - diff --git a/src/modules/image/quant.c b/src/modules/image/quant.c deleted file mode 100644 index 03aba30a99479a688adc1d541f5e150b0914d667..0000000000000000000000000000000000000000 --- a/src/modules/image/quant.c +++ /dev/null @@ -1,924 +0,0 @@ -#include <config.h> -/* $Id: quant.c,v 1.29 1997/01/27 07:56:21 per Exp $ */ - -/* - -quant, used by image when making gif's (mainly) - -Pontus Hagland, law@infovav.se -David K�gedal, kg@infovav.se - -*/ - -#include <unistd.h> -#include <stdio.h> - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#include "types.h" -#include "error.h" -#include "global.h" -#include "array.h" - -#include "threads.h" - - -#include "image.h" - -/* -#define QUANT_DEBUG_GAP -#define QUANT_DEBUG_POINT -#define QUANT_DEBUG -#define QUANT_DEBUG_RGB -*/ - -#define QUANT_MAXIMUM_NUMBER_OF_COLORS 65535 - -/**********************************************************************/ - -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - -/**********************************************************************/ - -#define sq(x) ((x)*(x)) -#define DISTANCE(A,B) \ - (sq(((int)(A).r)-((int)(B).r)) \ - +sq(((int)(A).g)-((int)(B).g)) \ - +sq(((int)(A).b)-((int)(B).b))) - - -typedef struct -{ - rgb_group rgb; - unsigned long count; - unsigned long next; -} rgb_entry; - -typedef struct -{ - unsigned long len; - rgb_entry tbl[1]; -} rgb_hashtbl; - -#define hash(rgb,l) (((rgb).r*127+(rgb).g*997+(rgb).b*2111)&(l-1)) -#define same_col(rgb1,rgb2) \ - (((rgb1).r==(rgb2).r) && ((rgb1).g==(rgb2).g) && ((rgb1).b==(rgb2).b)) - - -static INLINE int hash_enter(rgb_entry *rgbe,rgb_entry *end, - int len,rgb_group rgb) -{ - register rgb_entry *re; - - re=rgbe+hash(rgb,len); -/* fprintf(stderr,"%d\n",hash(rgb,len));*/ - - while (re->count && !same_col(re->rgb,rgb)) - if (++re==end) re=rgbe; - - if (!re->count) /* allocate it */ - { - re->rgb=rgb; - re->count=1; - return 1; - } - - re->count++; - return 0; -} - -static INLINE int hash_enter_strip(rgb_entry *rgbe,rgb_entry *end, - int len,rgb_group rgb,int strip) -{ - register rgb_entry *re; - - unsigned char strip_r[24]= -{ 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, - 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80 }; - unsigned char strip_g[24]= -{ 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, - 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80 }; - unsigned char strip_b[24]= -{ 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, - 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80 }; - - rgb.r&=strip_r[strip]; - rgb.g&=strip_g[strip]; - rgb.b&=strip_b[strip]; - - re=rgbe+hash(rgb,len); - - while (re->count && !same_col(re->rgb,rgb)) - if (++re==end) re=rgbe; - - if (!re->count) /* allocate it */ - { - re->rgb=rgb; - re->count=1; - return 1; - } - - re->count++; - return 0; -} - -static rgb_hashtbl *img_rehash(rgb_hashtbl *old, unsigned long newsize) -{ - unsigned long i; - rgb_hashtbl *new = malloc(sizeof(rgb_hashtbl) + - sizeof(rgb_entry) * newsize ); - MEMSET(new->tbl, 0, sizeof(rgb_entry) * newsize ); - - if (!new) error("Out of memory\n"); -#ifdef QUANT_DEBUG - fprintf(stderr,"img_rehash: old size = %lu, new size = %lu\n", - (old ? old->len : 0), newsize); -#endif - - new->len = newsize; - if (old) - { - for (i=0;i<old->len;i++) - if (old->tbl[i].count) - { - register rgb_entry *re; - - re=new->tbl+hash(old->tbl[i].rgb,newsize); - - while (re->count) - if (++re==new->tbl+newsize) re=new->tbl; - - *re=old->tbl[i]; - } - free(old); - } - return new; -} - -static int cmp_red(rgb_entry *e1, rgb_entry *e2) -{ - return e1->rgb.r - e2->rgb.r; -} - -static int cmp_green(rgb_entry *e1, rgb_entry *e2) -{ - return e1->rgb.g - e2->rgb.g; -} - -static int cmp_blue(rgb_entry *e1, rgb_entry *e2) -{ - return e1->rgb.b - e2->rgb.b; -} - -static int get_tbl_median(rgb_entry *tbl,int len) -{ - int a=0,x=0; - rgb_entry *m,*n; - - len--; - m=tbl; n=tbl+len-1; - while (m<n) - { -#if 0 - fprintf(stderr,"pos %3d,%3d sum %3d low=%3d,%3d,%3dc%3d high=%3d,%3d,%3dc%3d\n", - x,len,a, - tbl[x].rgb.r,tbl[x].rgb.g,tbl[x].rgb.b,tbl[x].count, - tbl[len].rgb.r,tbl[len].rgb.g,tbl[len].rgb.b,tbl[len].count); -#endif - if (a>0) a-=m++->count; - else a+=n--->count; - } - return m-tbl; -} - -static rgb_group get_tbl_point(rgb_entry *tbl,int len) -{ - unsigned long r=0,g=0,b=0,n=0; - int x; - rgb_group rgb; - for (x=0; x<len; x++) - { - r+=((unsigned long)tbl[x].rgb.r)*tbl[x].count, - g+=((unsigned long)tbl[x].rgb.g)*tbl[x].count, - b+=((unsigned long)tbl[x].rgb.b)*tbl[x].count; - n+=tbl[x].count; -#ifdef QUANT_DEBUG_POINT - fprintf(stderr,"(%d,%d,%d)*%lu; ", - tbl[x].rgb.r, - tbl[x].rgb.g, - tbl[x].rgb.b, - tbl[x].count); -#endif - } - rgb.r=(unsigned char)(r/n); - rgb.g=(unsigned char)(g/n); - rgb.b=(unsigned char)(b/n); -#ifdef QUANT_DEBUG_POINT - fprintf(stderr,"-> (%lu,%lu,%lu)/%lu = %d,%d,%d\n", - r,g,b,n, - rgb.r,rgb.g,rgb.b); -#endif - return rgb; -} - -#define MAKE_BINSORT(C,NAME) \ - void NAME(rgb_entry *e, unsigned long len) \ - { \ - unsigned long pos[256];\ - unsigned long i,j,k;\ - \ - rgb_entry *e2;\ - e2=(rgb_entry*)xalloc(sizeof(rgb_entry)*len);\ - \ - for (i=0; i<256; i++) pos[i]=~0;\ - \ - for (i=0; i<len; i++)\ - {\ - e[i].next=pos[j=e[i].rgb.C];\ - pos[j]=i;\ - }\ - \ - for (i=j=0; i<256; i++)\ - {\ - k=pos[i];\ - while (k!=(unsigned long)~0)\ - {\ - e2[j++]=e[k];\ - k=e[k].next;\ - }\ - }\ - MEMCPY(e,e2,len*sizeof(rgb_entry));\ - free(e2);\ - } - -MAKE_BINSORT(r,binsort_red) -MAKE_BINSORT(g,binsort_green) -MAKE_BINSORT(b,binsort_blue) - - -static void sort_tbl(rgb_hashtbl *ht, - unsigned long start, unsigned long len, - int level, unsigned long idx, - unsigned long gap, int ldir, - struct colortable *ct, rgb_group lower,rgb_group upper, - unsigned long **rn_next, - unsigned long *rgb_node) -{ - rgb_entry *tbl = ht->tbl; - - int (*sortfun)(const void *, const void *); - unsigned long x,y; - int dir=0; - -#ifdef QUANT_DEBUG - - fprintf(stderr,"%*ssort_tbl: level %d start = %lu " - " len=%lu, idx = %lu, gap = %lu", - level, "", - level, start, len, idx, gap); - fprintf(stderr,"\n%*s%d,%d,%d-%d,%d,%d ",level,"", - lower.r,lower.g,lower.b,upper.r,upper.g,upper.b); - -#endif - - if (len>1) - { - /* check which direction has the most span */ - /* we make it easy for us, only three directions: r,g,b */ - - -#define PRIO_RED 2 -#define PRIO_GREEN 4 -#define PRIO_BLUE 1 - -#if 0 - rgb_group min,max; - - max.r=min.r=tbl[start].rgb.r; - max.g=min.g=tbl[start].rgb.g; - max.b=min.b=tbl[start].rgb.b; - - for (x=1; x<len; x++) - { - if (min.r>tbl[start+x].rgb.r) min.r=tbl[start+x].rgb.r; - if (min.g>tbl[start+x].rgb.g) min.g=tbl[start+x].rgb.g; - if (min.b>tbl[start+x].rgb.b) min.b=tbl[start+x].rgb.b; - if (max.r<tbl[start+x].rgb.r) max.r=tbl[start+x].rgb.r; - if (max.g<tbl[start+x].rgb.g) max.g=tbl[start+x].rgb.g; - if (max.b<tbl[start+x].rgb.b) max.b=tbl[start+x].rgb.b; - } -#ifdef QUANT_DEBUG -fprintf(stderr,"space: %d,%d,%d-%d,%d,%d ", - min.r,min.g,min.b, - max.r,max.g,max.b); -#endif - - /* do this weighted, red=2 green=3 blue=1 */ - if ((max.r-min.r)*PRIO_RED>(max.g-min.g)*PRIO_GREEN) /* r>g */ - if ((max.r-min.r)*PRIO_RED>(max.b-min.b)*PRIO_BLUE) /* r>g, r>b */ - dir=0; - else /* r>g, b>r */ - dir=2; - else - if ((max.g-min.g)*PRIO_GREEN>(max.b-min.b)*PRIO_BLUE) /* g>r, g>b */ - dir=1; - else /* g>r, b>g */ - dir=2; -#endif - - rgbl_group sum={0,0,0}; - rgb_group mid; - - for (x=0; x<len; x++) - { - sum.r+=tbl[start+x].rgb.r; - sum.g+=tbl[start+x].rgb.g; - sum.b+=tbl[start+x].rgb.b; - } - mid.r=(unsigned char)(sum.r/len); - mid.g=(unsigned char)(sum.g/len); - mid.b=(unsigned char)(sum.b/len); - - sum.r=sum.g=sum.b=0; - for (x=0; x<len; x++) - { - sum.r+=sq(tbl[start+x].rgb.r-mid.r); - sum.g+=sq(tbl[start+x].rgb.g-mid.g); - sum.b+=sq(tbl[start+x].rgb.b-mid.b); - } - - if (sum.r*PRIO_RED>sum.g*PRIO_GREEN) /* r>g */ - if (sum.r*PRIO_RED>sum.b*PRIO_BLUE) /* r>g, r>b */ - dir=0; - else /* r>g, b>r */ - dir=2; - else - if (sum.g*PRIO_GREEN>sum.b*PRIO_BLUE) /* g>r, g>b */ - dir=1; - else /* g>r, b>g */ - dir=2; - - -#ifdef QUANT_DEBUG - fprintf(stderr," dir=%d ",dir); -#endif - if (dir!=ldir) - switch (dir) - { - case 0: binsort_red(tbl+start,len); break; - case 1: binsort_green(tbl+start,len); break; - case 2: binsort_blue(tbl+start,len); break; - } - -#ifdef QUANT_DEBUG - fprintf(stderr,"low: %d,%d,%d high: %d,%d,%d\n", - tbl[start].rgb.r, - tbl[start].rgb.g, - tbl[start].rgb.b, - tbl[start+len-1].rgb.r, - tbl[start+len-1].rgb.g, - tbl[start+len-1].rgb.b); -#endif - - } - - if (len>1 && gap>1) /* recurse */ - { - unsigned long pos,g1,g2; - rgb_group less,more,rgb; - unsigned char split_on=0; - int i; - - pos=get_tbl_median(tbl+start,len); - - rgb=tbl[start+pos].rgb; - - less=upper; - more=lower; - - switch (dir) - { - case 0: more.r=rgb.r+1; split_on=less.r=rgb.r; - while (pos<len-1 && tbl[start].rgb.r==tbl[start+pos].rgb.r) pos++; - while (pos>0 && tbl[start+len-1].rgb.r==tbl[start+pos].rgb.r) pos--; - break; - case 1: more.g=rgb.g+1; split_on=less.g=rgb.g; - while (pos<len-1 && tbl[start].rgb.g==tbl[start+pos].rgb.g) pos++; - while (pos>0 && tbl[start+len-1].rgb.g==tbl[start+pos].rgb.g) pos--; - break; - case 2: more.b=rgb.b+1; split_on=less.b=rgb.b; - while (pos<len-1 && tbl[start].rgb.b==tbl[start+pos].rgb.b) pos++; - while (pos>0 && tbl[start+len-1].rgb.b==tbl[start+pos].rgb.b) pos--; - break; - } - -#ifdef QUANT_DEBUG - fprintf(stderr, " pos=%lu len=%lu\n",pos,len); -#endif - -#ifdef QUANT_DEBUG_GAP - - fprintf(stderr,"\n left: "); - for (i=0; i<=pos; i++) - fprintf(stderr,"%d,%d,%d; ", - tbl[start+i].rgb.r,tbl[start+i].rgb.g,tbl[start+i].rgb.b); - fprintf(stderr,"\n right: "); - for (; i<len; i++) - fprintf(stderr,"%d,%d,%d; ", - tbl[start+i].rgb.r,tbl[start+i].rgb.g,tbl[start+i].rgb.b); - fprintf(stderr,"\n"); - -#endif - g1=gap>>1; - -#ifdef QUANT_DEBUG_GAP - fprintf(stderr,"gap: %d / %d pos+1=%d len-pos-1=%d gap-g1=%d\n", - g1,gap-g1,pos+1,len-pos-1,gap-g1); -#endif - - if (pos+1<g1) g1=pos+1,g2=gap-g1; - else if (len-pos-1<gap-g1) g2=(len-pos-1),g1=gap-g2; - else g2=gap-g1; - -#ifdef QUANT_DEBUG - fprintf(stderr,"gap: %d / %d ",g1,g2); -#endif - - if (gap>1) - { - /* split tree */ - - *rgb_node= - ( (*rn_next)-ct->rgb_node ) - | ( ((unsigned long)split_on) << 22 ) - | ( (dir+1)<<30 ) & 0xffffffff; - rgb_node=*rn_next; - (*rn_next)+=2; - - sort_tbl(ht,start,pos+1, - level+1,idx,g1,dir, - ct,lower,less,rn_next,rgb_node++); - - sort_tbl(ht,start+pos+1,len-pos-1, - level+1,idx+g1,g2,dir, - ct,more,upper,rn_next,rgb_node); - } - else - { - /* this shouldn't occur? /law */ - abort(); - sort_tbl(ht,start,pos+1, - level+1,idx,g1,dir, - ct,lower,less,rn_next,rgb_node); - } - return; - } - else - { - int r,g,b; - if (len>1) - ct->clut[idx]=get_tbl_point(tbl+start,len); - else - ct->clut[idx]=tbl[start].rgb; - -#ifdef QUANT_DEBUG - fprintf(stderr,"-> end node [%d,%d,%d] - [%d,%d,%d] => %d,%d,%d\n", - lower.r, lower.g, lower.b, upper.r, upper.g, upper.b, - ct->clut[idx].r,ct->clut[idx].g,ct->clut[idx].b); -#endif - - /* write end node */ - *rgb_node=idx; /* done */ - } -} - -static struct colortable *colortable_allocate(int numcol) -{ - struct colortable *ct; - ct = malloc(sizeof(struct colortable)+ - sizeof(rgb_group)*numcol); - if (!ct) error("Out of memory.\n"); - MEMSET(ct,0,sizeof(struct colortable)+ - sizeof(rgb_group)*numcol); - ct->numcol=numcol; - ct->rgb_node=malloc(sizeof(unsigned long)*numcol*4); - MEMSET(ct->rgb_node,0, - sizeof(unsigned long)*numcol*4); - return ct; -} - -struct colortable *colortable_quant(struct image *img,int numcol) -{ - rgb_hashtbl *tbl; - INT32 i,j; - INT32 sz = img->xsize * img->ysize; - rgb_entry entry; - struct colortable *ct=NULL; - rgb_group black,white; - rgb_group *p; - INT32 entries=0; - unsigned long *next_free_rgb_node; - - THREADS_ALLOW(); -#ifdef QUANT_DEBUG - fprintf(stderr,"img_quant called\n"); -#endif - CHRONO("quant"); - - if (numcol<2) numcol=2; - - if (numcol>MAX_NUMCOL) numcol=MAX_NUMCOL; - - ct = colortable_allocate(numcol); - -#ifdef QUANT_DEBUG - fprintf(stderr,"Moving colors into hashtable\n"); -#endif - - for (;;) - { - int strip=0; -rerun: - entries=0; - - - CHRONO("hash init"); - - tbl = img_rehash(NULL, 8192); - - p=img->img; - i=sz; - do - { - register rgb_entry *rgbe,*end; - int len,trig; - -#ifdef QUANT_DEBUG - fprintf(stderr,"hash: %d pixels left...\n",i); -#endif - CHRONO("hash..."); - - len=tbl->len; - trig=(len*2)/10; /* 20% full => rehash bigger */ - end=(rgbe=tbl->tbl)+tbl->len; - - if (!strip) - { - while (i--) - if ( (entries+=hash_enter(rgbe,end,len,*(p++))) > trig ) - { -#ifdef QUANT_DEBUG - fprintf(stderr,"rehash: 20%% = %d / %d...\n",entries,len); -#endif - CHRONO("rehash..."); - if ((len<<2) > QUANT_MAXIMUM_NUMBER_OF_COLORS) - { - strip++; - fprintf(stderr,"strip: %d\n",strip); - free(tbl); - goto rerun; - } - tbl=img_rehash(tbl,len<<2); /* multiple size by 4 */ - break; - } - } - else - while (i--) - if ( (entries+=hash_enter_strip(rgbe,end,len,*(p++),strip)) > trig ) - { -#ifdef QUANT_DEBUG - fprintf(stderr,"rehash: 20%% = %d / %d...\n",entries,len); -#endif - CHRONO("rehash..."); - if ((len<<2) > QUANT_MAXIMUM_NUMBER_OF_COLORS) - { - strip++; - free(tbl); - goto rerun; - } - tbl=img_rehash(tbl,len<<2); /* multiple size by 4 */ - break; - } - } - while (i>=0); - break; - } - - /* Compact the hash table */ - CHRONO("compact"); - -#ifdef QUANT_DEBUG - fprintf(stderr,"Compacting\n"); -#endif - i = tbl->len - 1; - j = 0; - while (i > entries) - { - while ((i >= entries) && tbl->tbl[i].count == 0) i--; - while ((j < entries) && tbl->tbl[j].count != 0) j++; - if (j<i) - { - tbl->tbl[j] = tbl->tbl[i]; - tbl->tbl[i].count = 0; - } - } - - white.r=white.g=white.b=255; - black.r=black.g=black.b=0; - -#ifdef QUANT_DEBUG - fprintf(stderr,"%d colors found, sorting and quantizing...\n",j); -#endif - - CHRONO("sort"); - if (j<numcol) ct->numcol=numcol=j; - - next_free_rgb_node=ct->rgb_node+1; - sort_tbl(tbl, 0, j, 0, 0, numcol, -1, ct, black, white, - &next_free_rgb_node,ct->rgb_node); - -#ifdef QUANT_DEBUG - fprintf(stderr,"img_quant done, %d colors selected\n", numcol); -#endif - CHRONO("done"); - - free(tbl); - CHRONO("really done"); - THREADS_DISALLOW(); - return ct; -} - - -struct colortable *colortable_from_array(struct array *arr,char *from) -{ - rgb_hashtbl *tbl; - INT32 i,j; - struct colortable *ct=NULL; - rgb_group black,white; - rgb_group *p; - INT32 entries=0; - struct svalue s,s2; - unsigned long *next_free_rgb_node; - - THREADS_ALLOW(); -#ifdef QUANT_DEBUG - fprintf(stderr,"ctfa called\n"); -#endif - CHRONO("ctfa"); - - white.r=white.g=white.b=255; - black.r=black.g=black.b=0; - - tbl=img_rehash(NULL,arr->size); - - s2.type=s.type=T_INT; - for (i=0; i<arr->size; i++) - { - array_index(&s,arr,i); - if (s.type!=T_ARRAY || s.u.array->size<3) - { - free(tbl); - error("Illegal type in colorlist, element %d, %s\n",i,from); - } - array_index(&s2,s.u.array,0); - if (s2.type!=T_INT) tbl->tbl[i].rgb.r=0; else tbl->tbl[i].rgb.r=s2.u.integer; - array_index(&s2,s.u.array,1); - if (s2.type!=T_INT) tbl->tbl[i].rgb.g=0; else tbl->tbl[i].rgb.g=s2.u.integer; - array_index(&s2,s.u.array,2); - if (s2.type!=T_INT) tbl->tbl[i].rgb.b=0; else tbl->tbl[i].rgb.b=s2.u.integer; - tbl->tbl[i].count=1; - } - free_svalue(&s); - free_svalue(&s2); - - ct = colortable_allocate(arr->size); - - CHRONO("sort"); - next_free_rgb_node=ct->rgb_node+1; - sort_tbl(tbl, 0, arr->size, 0, 0, arr->size, -1, ct, black, white, - &next_free_rgb_node,ct->rgb_node); - -#ifdef QUANT_DEBUG - fprintf(stderr,"img_quant done, %d colors selected\n", arr->size); -#endif - CHRONO("done"); - - free(tbl); - - for (i=0; i<QUANT_SELECT_CACHE; i++) - ct->cache[i].index=white; - j=colortable_rgb(ct,black); /* ^^ dont find it in the cache... */ - for (i=0; i<QUANT_SELECT_CACHE; i++) - ct->cache[i].index=black, - ct->cache[i].value=j; - - CHRONO("really done"); - THREADS_DISALLOW(); - return ct; -} - - -int colortable_rgb(struct colortable *ct,rgb_group rgb) -{ - int i,best; - - if (ct->cache->index.r==rgb.r && - ct->cache->index.g==rgb.g && - ct->cache->index.b==rgb.b) - return ct->cache->value; - -#ifdef QUANT_DEBUG_RGB -fprintf(stderr,"rgb: %d,%d,%d\n",rgb.r,rgb.g,rgb.b); -#endif - -#if QUANT_SELECT_CACHE>1 - for (i=1; i<QUANT_SELECT_CACHE; i++) - if (ct->cache[i].index.r==rgb.r && - ct->cache[i].index.g==rgb.g && - ct->cache[i].index.b==rgb.b) - { - best=ct->cache[i].value; - - MEMMOVE(ct->cache+1,ct->cache, - i*sizeof(struct rgb_cache)); - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB -fprintf(stderr,"cache: %lu: %d,%d,%d\n",best,ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; - } -#endif - - /* find node */ - -#if 1 - - do - { - rgb_group min={0,0,0},max={255,255,255}; - unsigned long *rn; - unsigned char split; - - rn=ct->rgb_node; - - for (;;) - { -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"-> %d: %c%d %d\n", - rn-ct->rgb_node, - (((*rn)>>30)==0)?'c': - (((*rn)>>30)==1)?'r': - (((*rn)>>30)==2)?'g':'b', - ((*rn)>>22) & 255, - ((*rn)&4194303)); -#endif - - switch ((*rn)>>30) - { - case 0: /* end node */ break; - case 1: /* red */ - split=(unsigned char)( ((*rn)>>22) & 255 ); - rn=ct->rgb_node+((*rn)&4194303); - if (rgb.r<=split) max.r=split; - else rn++,min.r=split+1; - continue; - case 2: /* green */ - split=(unsigned char)( ((*rn)>>22) & 255 ); - rn=ct->rgb_node+((*rn)&4194303); - if (rgb.g<=split) max.g=split; - else rn++,min.g=split+1; - continue; - case 3: /* blue */ - split=(unsigned char)( ((*rn)>>22) & 255 ); - rn=ct->rgb_node+((*rn)&4194303); - if (rgb.b<=split) max.b=split; - else rn++,min.b=split+1; - continue; - } - break; - } - best=*rn; - } - while (0); - -#endif - - /* place in cache */ -#if QUANT_SELECT_CACHE>1 - MEMMOVE(ct->cache+1,ct->cache, - (QUANT_SELECT_CACHE-1)*sizeof(struct rgb_cache)); -#endif - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB -fprintf(stderr," -> %lu: %d,%d,%d\n",best, - ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; -} - -int colortable_rgb_nearest(struct colortable *ct,rgb_group rgb) -{ - int i,best=0,di,di2; - rgb_group *prgb; - - if (ct->cache->index.r==rgb.r && - ct->cache->index.g==rgb.g && - ct->cache->index.b==rgb.b) - return ct->cache->value; - -#ifdef QUANT_DEBUG_RGB -fprintf(stderr,"rgb_n: #%02x%02x%02x; ",rgb.r,rgb.g,rgb.b); -#endif - -#if QUANT_SELECT_CACHE>1 - for (i=1; i<QUANT_SELECT_CACHE; i++) - if (ct->cache[i].index.r==rgb.r && - ct->cache[i].index.g==rgb.g && - ct->cache[i].index.b==rgb.b) - { - best=ct->cache[i].value; - - MEMMOVE(ct->cache+1,ct->cache, - i*sizeof(struct rgb_cache)); - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB -fprintf(stderr,"cache: %lu: %d,%d,%d\n",best,ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; - } -#endif - - /* find node */ - - di=1000000L; - for (i=0; i<ct->numcol; i++) - { - prgb=ct->clut+i; - if ((di2=DISTANCE(*prgb,rgb))<di) - { - best=i; - di=di2; -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"#%02x%02x%02x (%d) (%d), ", - ct->clut[i].r, - ct->clut[i].g, - ct->clut[i].b, - i,di); -#endif - } - } -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"\n"); -#endif - - /* place in cache */ -#if QUANT_SELECT_CACHE>1 - MEMMOVE(ct->cache+1,ct->cache, - (QUANT_SELECT_CACHE-1)*sizeof(struct rgb_cache)); -#endif - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB -fprintf(stderr," -> %lu: %d,%d,%d\n",best, - ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; -} - -void colortable_free(struct colortable *ct) -{ - int r,g,b; - free((char *)ct->rgb_node); - free((char *)ct); -} diff --git a/src/modules/image/testfont b/src/modules/image/testfont deleted file mode 100644 index 3705501ac48434af2a765ba61eee5a6718d3540e..0000000000000000000000000000000000000000 Binary files a/src/modules/image/testfont and /dev/null differ diff --git a/src/modules/image/testsuite.in b/src/modules/image/testsuite.in deleted file mode 100644 index b8a35edf849d18b3b0ca44ca915ed7063d3b1e7a..0000000000000000000000000000000000000000 --- a/src/modules/image/testsuite.in +++ /dev/null @@ -1,52 +0,0 @@ -cond([[ master()->programs["/precompiled/image"] ]], -[[ - test_true(programp(Image)) - test_true(objectp(clone(Image))) - test_true(objectp(clone(Image,10,10))) - test_true(objectp(clone(Image,10,10,1,1,1))) - test_eq(clone(Image,10,12)->xsize(),10)) - test_eq(clone(Image,10,12)->ysize(),12)) - test_true(objectp(clone(Image,10,10,1,1,1)->copy())) - test_eq(clone(Image,10,12)->copy()->xsize(),10)) - test_eq(clone(Image,10,12)->copy()->ysize(),12)) -dnl test_true(objectp(clone(Image,10,10)->crop(2,2,3,3))) - test_true(objectp(clone(Image,10,10)->autocrop())) - test_true(objectp(clone(Image,10,10)->gray())) - test_true(objectp(clone(Image,10,10)->color(2,2,4))) - test_true(objectp(clone(Image,10,10)->invert())) - test_true(objectp(clone(Image,10,10)->threshold(10,20,30))) -dnl matrix - test_true(objectp(clone(Image,10,10)->scale(2.1))) - test_eq(clone(Image,10,12)->scale(2.0)->xsize(),20) - test_eq(clone(Image,10,12)->scale(2.0)->ysize(),24) - test_true(objectp(clone(Image,10,10)->scale(0.2))) - test_true(objectp(clone(Image,10,10)->scale(2.0,0.2))) - test_true(objectp(clone(Image,10,10)->scale(0.2,2.2))) - test_true(objectp(clone(Image,10,10)->scale(0.2,2.2))) - test_true(objectp(clone(Image,10,10)->scale(0.2,2.2))) - test_eq(clone(Image,10,10)->scale(33,57)->xsize(),33) - test_eq(clone(Image,10,10)->scale(33,57)->ysize(),57) - test_true(stringp(clone(Image,10,10)->toppm())) -dnl fromppm - test_true(stringp(clone(Image,10,10)->toppm())) - test_true(stringp(clone(Image,10,10)->togif())) - test_true(objectp(clone(Image,10,10)->paste(clone(Image,3,3),2,3))) -dnl past_alpha -dnl past_mask - test_do(clone(Image,10,10)->setcolor(2,2,2)) - test_do(clone(Image,10,10)->setpixel(2,2,2,2,2)) - test_do(clone(Image,10,10)->line(2,2,4,4,2,2,2)) - test_do(clone(Image,10,10)->box(2,2,4,4,2,2,2)) - test_do(clone(Image,10,10)->circle(2,2,4,4,2,2,2)) -dnl tuned_box - test_eq(clone(Image,10,10)->xsize(),10) - test_eq(clone(Image,10,10)->ysize(),10) - test_do(clone(Font)) - test_do(clone(Font)->load("SRCDIR/testfont")) - test_any(object o=clone(Font); o->load("SRCDIR/testfont"); return o->height(),19) - test_any(object o=clone(Font); o->load("SRCDIR/testfont"); return o->write("foo")->xsize(),23) - test_any(object o=clone(Font); o->load("SRCDIR/testfont"); return -o->write("foo")->ysize(),20) -dnl test_any(object o=clone(Font); o->load("SRCDIR/testfont"); o->write("foo"); clone(Image,100,100)->paste_alpha(o); return 1,1) -]]) - diff --git a/src/modules/image/togif.c b/src/modules/image/togif.c deleted file mode 100644 index 6487272a9244ad8044695ffc7ed97f14338af9da..0000000000000000000000000000000000000000 --- a/src/modules/image/togif.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - -togif - -Pontus Hagland, law@infovav.se - -$Id: togif.c,v 1.25 1997/01/14 16:20:19 law Exp $ - -*/ - -#include "global.h" - -#include <math.h> -#include <ctype.h> - -#include "stralloc.h" -#include "global.h" -#include "threads.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "array.h" -#include "error.h" -#include "dynamic_buffer.h" - -#include "image.h" -#include "lzw.h" - -#define INITIAL_BUF_LEN 8192 - -#define THIS ((struct image *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) -#define testrange(x) max(min((x),255),0) - -static void buf_word( unsigned short w, dynamic_buffer *buf ) -{ - low_my_putchar( w&0xff, buf ); - low_my_putchar( (w>>8)&0xff, buf ); -} - -#define WEIGHT_NEXT(X) (((X)*8)/20) -#define WEIGHT_DOWNNEXT(X) (((X)*3)/20) -#define WEIGHT_DOWN(X) (((X)*3)/20) -#define WEIGHT_DOWNBACK(X) (((X)*0)/20) - -static int floyd_steinberg_add(rgbl_group *errl, - rgbl_group *errlfwd, - rgbl_group *errlback, - rgbl_group *err, - rgb_group rgb, - struct colortable *ct) -{ - rgb_group rgb2,rgb3; - rgbl_group cerr; - int c; - rgb2.r=testrange((long)rgb.r+err->r/FS_SCALE); - rgb2.g=testrange((long)rgb.g+err->g/FS_SCALE); - rgb2.b=testrange((long)rgb.b+err->b/FS_SCALE); -#ifdef FS_DEBUG - fprintf(stderr,"%g,%g,%g+%g,%g,%g=%g,%g,%g ", - 1.0*rgb.r, 1.0*rgb.g, 1.0*rgb.b, - err->r*1.0/FS_SCALE, err->g*1.0/FS_SCALE, err->b*1.0/FS_SCALE, - rgb2.r*1.0, rgb2.g*1.0, rgb2.b*1.0); -#endif - c=colortable_rgb(ct,rgb2); - rgb3=ct->clut[c]; - cerr.r=(long)rgb.r*FS_SCALE-(long)rgb3.r*FS_SCALE+err->r; - cerr.g=(long)rgb.g*FS_SCALE-(long)rgb3.g*FS_SCALE+err->g; - cerr.b=(long)rgb.b*FS_SCALE-(long)rgb3.b*FS_SCALE+err->b; - -#ifdef FS_DEBUG - fprintf(stderr,"got %g,%g,%g err %g,%g,%g ", - 1.0*rgb3.r, - 1.0*rgb3.g, - 1.0*rgb3.b, - 1.0*cerr.r, - 1.0*cerr.g, - 1.0*cerr.b); -#endif - - errl->r+=WEIGHT_DOWN(cerr.r); - errl->g+=WEIGHT_DOWN(cerr.g); - errl->b+=WEIGHT_DOWN(cerr.b); - if (errlback) - { - errlback->r+=WEIGHT_DOWNBACK(cerr.r); - errlback->g+=WEIGHT_DOWNBACK(cerr.g); - errlback->b+=WEIGHT_DOWNBACK(cerr.b); -#ifdef FS_DEBUG - fprintf(stderr,"errlback=>%g ",errlback->g*1.0/FS_SCALE); -#endif - } - if (errlfwd) - { - err->r=WEIGHT_NEXT(cerr.r); - err->g=WEIGHT_NEXT(cerr.g); - err->b=WEIGHT_NEXT(cerr.b); - err->r+=errlfwd->r; - err->g+=errlfwd->g; - err->b+=errlfwd->b; - errlfwd->r=WEIGHT_DOWNNEXT(cerr.r); - errlfwd->g=WEIGHT_DOWNNEXT(cerr.g); - errlfwd->b=WEIGHT_DOWNNEXT(cerr.b); -#ifdef FS_DEBUG - fprintf(stderr,"errlfwd=>%g ",errlfwd->g*1.0/FS_SCALE); -#endif - } -#ifdef FS_DEBUG - fprintf(stderr,"errl=>%g ",errl->g*1.0/FS_SCALE); - fprintf(stderr,"err=>%g\n",err->g*1.0/FS_SCALE); -#endif - return c; -} - -void image_floyd_steinberg(rgb_group *rgb,int xsize, - rgbl_group *errl, - int way,int *res, - struct colortable *ct) -{ - rgbl_group err; - int x; - - if (way) - { - err.r=errl[xsize-1].r; - err.g=errl[xsize-1].g; - err.b=errl[xsize-1].b; - for (x=xsize-1; x>=0; x--) - res[x]=floyd_steinberg_add(errl+x, - (x==0)?NULL:errl+x-1, - (x==xsize-1)?NULL:errl+x+1, - &err,rgb[x],ct); - } - else - { - err.r=errl->r; - err.g=errl->g; - err.b=errl->b; - for (x=0; x<xsize; x++) - res[x]=floyd_steinberg_add(errl+x, - (x==xsize-1)?NULL:errl+x+1, - (x==0)?NULL:errl+x-1, - &err,rgb[x],ct); - } -} - - -struct pike_string * - image_encode_gif(struct image *img,struct colortable *ct, - rgb_group *transparent,int fs) -{ - dynamic_buffer buf; - long i; - rgb_group *rgb; - struct lzw lzw; - int colors,bpp; - -CHRONO("image_encode_gif begin"); - - buf.s.str=NULL; - initialize_buf(&buf); - - colors=4; bpp=2; - while (colors<ct->numcol) { colors<<=1; bpp++; } - - low_my_binary_strcat(transparent?"GIF89a":"GIF87a",6,&buf); - buf_word((unsigned short)img->xsize,&buf); - buf_word((unsigned short)img->ysize,&buf); - low_my_putchar( (char)(0xf0|(bpp-1)), &buf); - /* | global colormap | 3 bits color res | sort | 3 bits bpp */ - /* color res is'nt cared of */ - - low_my_putchar( 0, &buf ); /* background color */ - low_my_putchar( 0, &buf ); /* just zero */ - - for (i=0; i<ct->numcol; i++) - { - low_my_putchar(ct->clut[i].r,&buf); - low_my_putchar(ct->clut[i].g,&buf); - low_my_putchar(ct->clut[i].b,&buf); - } - - for (; i<colors; i++) - { - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - } - - if (transparent) - { - i=colortable_rgb(ct,*transparent); - - low_my_putchar( '!', &buf ); /* extras */ - low_my_putchar( 0xf9, &buf ); /* transparency */ - low_my_putchar( 4, &buf ); - low_my_putchar( 1, &buf ); - low_my_putchar( 0, &buf ); - low_my_putchar( 0, &buf ); - low_my_putchar( i, &buf ); - low_my_putchar( 0, &buf ); - } - - - low_my_putchar( ',', &buf ); /* image separator */ - - buf_word(0,&buf); /* leftofs */ - buf_word(0,&buf); /* topofs */ - buf_word(img->xsize,&buf); /* width */ - buf_word(img->ysize,&buf); /* height */ - - low_my_putchar(0x00, &buf); - /* not interlaced (interlaced == 0x40) */ - /* no local colormap ( == 0x80) */ - - low_my_putchar( bpp, &buf ); /* bits per pixel , or min 2 */ - - i=img->xsize*img->ysize; - rgb=img->img; - -CHRONO("image_encode_gif header done"); - -THREADS_ALLOW(); - lzw_init(&lzw,bpp); - if (!fs) - while (i--) lzw_add(&lzw,colortable_rgb(ct,*(rgb++))); - else - { - rgbl_group *errb; - rgb_group corgb; - int w,*cres,j; - errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*img->xsize); - cres=(int*)xalloc(sizeof(int)*img->xsize); - for (i=0; i<img->xsize; i++) - errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; - - w=0; - i=img->ysize; - while (i--) - { - image_floyd_steinberg(rgb,img->xsize,errb,w=!w,cres,ct); - for (j=0; j<img->xsize; j++) - lzw_add(&lzw,cres[j]); - rgb+=img->xsize; - } - - free(errb); - free(cres); - } - - lzw_write_last(&lzw); - -CHRONO("lzw done"); - - for (i=0; i<(int)lzw.outpos; i+=254) - { - int wr; - if (i+254>(int)lzw.outpos) wr=lzw.outpos-i; - else wr=254; - low_my_putchar( (unsigned char)wr, &buf ); /* bytes in chunk */ - low_my_binary_strcat( (char *) lzw.out+i, wr, &buf ); - } - low_my_putchar( 0, &buf ); /* terminate stream */ - -CHRONO("image_encode_gif wrote ok"); - - lzw_quit(&lzw); - - low_my_putchar( ';', &buf ); /* end gif file */ - -CHRONO("image_encode_gif done"); -THREADS_DISALLOW(); - - return low_free_buf(&buf); -} - -#define STD_ARENA_SIZE 16384 - -int image_decode_gif(struct image *dest,struct image *dest_alpha, - unsigned char *src,unsigned long len) -{ - unsigned char *arena,*tmpstore,*q; - rgb_group *global_palette,*palette; - rgb_group *rgb; - int bpp; - unsigned long i,j; - INT32 mod; - INT32 leftofs,topofs,width,height; - int interlaced,transparent; - unsigned long arenalen,pos; - - if (src[0]!='G' - ||src[1]!='I' - ||src[2]!='F' - ||len<12) - return 0; /* not a gif, you fool */ - - dest->xsize=src[6]+(src[7]<<8); - dest->ysize=src[8]+(src[9]<<8); - - if (! (arena=malloc(arenalen=STD_ARENA_SIZE)) ) return 0; - - dest->img=malloc(dest->xsize*dest->ysize*sizeof(rgb_group)); - if (!dest->img) { free(arena); return 0; } - /* out of memory (probably illegal size) */ - - bpp=(src[10]&7)+1; - - THREADS_ALLOW(); - if (src[10]&128) - { - global_palette=(rgb_group*)(src+13); - src+=3*(1<<bpp); - len-=3*(1<<bpp); - rgb=dest->img; - i=dest->xsize*dest->ysize; -/* - while (i--) - *rgb=global_palette[src[11]]; * paint with background color */ - - } - else - global_palette=NULL; - MEMSET(dest->img,0,sizeof(rgb_group)*dest->xsize*dest->ysize); - src+=13; len-=13; - - do - { - switch (*src) - { - case '!': /* function block */ - if (len<7) break; /* no len left */ - if (src[1]==0xf9) - transparent=src[6]; - len-=src[3]+1; - src+=src[3]+1; - continue; - case ',': /* image block(s) */ - if (len<10) len-=10; /* no len left */ - leftofs=src[1]+(src[2]<<8); - topofs=src[3]+(src[4]<<8); - width=src[5]+(src[6]<<8); - height=src[7]+(src[8]<<8); - interlaced=src[9]&64; - - if (src[9]&128) - { - palette=(rgb_group*)(src+10); - src+=((src[9]&7)+1)*3; - } - else - palette=global_palette; - - src+=11; - len-=11; - pos=0; - if (len<3) break; /* no len left */ - bpp=src[-1]; - - while (len>1) - { - if (!(i=*src)) break; /* length of block */ - if (pos+i>arenalen) - { - arena=realloc(arena,arenalen*=2); - if (!arena) return 1; - } - MEMCPY(arena+pos,src+1,min(i,len-1)); - pos+=min(i,len-1); - len-=i+1; - src+=i+1; - } - - if (leftofs+width<=dest->xsize && topofs+height<=dest->ysize) - { - tmpstore=malloc(width*height); - if (!tmpstore) break; - i=lzw_unpack(tmpstore,width*height,arena,pos,bpp); - if (i!=(unsigned long)(width*height)) - MEMSET(tmpstore+i,0,width*height-i); - rgb=dest->img+leftofs+topofs*dest->ysize; - mod=width-dest->xsize; - j=height; - q=tmpstore; - if (palette) - while (j--) - { - i=width; - while (i--) *(rgb++)=palette[*(q++)]; - rgb+=mod; - } - free(tmpstore); - } - - continue; - case ';': - - break; /* file done */ - default: - break; /* unknown, file is ok? */ - } - } - while (0); - THREADS_DISALLOW(); - - if (arena) free(arena); - return 1; /* ok */ -} - - - -void image_fromgif(INT32 args) -{ - if (sp[-args].type!=T_STRING) - error("Illegal argument to image->fromgif()\n"); - - if (THIS->img) free(THIS->img); - THIS->img=NULL; - - image_decode_gif(THIS,NULL,sp[-args].u.string->str,sp[-args].u.string->len); - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -static INLINE void getrgb(struct image *img, - INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; - img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; - img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; - if (args-args_start>=4) - if (sp[3-args+args_start].type!=T_INT) - error("Illegal alpha argument to %s\n",name); - else - img->alpha=sp[3-args+args_start].u.integer; - else - img->alpha=0; -} - -void image_togif(INT32 args) -{ - rgb_group *transparent=NULL; - struct colortable *ct=NULL; - - if (args>0 && sp[-args].type==T_ARRAY) - ct=colortable_from_array(sp[-args].u.array,"image->togif()\n"); - else if (args>0 && args!=3 && sp[-args].type==T_INT) - ct=colortable_quant(THIS,min(256,max(2,sp[-args].u.integer))); - - if (args>=3+!!ct) - { - getrgb(THIS,!!ct,args,"image->togif() (transparency)"); - transparent=&(THIS->rgb); - } - - pop_n_elems(args); - if (!THIS->img) { error("no image\n"); return; } - - if (!ct) ct=colortable_quant(THIS,256); - push_string( image_encode_gif( THIS,ct, transparent, 0) ); - colortable_free(ct); -} - - -void image_togif_fs(INT32 args) -{ - rgb_group *transparent=NULL; - struct colortable *ct=NULL; - - if (args>0 && sp[-args].type==T_ARRAY) - ct=colortable_from_array(sp[-args].u.array,"image->togif_fs()\n"); - else if (args>0 && args!=3 && sp[-args].type==T_INT) - ct=colortable_quant(THIS,min(256,max(2,sp[-args].u.integer))); - - if (args>=3+!!ct) - { - getrgb(THIS,!!ct,args,"image->togif() (transparency)"); - transparent=&(THIS->rgb); - } - - pop_n_elems(args); - if (!THIS->img) { error("no image\n"); return; } - - if (!ct) - ct=colortable_quant(THIS,256); - push_string( image_encode_gif( THIS,ct, transparent, 1) ); - colortable_free(ct); -} - -void image_gif_begin(INT32 args) -{ - dynamic_buffer buf; - long i; - int colors,bpp; - struct colortable *ct=NULL; - - if (args) - if (sp[-args].type==T_INT && sp[-args].u.integer!=0) - ct=colortable_quant(THIS,max(256,min(2,sp[-args].u.integer))); - else if (sp[-args].type==T_ARRAY) - ct=colortable_from_array(sp[-args].u.array,"image->gif_begin()\n"); - - pop_n_elems(args); - - buf.s.str=NULL; - initialize_buf(&buf); - - if (ct) - { - colors=4; bpp=2; - while (colors<ct->numcol) { colors<<=1; bpp++; } - } - else - { - colors=256; bpp=8; - } - - low_my_binary_strcat("GIF89a",6,&buf); - buf_word((unsigned short)THIS->xsize,&buf); - buf_word((unsigned short)THIS->ysize,&buf); - low_my_putchar( (char)((0x80*!!ct) | 0x70 | (bpp-1) ), &buf); - /* | global colormap | 3 bits color res | sort | 3 bits bpp */ - /* color res is'nt cared of */ - - low_my_putchar( 0, &buf ); /* background color */ - low_my_putchar( 0, &buf ); /* just zero */ - - if (!!ct) - { - for (i=0; i<ct->numcol; i++) - { - low_my_putchar(ct->clut[i].r,&buf); - low_my_putchar(ct->clut[i].g,&buf); - low_my_putchar(ct->clut[i].b,&buf); - } - - for (; i<colors; i++) - { - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - } - } - push_string(low_free_buf(&buf)); -} - -void image_gif_end(INT32 args) -{ - pop_n_elems(args); - push_string(make_shared_binary_string(";",1)); -} - -void image_gif_netscape_loop(INT32 args) -{ - unsigned short loops=0; - char buf[30]; - if (args) - if (sp[-args].type!=T_INT) - error("Illegal argument to image->gif_netscape_loop()\n"); - else - loops=sp[-args].u.integer; - else - loops=65535; - pop_n_elems(args); - - sprintf(buf,"%c%c%cNETSCAPE2.0%c%c%c%c%c", - 33,255,11,3,1,loops&255,(loops>>8)&255,0); - - push_string(make_shared_binary_string(buf,19)); -} - -static void img_gif_add(INT32 args,int fs,int lm) -{ - INT32 x=0,y=0,i; - struct lzw lzw; - rgb_group *rgb; - struct colortable *ct=NULL; - dynamic_buffer buf; - int colors,bpp; - -CHRONO("gif add init"); - - buf.s.str=NULL; - initialize_buf(&buf); - - if (args==0) x=y=0; - else if (sp[-args].type!=T_INT - || sp[1-args].type!=T_INT) - error("Illegal argument(s) to image->gif_add()\n"); - else - { - x=sp[-args].u.integer; - y=sp[1-args].u.integer; - } - - - if (args>2 && sp[2-args].type==T_ARRAY) - ct=colortable_from_array(sp[2-args].u.array,"image->gif_add()\n"); - else if (args>3 && sp[2-args].type==T_INT) - ct=colortable_quant(THIS,max(256,min(2,sp[2-args].u.integer))); - - if (args>2+!!ct) - { - unsigned short delay=0; - if (sp[2+!!ct-args].type==T_INT) - delay=sp[2+!!ct-args].u.integer; - else if (sp[2+!!ct-args].type==T_FLOAT) - delay=(unsigned short)(sp[2+!!ct-args].u.float_number*100); - else - error("Illegal argument %d to image->gif_add()\n",3+!!ct); - - low_my_putchar( '!', &buf ); /* extension block */ - low_my_putchar( 0xf9, &buf ); /* graphics control */ - low_my_putchar( 4, &buf ); /* block size */ - low_my_putchar( 0, &buf ); /* disposal, transparency, blabla */ - buf_word( delay, &buf ); /* delay in centiseconds */ - low_my_putchar( 0, &buf ); /* (transparency index) */ - low_my_putchar( 0, &buf ); /* terminate block */ - } - - ct=colortable_quant(THIS,256); - - colors=4; bpp=2; - while (colors<ct->numcol) { colors<<=1; bpp++; } - - - - - low_my_putchar( ',', &buf ); /* image separator */ - - buf_word(x,&buf); /* leftofs */ - buf_word(y,&buf); /* topofs */ - buf_word(THIS->xsize,&buf); /* width */ - buf_word(THIS->ysize,&buf); /* height */ - - low_my_putchar((0x80*lm)|(bpp-1), &buf); - /* not interlaced (interlaced == 0x40) */ - /* local colormap ( == 0x80) */ - /* 8 bpp in map ( == 0x07) */ - - if (lm) - { - for (i=0; i<ct->numcol; i++) - { - low_my_putchar(ct->clut[i].r,&buf); - low_my_putchar(ct->clut[i].g,&buf); - low_my_putchar(ct->clut[i].b,&buf); - } - for (; i<colors; i++) - { - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - } - } - - low_my_putchar( bpp, &buf ); - - i=THIS->xsize*THIS->ysize; - rgb=THIS->img; - -CHRONO("begin pack"); - - THREADS_ALLOW(); - lzw_init(&lzw,bpp); - if (!fs) - while (i--) lzw_add(&lzw,colortable_rgb(ct,*(rgb++))); - else - { - rgbl_group *errb; - rgb_group corgb; - int w,*cres,j; - errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*THIS->xsize); - cres=(int*)xalloc(sizeof(int)*THIS->xsize); - for (i=0; i<THIS->xsize; i++) - errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; - - w=0; - i=THIS->ysize; - while (i--) - { - image_floyd_steinberg(rgb,THIS->xsize,errb,w=!w,cres,ct); - for (j=0; j<THIS->xsize; j++) - lzw_add(&lzw,cres[j]); - rgb+=THIS->xsize; - } - - free(errb); - free(cres); - } - - lzw_write_last(&lzw); - -CHRONO("end pack"); - - for (i=0; i<(int)lzw.outpos; i+=254) - { - int wr; - if (i+254>(int)lzw.outpos) wr=lzw.outpos-i; - else wr=254; - low_my_putchar( (unsigned char)wr, &buf ); /* bytes in chunk */ - low_my_binary_strcat( (char *) lzw.out+i, wr, &buf ); - } - low_my_putchar( 0, &buf ); /* terminate stream */ - - lzw_quit(&lzw); - - colortable_free(ct); - THREADS_DISALLOW(); - -CHRONO("done"); - - pop_n_elems(args); - push_string(low_free_buf(&buf)); -} - -void image_gif_add(INT32 args) -{ - img_gif_add(args,0,1); -} - -void image_gif_add_fs(INT32 args) -{ - img_gif_add(args,1,1); -} - -void image_gif_add_nomap(INT32 args) -{ - img_gif_add(args,0,0); -} - -void image_gif_add_fs_nomap(INT32 args) -{ - img_gif_add(args,1,0); -} - diff --git a/src/modules/mysql/.cvsignore b/src/modules/mysql/.cvsignore deleted file mode 100644 index 323c193f0fa8587cc986797a6352e9c54067ff58..0000000000000000000000000000000000000000 --- a/src/modules/mysql/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.pure -Makefile -config.h.in -config.log -config.status -configure -dependencies -linker_options -stamp-h diff --git a/src/modules/mysql/.gitignore b/src/modules/mysql/.gitignore deleted file mode 100644 index 5a77561f9be70aacc6af6ea6fa9c40ea15a85a9b..0000000000000000000000000000000000000000 --- a/src/modules/mysql/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.pure -/Makefile -/config.h.in -/config.log -/config.status -/configure -/dependencies -/linker_options -/stamp-h diff --git a/src/modules/mysql/Makefile.in b/src/modules/mysql/Makefile.in deleted file mode 100644 index ee236764a8d0eecd00bfa1928a0cc69cd362082e..0000000000000000000000000000000000000000 --- a/src/modules/mysql/Makefile.in +++ /dev/null @@ -1,12 +0,0 @@ -# -# $Id: Makefile.in,v 1.3 1997/02/07 00:43:32 hubbe Exp $ -# - -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -MODULE_CPPFLAGS=@DEFS@ @CPPFLAGS@ -OBJS=mysql.o result.o -MODULE_LDFLAGS=@LDFLAGS@ @MYSQL_LIBS@ - -@dynamic_module_makefile@ -@dependencies@ \ No newline at end of file diff --git a/src/modules/mysql/acconfig.h b/src/modules/mysql/acconfig.h deleted file mode 100644 index b87be83028a0fe4c08b2218547b4093975472c01..0000000000000000000000000000000000000000 --- a/src/modules/mysql/acconfig.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * $Id: acconfig.h,v 1.1 1997/01/31 23:53:38 grubba Exp $ - * - * Config-file for the Pike mySQL-module. - * - * Henrik Grubbstr�m 1997-01-30 - */ - -#ifndef PIKE_MYSQL_CONFIG_H -#define PIKE_MYSQL_CONFIG_H - -@TOP@ -@BOTTOM@ - -/* Define if you have mySQL */ -#undef HAVE_MYSQL - -#endif /* PIKE_MYSQL_CONFIG_H */ diff --git a/src/modules/mysql/configure.in b/src/modules/mysql/configure.in deleted file mode 100644 index 14acbf07f78ce57a357fe046890b71c6b64f4d16..0000000000000000000000000000000000000000 --- a/src/modules/mysql/configure.in +++ /dev/null @@ -1,192 +0,0 @@ -# -# $Id: configure.in,v 1.15 1997/02/07 00:43:33 hubbe Exp $ -# -# Configure script for the mysql-module -# -# Henrik Grubbstr�m -# - -# -# NOTE: -# Prior to 3.20.0 After 3.20.0 -# -------------------------------------------------------------- -# /usr/local/mysql/mach-lib-threads /usr/local/lib/mysql -# /usr/local/mysql/include /usr/local/include/mysql -# libmysql.a libmysqllib.a -# libstrings.a libmystrings.a -# - - -AC_INIT(mysql.c) -AC_CONFIG_HEADER(config.h) - -sinclude(../module_configure.in) - -OLD_LIBS=$LIBS -OLD_LDFLAGS=$LDFLAGS -OLD_CPPFLAGS=$CPPFLAGS -MYSQL_LIBS="" - -AC_ARG_WITH(mysql, [ --without-mysql no support for the Mysql database],[],[with_mysql=yes]) - -if test x$with_mysql = xyes; then - - AC_MSG_CHECKING(Checking for Mysql lib-directory) - - AC_CACHE_VAL(pike_cv_mysql_lib_dir, [ - for pike_cv_mysql_lib_dir in /usr/local/lib/mysql /usr/local/mysql/lib/mysql /usr/gnu/lib/mysql /usr/lib/mysql /lib/mysql /usr/local/mysql/lib /usr/local/mysql/mach-lib-thread no; do - if test -d $pike_cv_mysql_lib_dir/.; then - break - else - : - fi - done - ]) - - AC_MSG_RESULT($pike_cv_mysql_lib_dir) - - if test x$pike_cv_mysql_lib_dir = xno; then :; else - echo Adding $pike_cv_mysql_lib_dir to the library search path. - LDFLAGS="-L$pike_cv_mysql_lib_dir ${LDFLAGS}" - fi - - AC_MSG_CHECKING(Checking for Mysql include-directory) - - AC_CACHE_VAL(pike_cv_mysql_include_dir, [ - for pike_cv_mysql_include_dir in /usr/local/include/mysql /usr/local/mysql/include/mysql /usr/gnu/include/mysql /usr/include/mysql /include/mysql /usr/local/mysql/include no; do - if test -d $pike_cv_mysql_include_dir/.; then - break - else - : - fi - done - ]) - - AC_MSG_RESULT($pike_cv_mysql_include_dir) - - if test x$pike_cv_mysql_include_dir = xno; then :; else - echo Adding $pike_cv_mysql_include_dir to the include search path. - CPPFLAGS="-I$pike_cv_mysql_include_dir ${CPPFLAGS}" - fi - - # Header file - - AC_CHECK_HEADERS(mysql.h mysql/mysql.h) - - # Mysql libs - - pike_cv_mysql="no" - - AC_CHECK_LIB(mystrings, bchange, [ - LIBS="-lmystrings $LIBS" - MYSQL_LIBS="-lmystrings ${MYSQL_LIBS}" - pike_cv_mysql="post3.20" - ], [ - AC_CHECK_LIB(strings, bchange, [ - LIBS="-lstrings $LIBS" - MYSQL_LIBS="-lstrings ${MYSQL_LIBS}" - pike_cv_mysql="pre3.20" - ], []) - ]) - - AC_MSG_CHECKING(Mysql version) - - AC_MSG_RESULT($pike_cv_mysql) - - if test x$pike_cv_mysql = xno; then - # Restore variables, so we don't link with unnessesary libs - - LIBS=$OLD_LIBS - CPPFLAGS=$OLD_CPPFLAGS - LDFLAGS=$OLD_LDFLAGS - MYSQL_LIBS="" - else - - # System libs which might be needed - - if echo $LIBS|grep -- -lsocket >&5 2>&5; then - : - else - AC_CHECK_LIB(socket, socket, [ - LIBS="-lsocket $LIBS" - MYSQL_LIBS="-lsocket ${MYSQL_LIBS}" - ], []) - fi - if echo $LIBS|grep -- -lnsl >&5 2>&5; then - : - else - AC_CHECK_LIB(nsl, gethostbyname, [ - LIBS="-lnsl $LIBS" - MYSQL_LIBS="-lnsl ${MYSQL_LIBS}" - ], []) - fi - if echo $LIBS|grep -- -lm >&5 2>&5; then - : - else - AC_CHECK_LIB(m, floor, [ - LIBS="-lm $LIBS" - MYSQL_LIBS="-lm ${MYSQL_LIBS}" - ], []) - fi - - # Pthreads is still needed in 3.20.0. - AC_CHECK_FUNC(pthread_self, [], [ - AC_CHECK_LIB(pthread, pthread_self, [ - LIBS="-lpthread $LIBS" - echo Warning added -lpthread to \$LIBS\! - ], [ - AC_CHECK_LIB(pthreads, pthread_self, [ - LIBS="-lpthreads $LIBS" - echo Warning added -lpthreads to \$LIBS\! - ], []) - ]) - ]) - - AC_CHECK_LIB(dbug, _db_doprnt_, [ - LIBS="-ldbug $LIBS" - MYSQL_LIBS="-ldbug ${MYSQL_LIBS}" - ], []) - - AC_CHECK_LIB(mysys, my_init, [ - LIBS="-lmysys $LIBS" - MYSQL_LIBS="-lmysys ${MYSQL_LIBS}" - ], []) - - # Try a couple of mysqlclient libs - # in order of age, newest first. - - AC_CHECK_LIB(mysqlclient, mysql_connect, [ - LIBS="-lmysqlclient $LIBS" - MYSQL_LIBS="-lmysqlclient ${MYSQL_LIBS}" - ], [ - AC_CHECK_LIB(mysqllib, mysql_connect, [ - LIBS="-lmysqllib $LIBS" - MYSQL_LIBS="-lmysqllib ${MYSQL_LIBS}" - ], [ - AC_CHECK_LIB(mysql, mysql_connect, [ - LIBS="-lmysql $LIBS" - MYSQL_LIBS="-lmysql ${MYSQL_LIBS}" - ], [ pike_cv_mysql="no" ]) - ]) - ]) - - if test x$pike_cv_mysql = xno; then - # Restore variables, so we don't link with unnessesary libs - - LIBS=$OLD_LIBS - CPPFLAGS=$OLD_CPPFLAGS - LDFLAGS=$OLD_LDFLAGS - MYSQL_LIBS="" - else - AC_DEFINE(HAVE_MYSQL) - - AC_CHECK_FUNCS(mysql_real_query mysql_fetch_lengths) - fi - fi -else - : -fi - -AC_SUBST(MYSQL_LIBS) - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) diff --git a/src/modules/mysql/mysql.c b/src/modules/mysql/mysql.c deleted file mode 100644 index 34285d11c09cdb2ee593683d1c05a7e2f0f5e3f5..0000000000000000000000000000000000000000 --- a/src/modules/mysql/mysql.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * $Id: mysql.c,v 1.18 1997/02/08 02:59:08 grubba Exp $ - * - * SQL database functionality for Pike - * - * Henrik Grubbstr�m 1996-12-21 - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#ifdef HAVE_MYSQL - -/* - * Includes - */ - -/* From the mysql-dist */ -/* Workaround for versions prior to 3.20.0 not beeing protected for - * multiple inclusion. - */ -#ifndef _mysql_h -#ifdef HAVE_MYSQL_H -#include <mysql.h> -#else -#ifdef HAVE_MYSQL_MYSQL_H -#include <mysql/mysql.h> -#else -#error Need mysql.h header-file -#endif /* HAVE_MYSQL_MYSQL_H */ -#endif /* HAVE_MYSQL_H */ -#ifndef _mysql_h -#define _mysql_h -#endif -#endif - -/* dynamic_buffer.h contains a conflicting typedef for string - * we don't use any dynamic buffers, so we have this work-around - */ -#define DYNAMIC_BUFFER_H -typedef struct dynamic_buffer_s dynamic_buffer; - -#endif /* HAVE_MYSQL */ - -/* From the Pike-dist */ -#include <global.h> -#include <svalue.h> -#include <object.h> -#include <stralloc.h> -#include <interpret.h> -#include <port.h> -#include <error.h> -#include <las.h> -#include <threads.h> - -/* System includes */ -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif - -#ifdef HAVE_MYSQL - -/* Local includes */ -#include "precompiled_mysql.h" - -/* - * Globals - */ - -RCSID("$Id: mysql.c,v 1.18 1997/02/08 02:59:08 grubba Exp $"); - -struct program *mysql_program = NULL; - -/* - * Functions - */ - -/* - * State maintenance - */ - -static void init_mysql_struct(struct object *o) -{ - MEMSET(PIKE_MYSQL, 0, sizeof(struct precompiled_mysql)); -} - -static void exit_mysql_struct(struct object *o) -{ - MYSQL *socket = PIKE_MYSQL->socket; - MYSQL_RES *last_result = PIKE_MYSQL->last_result; - - PIKE_MYSQL->last_result = NULL; - PIKE_MYSQL->socket = NULL; - - THREADS_ALLOW(); - - if (last_result) { - mysql_free_result(last_result); - } - if (socket) { - mysql_close(socket); - } - - THREADS_DISALLOW(); -} - -/* - * Methods - */ - -/* void create(string|void host, string|void database, string|void user, string|void password) */ -static void f_create(INT32 args) -{ - MYSQL *mysql = &PIKE_MYSQL->mysql; - MYSQL *socket; - char *host = NULL; - char *database = NULL; - char *user = NULL; - char *password = NULL; - - if (args >= 1) { - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql()\n"); - } - if (sp[-args].u.string->len) { - host = sp[-args].u.string->str; - } - - if (args >= 2) { - if (sp[1-args].type != T_STRING) { - error("Bad argument 2 to mysql()\n"); - } - if (sp[1-args].u.string->len) { - database = sp[1-args].u.string->str; - } - - if (args >= 3) { - if (sp[2-args].type != T_STRING) { - error("Bad argument 3 to mysql()\n"); - } - if (sp[2-args].u.string->len) { - user = sp[2-args].u.string->str; - } - - if (args >= 4) { - if (sp[3-args].type != T_STRING) { - error("Bad argument 4 to mysql()\n"); - } - if (sp[3-args].u.string->len) { - password = sp[3-args].u.string->str; - } - } - } - } - } - - THREADS_ALLOW(); - - socket = mysql_connect(mysql, host, user, password); - - THREADS_DISALLOW(); - - if (!(PIKE_MYSQL->socket = socket)) { - error("mysql(): Couldn't connect to SQL-server\n"); - } - if (database) { - int tmp; - - THREADS_ALLOW(); - - tmp = mysql_select_db(socket, database); - - THREADS_DISALLOW(); - - if (tmp < 0) { - mysql_close(PIKE_MYSQL->socket); - PIKE_MYSQL->socket = NULL; - error("mysql(): Couldn't select database \"%s\"\n", database); - } - } - - pop_n_elems(args); -} - -/* int affected_rows() */ -static void f_affected_rows(INT32 args) -{ - pop_n_elems(args); - push_int(mysql_affected_rows(PIKE_MYSQL->socket)); -} - -/* int insert_id() */ -static void f_insert_id(INT32 args) -{ - pop_n_elems(args); - push_int(mysql_insert_id(PIKE_MYSQL->socket)); -} - -/* int|string error() */ -static void f_error(INT32 args) -{ - char *error_msg = mysql_error(PIKE_MYSQL->socket); - - pop_n_elems(args); - if (error_msg && *error_msg) { - push_text(error_msg); - } else { - push_int(0); - } -} - -/* void select_db(string database) */ -static void f_select_db(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - char *database; - int tmp; - - if (!args) { - error("Too few arguments to mysql->select_db()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->select_db()\n"); - } - - database = sp[-args].u.string->str; - - THREADS_ALLOW(); - - tmp = mysql_select_db(socket, database); - - THREADS_DISALLOW(); - - if (tmp < 0) { - error("mysql->select_db(): Couldn't select database \"%s\"\n", - sp[-args].u.string->str); - } - - pop_n_elems(args); -} - -/* object(mysql_result) big_query(string q) */ -static void f_big_query(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - MYSQL_RES *result; - char *query; - int qlen; - int tmp; - - if (!args) { - error("Too few arguments to mysql->big_query()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->big_query()\n"); - } - - query = sp[-args].u.string->str; - qlen = sp[-args].u.string->len; - - THREADS_ALLOW(); - - /* NOTE the temporary tmp is needed since THREADS_ALLOW() opens a scope, - * which is closed at THREADS_DISALLOW() - */ - -#ifdef HAVE_MYSQL_REAL_QUERY - tmp = mysql_real_query(socket, query, qlen); -#else - tmp = mysql_query(socket, query); -#endif /* HAVE_MYSQL_REAL_QUERY */ - - THREADS_DISALLOW(); - - if (tmp < 0) { - error("mysql->big_query(): Query \"%s\" failed\n", - sp[-args].u.string->str); - } - - THREADS_ALLOW(); - - /* The same thing applies here */ - - result = mysql_store_result(socket); - - THREADS_DISALLOW(); - - pop_n_elems(args); - - if (!(PIKE_MYSQL->last_result = result)) { - if (mysql_num_fields(socket) && mysql_error(socket)[0]) { - error("mysql->big_query(): Couldn't create result for query\n"); - } - /* query was INSERT or similar - return 0 */ - - push_int(0); - } else { - /* Return the result-object */ - - push_object(fp->current_object); - fp->current_object->refs++; - - push_object(clone(mysql_result_program, 1)); - } -} - -/* void create_db(string database) */ -static void f_create_db(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - char *database; - int tmp; - - if (!args) { - error("Too few arguments to mysql->create_db()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->create_db()\n"); - } - if (sp[-args].u.string->len > 127) { - error("Database name \"%s\" is too long (max 127 characters)\n", - sp[-args].u.string->str); - } - database = sp[-args].u.string->str; - - THREADS_ALLOW(); - - tmp = mysql_create_db(socket, database); - - THREADS_DISALLOW(); - - if (tmp < 0) { - error("mysql->create_db(): Creation of database \"%s\" failed\n", - sp[-args].u.string->str); - } - - pop_n_elems(args); -} - -/* void drop_db(string database) */ -static void f_drop_db(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - char *database; - int tmp; - - if (!args) { - error("Too few arguments to mysql->drop_db()\n"); - } - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->drop_db()\n"); - } - if (sp[-args].u.string->len > 127) { - error("Database name \"%s\" is too long (max 127 characters)\n", - sp[-args].u.string->str); - } - database = sp[-args].u.string->str; - - THREADS_ALLOW(); - - tmp = mysql_drop_db(socket, database); - - THREADS_DISALLOW(); - - if (tmp < 0) { - error("mysql->drop_db(): Drop of database \"%s\" failed\n", - sp[-args].u.string->str); - } - - pop_n_elems(args); -} - -/* void shutdown() */ -static void f_shutdown(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - int tmp; - - THREADS_ALLOW(); - - tmp = mysql_shutdown(socket); - - THREADS_DISALLOW(); - - if (tmp < 0) { - error("mysql->shutdown(): Shutdown failed\n"); - } - - pop_n_elems(args); -} - -/* void reload() */ -static void f_reload(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - int tmp; - - THREADS_ALLOW(); - - tmp = mysql_reload(socket); - - THREADS_DISALLOW(); - - if (tmp < 0) { - error("mysql->reload(): Reload failed\n"); - } - - pop_n_elems(args); -} - -/* string statistics() */ -static void f_statistics(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - char *stats; - - pop_n_elems(args); - - THREADS_ALLOW(); - - stats = mysql_stat(socket); - - THREADS_DISALLOW(); - - push_text(stats); -} - -/* string server_info() */ -static void f_server_info(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - char *info; - - pop_n_elems(args); - - push_text("mysql/"); - - THREADS_ALLOW(); - - info = mysql_get_server_info(socket); - - THREADS_DISALLOW(); - - push_text(info); - f_add(2); -} - -/* string host_info() */ -static void f_host_info(INT32 args) -{ - pop_n_elems(args); - - push_text(mysql_get_host_info(PIKE_MYSQL->socket)); -} - -/* int protocol_info() */ -static void f_protocol_info(INT32 args) -{ - pop_n_elems(args); - - push_int(mysql_get_proto_info(PIKE_MYSQL->socket)); -} - -/* object(mysql_res) list_dbs(void|string wild) */ -static void f_list_dbs(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - MYSQL_RES *result; - char *wild = NULL; - - if (args) { - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->list_dbs()\n"); - } - if (sp[-args].u.string->len > 80) { - error("Wildcard \"%s\" is too long (max 80 characters)\n", - sp[-args].u.string->str); - } - wild = sp[-args].u.string->str; - } - - THREADS_ALLOW(); - - result = mysql_list_dbs(socket, wild); - - THREADS_DISALLOW(); - - if (!(PIKE_MYSQL->last_result = result)) { - error("mysql->list_dbs(): Cannot list databases: %s\n", - mysql_error(PIKE_MYSQL->socket)); - } - - pop_n_elems(args); - - push_object(fp->current_object); - fp->current_object->refs++; - - push_object(clone(mysql_result_program, 1)); -} - -/* object(mysql_res) list_tables(void|string wild) */ -static void f_list_tables(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - MYSQL_RES *result; - char *wild = NULL; - - if (args) { - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->list_tables()\n"); - } - if (sp[-args].u.string->len > 80) { - error("Wildcard \"%s\" is too long (max 80 characters)\n", - sp[-args].u.string->str); - } - wild = sp[-args].u.string->str; - } - - THREADS_ALLOW(); - - result = mysql_list_tables(socket, wild); - - THREADS_DISALLOW(); - - if (!(PIKE_MYSQL->last_result = result)) { - error("mysql->list_tables(): Cannot list databases: %s\n", - mysql_error(PIKE_MYSQL->socket)); - } - - pop_n_elems(args); - - push_object(fp->current_object); - fp->current_object->refs++; - - push_object(clone(mysql_result_program, 1)); -} - -/* array(int|mapping(string:mixed)) list_fields(string table, void|string wild) */ -static void f_list_fields(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - MYSQL_RES *result; - MYSQL_FIELD *field; - int i = 0; - char *table; - char *wild = NULL; - - if (!args) { - error("Too few arguments to mysql->list_fields()\n"); - } - - if (sp[-args].type != T_STRING) { - error("Bad argument 1 to mysql->list_fields()\n"); - } - if (sp[-args].u.string->len > 125) { - error("Table name \"%s\" is too long (max 125 characters)\n", - sp[-args].u.string->str); - } - table = sp[-args].u.string->str; - if (args > 1) { - if (sp[-args+1].type != T_STRING) { - error("Bad argument 2 to mysql->list_fields()\n"); - } - if (sp[-args+1].u.string->len + sp[-args].u.string->len > 125) { - error("Wildcard \"%s\" + table name \"%s\" is too long " - "(max 125 characters)\n", - sp[-args+1].u.string->str, sp[-args].u.string->str); - } - wild = sp[-args+1].u.string->str; - } - - THREADS_ALLOW(); - - result = mysql_list_fields(socket, table, wild); - - THREADS_DISALLOW(); - - if (!result) { - error("mysql->list_fields(): Cannot list databases: %s\n", - mysql_error(PIKE_MYSQL->socket)); - } - - pop_n_elems(args); - - while ((field = mysql_fetch_field(result))) { - mysqlmod_parse_field(field, 1); - i++; - } - f_aggregate(i); -} - -/* object(mysql_res) list_processes() */ -static void f_list_processes(INT32 args) -{ - MYSQL *socket = PIKE_MYSQL->socket; - MYSQL_RES *result; - - pop_n_elems(args); - - THREADS_ALLOW(); - - result = mysql_list_processes(socket); - - THREADS_DISALLOW(); - - if (!(PIKE_MYSQL->last_result = result)) { - error("mysql->list_processes(): Cannot list databases: %s\n", - mysql_error(PIKE_MYSQL->socket)); - } - - push_object(fp->current_object); - fp->current_object->refs++; - - push_object(clone(mysql_result_program, 1)); -} - -/* - * Support for binary data in tables - */ -static void f_binary_data(INT32 args) -{ - pop_n_elems(args); -#ifdef HAVE_MYSQL_FETCH_LENGTHS - push_int(1); -#else - push_int(0); -#endif /* HAVE_MYSQL_FETCH_LENGTHS */ -} - -#endif /* HAVE_MYSQL */ - -/* - * Module linkage - */ - - -void pike_module_init(void) -{ -#ifdef HAVE_MYSQL - /* - * start_new_program(); - * - * add_storage(); - * - * add_function(); - * add_function(); - * ... - * - * set_init_callback(); - * set_exit_callback(); - * - * program = end_c_program(); - * program->refs++; - * - */ - - start_new_program(); - add_storage(sizeof(struct precompiled_mysql)); - - add_function("error", f_error, "function(void:int|string)", OPT_EXTERNAL_DEPEND); - add_function("create", f_create, "function(string|void, string|void, string|void, string|void:void)", OPT_SIDE_EFFECT); - add_function("affected_rows", f_affected_rows, "function(void:int)", OPT_EXTERNAL_DEPEND); - add_function("insert_id", f_insert_id, "function(void:int)", OPT_EXTERNAL_DEPEND); - add_function("select_db", f_select_db, "function(string:void)", OPT_SIDE_EFFECT); - add_function("big_query", f_big_query, "function(string:int|object)", OPT_EXTERNAL_DEPEND); - add_function("create_db", f_create_db, "function(string:void)", OPT_SIDE_EFFECT); - add_function("drop_db", f_drop_db, "function(string:void)", OPT_SIDE_EFFECT); - add_function("shutdown", f_shutdown, "function(void:void)", OPT_SIDE_EFFECT); - add_function("reload", f_reload, "function(void:void)", OPT_SIDE_EFFECT); - add_function("statistics", f_statistics, "function(void:string)", OPT_EXTERNAL_DEPEND); - add_function("server_info", f_server_info, "function(void:string)", OPT_EXTERNAL_DEPEND); - add_function("host_info", f_host_info, "function(void:string)", OPT_EXTERNAL_DEPEND); - add_function("protocol_info", f_protocol_info, "function(void:int)", OPT_EXTERNAL_DEPEND); - add_function("list_dbs", f_list_dbs, "function(void|string:object)", OPT_EXTERNAL_DEPEND); - add_function("list_tables", f_list_tables, "function(void|string:object)", OPT_EXTERNAL_DEPEND); - add_function("list_fields", f_list_fields, "function(string, void|string:array(int|mapping(string:mixed)))", OPT_EXTERNAL_DEPEND); - add_function("list_processes", f_list_processes, "function(void|string:object)", OPT_EXTERNAL_DEPEND); - - add_function("binary_data", f_binary_data, "function(void:int)", OPT_TRY_OPTIMIZE); - - set_init_callback(init_mysql_struct); - set_exit_callback(exit_mysql_struct); - - mysql_program = end_program(); - add_program_constant("mysql", mysql_program, 0); - - init_mysql_res_programs(); -#endif /* HAVE_MYSQL */ -} - -void pike_module_exit(void) -{ -#ifdef HAVE_MYSQL - exit_mysql_res(); - - if (mysql_program) { - free_program(mysql_program); - mysql_program = NULL; - } -#endif /* HAVE_MYSQL */ -} - diff --git a/src/modules/mysql/precompiled_mysql.h b/src/modules/mysql/precompiled_mysql.h deleted file mode 100644 index 84c7b229624bb2238dc7ba1f9ef5cc431a274483..0000000000000000000000000000000000000000 --- a/src/modules/mysql/precompiled_mysql.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * $Id: precompiled_mysql.h,v 1.3 1997/02/01 14:44:41 grubba Exp $ - * - * SQL database connectivity for Pike - * - * Henrik Grubbstr�m 1996-12-21 - */ - -#ifndef PRECOMPILED_MYSQL_H -#define PRECOMPILED_MYSQL_H - -/* - * Includes - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -/* From the mysql-dist */ -/* Workaround for versions prior to 3.20.0 not beeing protected for - * multiple inclusion. - */ -#ifndef _mysql_h -#ifdef HAVE_MYSQL_H -#include <mysql.h> -#else -#ifdef HAVE_MYSQL_MYSQL_H -#include <mysql/mysql.h> -#else -#error Need mysql.h header-file -#endif /* HAVE_MYSQL_MYSQL_H */ -#endif /* HAVE_MYSQL_H */ -#ifndef _mysql_h -#define _mysql_h -#endif -#endif - -/* From the Pike-dist */ - -/* - * Structures - */ - -struct precompiled_mysql { - MYSQL mysql, *socket; - MYSQL_RES *last_result; /* UGLY way to pass arguments to create() */ -}; - -struct precompiled_mysql_result { - MYSQL_RES *result; -}; - -/* - * Defines - */ - -#define PIKE_MYSQL ((struct precompiled_mysql *)(fp->current_storage)) -#define PIKE_MYSQL_RES ((struct precompiled_mysql_result *)(fp->current_storage)) - -/* - * Globals - */ - -extern struct program *mysql_program; -extern struct program *mysql_result_program; - -/* - * Prototypes - */ - -/* From result.c */ - -void init_mysql_res_efuns(void); -void init_mysql_res_programs(void); -void exit_mysql_res(void); - -#endif /* PRECOMPILED_MYSQL_H */ diff --git a/src/modules/mysql/result.c b/src/modules/mysql/result.c deleted file mode 100644 index 83a59ccbb18b42fc33ada814a8fec9fad4ade05b..0000000000000000000000000000000000000000 --- a/src/modules/mysql/result.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * $Id: result.c,v 1.16 1997/02/07 01:42:21 hubbe Exp $ - * - * mysql query result - * - * Henrik Grubbstr�m 1996-12-21 - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#ifdef HAVE_MYSQL -/* - * Includes - */ - -/* From the mysql-dist */ -/* Workaround for versions prior to 3.20.0 not beeing protected for - * multiple inclusion. - */ -#ifndef _mysql_h -#ifdef HAVE_MYSQL_H -#include <mysql.h> -#else -#ifdef HAVE_MYSQL_MYSQL_H -#include <mysql/mysql.h> -#else -#error Need mysql.h header-file -#endif /* HAVE_MYSQL_MYSQL_H */ -#endif /* HAVE_MYSQL_H */ -#ifndef _mysql_h -#define _mysql_h -#endif -#endif - -/* dynamic_buffer.h contains a conflicting typedef for string - * we don't use any dynamic buffers, so we have this work-around - */ -#define DYNAMIC_BUFFER_H -typedef struct dynamic_buffer_s dynamic_buffer; - -/* From the Pike-dist */ -#include <global.h> -#include <svalue.h> -#include <mapping.h> -#include <object.h> -#include <program.h> -#include <stralloc.h> -#include <interpret.h> -#include <error.h> -#include <builtin_functions.h> -#include <las.h> -#include <threads.h> - -/* Local includes */ -#include "precompiled_mysql.h" - -/* System includes */ -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif - -/* Define this to get support for field->default. NOT SUPPORTED */ -#undef SUPPORT_DEFAULT - -/* Define this to get field_seek() and fetch_field() */ -/* #define SUPPORT_FIELD_SEEK */ - -/* - * Globals - */ - -RCSID("$Id: result.c,v 1.16 1997/02/07 01:42:21 hubbe Exp $"); - -struct program *mysql_result_program = NULL; - -/* - * Functions - */ - -/* - * State maintenance - */ - -static void init_res_struct(struct object *o) -{ - memset(PIKE_MYSQL_RES, 0, sizeof(struct precompiled_mysql_result)); -} - -static void exit_res_struct(struct object *o) -{ - if (PIKE_MYSQL_RES->result) { - mysql_free_result(PIKE_MYSQL_RES->result); - PIKE_MYSQL_RES->result = NULL; - } -} - -/* - * Help functions - */ - -void mysqlmod_parse_field(MYSQL_FIELD *field, int support_default) -{ - if (field) { - int nbits = 0; - push_text("name"); push_text(field->name); - push_text("table"); push_text(field->table); - if (support_default) { - push_text("default"); - if (field->def) { - push_text(field->def); - } else { - push_int(0); - } - } - push_text("type"); - switch(field->type) { - case FIELD_TYPE_DECIMAL: - push_text("decimal"); - break; - case FIELD_TYPE_CHAR: - push_text("char"); - break; - case FIELD_TYPE_SHORT: - push_text("short"); - break; - case FIELD_TYPE_LONG: - push_text("long"); - break; - case FIELD_TYPE_FLOAT: - push_text("float"); - break; - case FIELD_TYPE_DOUBLE: - push_text("double"); - break; - case FIELD_TYPE_NULL: - push_text("null"); - break; - case FIELD_TYPE_TIME: - push_text("time"); - break; - case FIELD_TYPE_LONGLONG: - push_text("longlong"); - break; - case FIELD_TYPE_INT24: - push_text("int24"); - break; - case FIELD_TYPE_TINY_BLOB: - push_text("tiny blob"); - break; - case FIELD_TYPE_MEDIUM_BLOB: - push_text("medium blob"); - break; - case FIELD_TYPE_LONG_BLOB: - push_text("long blob"); - break; - case FIELD_TYPE_BLOB: - push_text("blob"); - break; - case FIELD_TYPE_VAR_STRING: - push_text("var string"); - break; - case FIELD_TYPE_STRING: - push_text("string"); - break; - default: - push_text("unknown"); - break; - } - push_text("length"); push_int(field->length); - push_text("max_length"); push_int(field->max_length); - - push_text("flags"); - if (IS_PRI_KEY(field->flags)) { - nbits++; - push_text("primary_key"); - } - if (IS_NOT_NULL(field->flags)) { - nbits++; - push_text("not_null"); - } - if (IS_BLOB(field->flags)) { - nbits++; - push_text("blob"); - } - f_aggregate_multiset(nbits); - - push_text("decimals"); push_int(field->decimals); - - if (support_default) { - f_aggregate_mapping(8*2); - } else { - f_aggregate_mapping(7*2); - } - } else { - /* - * Should this be an error? - */ - push_int(0); - } -} - -/* - * Methods - */ - -/* void create(object(mysql)) */ -static void f_create(INT32 args) -{ - if (!args) { - error("Too few arguments to mysql_result()\n"); - } - if ((sp[-args].type != T_OBJECT) || - (sp[-args].u.object->prog != mysql_program)) { - error("Bad argument 1 to mysql_result()\n"); - } - - PIKE_MYSQL_RES->result = ((struct precompiled_mysql *)sp[-args].u.object->storage)->last_result; - ((struct precompiled_mysql *)sp[-args].u.object->storage)->last_result = NULL; - - pop_n_elems(args); - - if (!PIKE_MYSQL_RES->result) { - error("mysql_result(): No result to clone\n"); - } -} - -/* int num_rows() */ -static void f_num_rows(INT32 args) -{ - pop_n_elems(args); - push_int(mysql_num_rows(PIKE_MYSQL_RES->result)); -} - -/* int num_fields() */ -static void f_num_fields(INT32 args) -{ - pop_n_elems(args); - push_int(mysql_num_fields(PIKE_MYSQL_RES->result)); -} - -#ifdef SUPPORT_FIELD_SEEK - -/* void field_seek(int fieldno) */ -static void f_field_seek(INT32 args) -{ - if (!args) { - error("Too few arguments to mysql->field_seek()\n"); - } - if (sp[-args].type != T_INT) { - error("Bad argument 1 to mysql->field_seek()\n"); - } - mysql_field_seek(PIKE_MYSQL_RES->result, sp[-args].u.integer); - pop_n_elems(args); -} - -#endif /* SUPPORT_FIELD_SEEK */ - -/* int eof() */ -static void f_eof(INT32 args) -{ - pop_n_elems(args); - push_int(mysql_eof(PIKE_MYSQL_RES->result)); -} - -#ifdef SUPPORT_FIELD_SEEK - -/* int|mapping(string:mixed) fetch_field() */ -static void f_fetch_field(INT32 args) -{ - MYSQL_FIELD *field; - MYSQL_RES *res = PIKE_MYSQL_RES->result; - - pop_n_elems(args); - - THREADS_ALLOW(); - - field = mysql_fetch_field(res); - - THREADS_DISALLOW(); - - mysqlmod_parse_field(field, 0); -} - -#endif /* SUPPORT_FIELD_SEEK */ - -/* array(int|mapping(string:mixed)) fetch_fields() */ -static void f_fetch_fields(INT32 args) -{ - MYSQL_FIELD *field; - int i = 0; - - pop_n_elems(args); - - while ((field = mysql_fetch_field(PIKE_MYSQL_RES->result))) { - mysqlmod_parse_field(field, 0); - i++; - } - f_aggregate(i); - - mysql_field_seek(PIKE_MYSQL_RES->result, 0); -} - -/* void seek(int row) */ -static void f_seek(INT32 args) -{ - if (!args) { - error("Too few arguments to mysql_result->seek()\n"); - } - if (sp[-args].type != T_INT) { - error("Bad argument 1 to mysql_result->seek()\n"); - } - if (sp[-args].u.integer < 0) { - error("Negative argument 1 to mysql_result->seek()\n"); - } - mysql_data_seek(PIKE_MYSQL_RES->result, sp[-args].u.integer); - - pop_n_elems(args); -} - -/* int|array(string|float|int) fetch_row() */ -static void f_fetch_row(INT32 args) -{ - int num_fields = mysql_num_fields(PIKE_MYSQL_RES->result); - MYSQL_ROW row = mysql_fetch_row(PIKE_MYSQL_RES->result); -#ifdef HAVE_MYSQL_FETCH_LENGTHS - int *row_lengths = mysql_fetch_lengths(PIKE_MYSQL_RES->result); -#endif /* HAVE_MYSQL_FETCH_LENGTHS */ - - pop_n_elems(args); - - mysql_field_seek(PIKE_MYSQL_RES->result, 0); - - if ((num_fields > 0) && row) { - int i; - - for (i=0; i < num_fields; i++) { - if (row[i]) { - MYSQL_FIELD *field; - - if (field = mysql_fetch_field(PIKE_MYSQL_RES->result)) { - switch (field->type) { - /* Integer types */ - case FIELD_TYPE_SHORT: - case FIELD_TYPE_LONG: - case FIELD_TYPE_INT24: -#if 0 - /* This one will not always fit in an INT32 */ - case FIELD_TYPE_LONGLONG: -#endif /* 0 */ - push_int(atoi(row[i])); - break; - /* Floating point types */ - case FIELD_TYPE_DECIMAL: /* Is this a float or an int? */ - case FIELD_TYPE_FLOAT: - case FIELD_TYPE_DOUBLE: - push_float(atof(row[i])); - break; - default: -#ifdef HAVE_MYSQL_FETCH_LENGTHS - push_string(make_shared_binary_string(row[i], row_lengths[i])); -#else - push_text(row[i]); -#endif /* HAVE_MYSQL_FETCH_LENGTHS */ - break; - } - } else { - /* Probably doesn't happen, but... */ -#ifdef HAVE_MYSQL_FETCH_LENGTHS - push_string(make_shared_binary_string(row[i], row_lengths[i])); -#else - push_text(row[i]); -#endif /* HAVE_MYSQL_FETCH_LENGTHS */ - } - } else { - /* NULL? */ - push_int(0); - } - } - f_aggregate(num_fields); - } else { - /* No rows left in result */ - push_int(0); - } - - mysql_field_seek(PIKE_MYSQL_RES->result, 0); -} - -/* - * Module linkage - */ - - -void init_mysql_res_programs(void) -{ - /* - * start_new_program(); - * - * add_storage(); - * - * add_function(); - * add_function(); - * ... - * - * set_init_callback(); - * set_exit_callback(); - * - * program = end_c_program(); - * program->refs++; - * - */ - - start_new_program(); - add_storage(sizeof(struct precompiled_mysql_result)); - - add_function("create", f_create, "function(object:void)", OPT_SIDE_EFFECT); - add_function("num_rows", f_num_rows, "function(void:int)", OPT_EXTERNAL_DEPEND); - add_function("num_fields", f_num_fields, "function(void:int)", OPT_EXTERNAL_DEPEND); -#ifdef SUPPORT_FIELD_SEEK - add_function("field_seek", f_field_seek, "function(int:void)", OPT_SIDE_EFFECT); -#endif /* SUPPORT_FIELD_SEEK */ - add_function("eof", f_eof, "function(void:int)", OPT_EXTERNAL_DEPEND); -#ifdef SUPPORT_FIELD_SEEK - add_function("fetch_field", f_fetch_field, "function(void:int|mapping(string:mixed))", OPT_EXTERNAL_DEPEND); -#endif /* SUPPORT_FIELD_SEEK */ - add_function("fetch_fields", f_fetch_fields, "function(void:array(int|mapping(string:mixed)))", OPT_EXTERNAL_DEPEND); - add_function("seek", f_seek, "function(int:void)", OPT_SIDE_EFFECT); - add_function("fetch_row", f_fetch_row, "function(void:int|array(string|int|float))", OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT); - - set_init_callback(init_res_struct); - set_exit_callback(exit_res_struct); - - mysql_result_program = end_program(); - add_program_constant("mysql_result",mysql_result_program, 0); -} - -void exit_mysql_res(void) -{ - if (mysql_result_program) { - free_program(mysql_result_program); - mysql_result_program = NULL; - } -} - -#endif /* HAVE_MYSQL */ diff --git a/src/modules/pipe/.cvsignore b/src/modules/pipe/.cvsignore deleted file mode 100644 index 47c84b07459ebcb78e36ee8c2e1a30cee7f440ff..0000000000000000000000000000000000000000 --- a/src/modules/pipe/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.pure -Makefile -config.h -config.log -config.status -configure -dependencies -stamp-h diff --git a/src/modules/pipe/.gitignore b/src/modules/pipe/.gitignore deleted file mode 100644 index b27587e1b501d0baa775ec479e1a69e7da31aef0..0000000000000000000000000000000000000000 --- a/src/modules/pipe/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/.pure -/Makefile -/config.h -/config.log -/config.status -/configure -/dependencies -/stamp-h diff --git a/src/modules/pipe/Makefile.in b/src/modules/pipe/Makefile.in deleted file mode 100644 index 2f114663c728caf7b6e11bb301fe8a705f77db0e..0000000000000000000000000000000000000000 --- a/src/modules/pipe/Makefile.in +++ /dev/null @@ -1,6 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -OBJS=pipe.o - -@dynamic_module_makefile@ -@dependencies@ diff --git a/src/modules/pipe/config.h.in b/src/modules/pipe/config.h.in deleted file mode 100644 index 508a935ac246d6d24a59b2a5c7117feb8fc9ef50..0000000000000000000000000000000000000000 --- a/src/modules/pipe/config.h.in +++ /dev/null @@ -1,13 +0,0 @@ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define if you have the mmap function. */ -#undef HAVE_MMAP - -/* Define if you have the munmap function. */ -#undef HAVE_MUNMAP - -/* Define if you have the <linux/mman.h> header file. */ -#undef HAVE_LINUX_MMAN_H - -/* Define if you have the <sys/mman.h> header file. */ -#undef HAVE_SYS_MMAN_H diff --git a/src/modules/pipe/configure.in b/src/modules/pipe/configure.in deleted file mode 100644 index 84dd753063f827919780d8d80eb1b3967a264fdf..0000000000000000000000000000000000000000 --- a/src/modules/pipe/configure.in +++ /dev/null @@ -1,11 +0,0 @@ -AC_INIT(pipe.c) -AC_CONFIG_HEADER(config.h) - -sinclude(../module_configure.in) - -AC_HAVE_HEADERS(sys/mman.h linux/mman.h) -AC_HAVE_FUNCS(mmap munmap) - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/pipe/pipe.c b/src/modules/pipe/pipe.c deleted file mode 100644 index 347c9f2cd496449bf857d6b01936f9da4d8369bd..0000000000000000000000000000000000000000 --- a/src/modules/pipe/pipe.c +++ /dev/null @@ -1,1142 +0,0 @@ -#include <config.h> -#include "machine.h" - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#else -#ifdef HAVE_LINUX_MMAN_H -#include <linux/mman.h> -#else -#ifdef HAVE_MMAP -/* sys/mman.h is _probably_ there anyway. */ -#include <sys/mman.h> -#endif -#endif -#endif - -#include <fcntl.h> - -#include "global.h" -RCSID("$Id: pipe.c,v 1.10 1997/02/07 01:42:42 hubbe Exp $"); - -#include "stralloc.h" -#include "types.h" -#include "macros.h" -#include "object.h" -#include "constants.h" -#include "interpret.h" -#include "svalue.h" -#include "error.h" - -#ifndef S_ISREG -#ifdef S_IFREG -#define S_ISREG(mode) (((mode) & (S_IFMT)) == (S_IFREG)) -#else -#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) -#endif -#endif - -/* -#define PIPE_STRING_DEBUG -#define PIPE_MMAP_DEBUG -#define PIPE_FILE_DEBUG -#define BLOCKING_CLOSE -*/ - -#if 0 -#define INSISTANT_WRITE -#endif - -#ifndef MAP_FILE -# define MAP_FILE 0 -#endif - -#define READ_BUFFER_SIZE 32768 -#define MAX_BYTES_IN_BUFFER 65536 - -/* - * usage: - * single socket output - * or regular file output and (multiple, adding) socket output - * with no mmap input - * - * multiple socket output without regular file output illegal - */ - -static struct program *pipe_program, *output_program; - -#define THIS ((struct pipe *)(fp->current_storage)) -#define THISOBJ (fp->current_object) - -struct input -{ - enum { I_NONE,I_OBJ,I_STRING,I_MMAP } type; - union - { - struct object *obj; - struct pike_string *str; - char *mmap; - } u; - unsigned long len; /* current input: string or mmap len */ - int set_blocking_offset, set_nonblocking_offset; - struct input *next; -}; - -struct output -{ - struct object *obj; - int write_offset, set_blocking_offset, set_nonblocking_offset; - int fd; - - enum - { - O_RUN, /* waiting for callback */ - O_SLEEP /* sleeping; waiting for more data */ - } mode; - - unsigned long pos; /* position in buffer */ - struct object *next; - struct pipe *the_pipe; -}; - -struct buffer -{ - struct pike_string *s; - struct buffer *next; -}; - -struct pipe -{ - int living_outputs; /* number of output objects */ - - struct svalue done_callback; - struct svalue output_closed_callback; - struct svalue id; - - /* - * if fd is -1: use fd - * else firstinput's type is I_MMAP: use firstinput's mmap - * else use buffer - */ - - int fd; /* buffer fd or -1 */ - - unsigned long bytes_in_buffer; - unsigned long pos; - /* fd: size of buffer file */ - /* current position of first element (buffer or mmap) */ - struct buffer *firstbuffer,*lastbuffer; - short sleeping; /* sleeping; buffer is full */ - short done; - struct input *firstinput,*lastinput; - struct object *firstoutput; -}; - -static int offset_input_read_callback; -static int offset_input_close_callback; -static int offset_output_write_callback; -static int offset_output_close_callback; -static int mmapped, nobjects, nstrings, noutputs, ninputs, nbuffers, sbuffers; - -static char static_buffer[READ_BUFFER_SIZE]; - -void close_and_free_everything(struct object *o,struct pipe *); -static INLINE void output_finish(struct object *obj); -static INLINE void output_try_write_some(struct object *obj); - -/********** internal ********************************************************/ - -/* Push a callback to this object given the internal function number. - */ -static void push_callback(int no) -{ - sp->u.object=THISOBJ; - THISOBJ->refs++; - sp->subtype=no+fp->context.identifier_level; - sp->type=T_FUNCTION; - sp++; -} - -/* Allocate a new struct input, link it last in the linked list */ -static INLINE struct input *new_input(void) -{ - struct input *i; - ninputs++; - i=ALLOC_STRUCT(input); - i->type=I_NONE; - i->next=NULL; - if (THIS->lastinput) - THIS->lastinput->next=i; - else - THIS->firstinput=i; - THIS->lastinput=i; - return i; -} - -/* Free an input struct and all that it stands for */ -static INLINE void free_input(struct input *i) -{ - ninputs--; - switch (i->type) - { - case I_OBJ: - if (!i->u.obj) break; - if (i->u.obj->prog) - { -#ifdef BLOCKING_CLOSE - apply_low(i->u.obj,i->set_blocking_offset,0); - pop_stack(); -#endif - apply(i->u.obj,"close",0); - pop_stack(); - destruct(i->u.obj); - } - free_object(i->u.obj); - nobjects--; - i->u.obj=0; - break; - - case I_STRING: - free_string(i->u.str); - nstrings--; - break; - - case I_MMAP: -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) - munmap(i->u.mmap,i->len); - mmapped -= i->len; -#else - error("I_MMAP input when MMAP is diabled!"); -#endif - break; - } - free((char *)i); -} - -/* do the done_callback, then close and free everything */ -static INLINE void pipe_done(void) -{ - if (THIS->done_callback.type!=T_INT) - { - assign_svalue_no_free(sp++,&THIS->id); - apply_svalue(&(THIS->done_callback),1); - pop_stack(); - - if(!THISOBJ->prog) /* We will not free anything in this case. */ - return; - /* error("Pipe done callback destructed pipe.\n"); */ - } - close_and_free_everything(THISOBJ,THIS); -} - -static void finished_p(void) -{ - if(THIS->done) return; - - if(THIS->fd != -1) - { - if(THIS->living_outputs > 1) return; - if(THIS->firstinput) return; - - }else{ - if(THIS->living_outputs) return; - } - pipe_done(); -} - -/* Allocate a new buffer and put it at the end of the chain of buffers - * scheduled for output. Return 1 if we have more bytes in buffers - * than allowed afterwards. - */ -static INLINE int append_buffer(struct pike_string *s) - /* 1=buffer full */ -{ - struct buffer *b; - - if(THIS->fd!= -1) - { - lseek(THIS->fd,THIS->pos,0); - write(THIS->fd,s->str,s->len); - THIS->pos+=s->len; - return 0; - } - else - { - nbuffers++; - b=ALLOC_STRUCT(buffer); - b->next=NULL; - b->s=s; - sbuffers += s->len; - s->refs++; - - if (THIS->lastbuffer) - THIS->lastbuffer->next=b; - else - THIS->firstbuffer=b; - - THIS->lastbuffer=b; - - THIS->bytes_in_buffer+=s->len; - } - return THIS->bytes_in_buffer > MAX_BYTES_IN_BUFFER; -} - -/* Wake up the sleepers */ -static void low_start() -{ - struct object *obj, *next; - struct output *o; - - - THISOBJ->refs++; /* dont kill yourself now */ - for(obj=THIS->firstoutput;obj;obj=next) - { - obj->refs++; /* Hang on PLEASE!! /hubbe */ - o=(struct output *)(obj->storage); - if (o->obj && o->mode==O_SLEEP) - { - if (!o->obj->prog) - { - output_finish(obj); - } - else - { -#if 0 - push_int(0); - push_callback(offset_output_write_callback); - push_callback(offset_output_close_callback); - apply_low(o->obj,o->set_nonblocking_offset,3); -#endif - output_try_write_some(obj); - o->mode=O_RUN; /* Hubbe */ - } - } - next=o->next; - free_object(obj); - } - - free_object(THISOBJ); -} - -/* Let's guess what this function does.... - * - */ -static INLINE void input_finish(void) -{ - struct input *i; - - while(1) - { - i=THIS->firstinput->next; - free_input(THIS->firstinput); - THIS->firstinput=i; - - if(!i) break; - - switch(i->type) - { - case I_OBJ: - THIS->sleeping=0; - push_callback(offset_input_read_callback); - push_int(0); - push_callback(offset_input_close_callback); - apply_low(i->u.obj,i->set_nonblocking_offset,3); - pop_stack(); - return; - - case I_MMAP: - if (THIS->fd==-1) return; - continue; - - case I_STRING: - append_buffer(i->u.str); - } - } - THIS->sleeping=0; - - low_start(); - finished_p(); -} - -/* This function reads some data from the file cache.. - * Called when we want some data to send. - */ -static INLINE struct pike_string* gimme_some_data(unsigned long pos) -{ - struct buffer *b; - unsigned long len; - - /* We have a file cache, read from it */ - if (THIS->fd!=-1) - { - if (THIS->pos<=pos) return NULL; /* no data */ - len=THIS->pos-pos; - if (len>READ_BUFFER_SIZE) len=READ_BUFFER_SIZE; - lseek(THIS->fd,pos,0); /* SEEK_SET */ - read(THIS->fd,static_buffer,len); - return make_shared_binary_string(static_buffer,len); - } - - if (pos<THIS->pos) - return make_shared_string("buffer underflow"); /* shit */ - - /* We want something in the next buffer */ - while (THIS->firstbuffer && pos>=THIS->pos+THIS->firstbuffer->s->len) - { - /* Free the first buffer, and update THIS->pos */ - b=THIS->firstbuffer; - THIS->pos+=b->s->len; - THIS->bytes_in_buffer-=b->s->len; - THIS->firstbuffer=b->next; - if (!b->next) - THIS->lastbuffer=NULL; - sbuffers-=b->s->len; - nbuffers--; - free_string(b->s); - free((char *)b); - - /* Wake up first input if it was sleeping and we - * have room for more in the buffer. - */ - if (THIS->sleeping && - THIS->firstinput && - THIS->bytes_in_buffer<MAX_BYTES_IN_BUFFER) - { - THIS->sleeping=0; - push_callback(offset_input_read_callback); - push_int(0); - push_callback(offset_input_close_callback); - apply(THIS->firstinput->u.obj, "set_nonblocking", 3); - pop_stack(); - } - } - - while (!THIS->firstbuffer) - { - if (THIS->firstinput) - { -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) - if (THIS->firstinput->type==I_MMAP) - { - if (pos >= THIS->firstinput->len + THIS->pos) /* end of mmap */ - { - THIS->pos+=THIS->firstinput->len; - input_finish(); - continue; - } - len=THIS->firstinput->len+THIS->pos-pos; - if (len>READ_BUFFER_SIZE) len=READ_BUFFER_SIZE; - return make_shared_binary_string(THIS->firstinput->u.mmap+ - pos-THIS->pos, - len); - } - else -#endif - if (THIS->firstinput->type!=I_OBJ) - { - input_finish(); /* shouldn't be anything else ... maybe a finished object */ - } - } - return NULL; /* no data */ - } - - if (pos==THIS->pos) - { - THIS->firstbuffer->s->refs++; - return THIS->firstbuffer->s; - } - return make_shared_binary_string(THIS->firstbuffer->s->str+ - pos-THIS->pos, - THIS->firstbuffer->s->len- - pos+THIS->pos); -} - - -/* - * close and free the contents of a struct output - * Note that the output struct is not freed or unlinked here, - * that is taken care of later. - */ -static INLINE void output_finish(struct object *obj) -{ - struct output *o; - - o=(struct output *)(obj->storage); - - if (o->obj) - { - if(o->obj->prog) - { -#ifdef BLOCKING_CLOSE - apply_low(o->obj,o->set_blocking_offset,0); - pop_stack(); -#endif - push_int(0); - apply(o->obj,"set_id",1); - pop_stack(); - - apply(o->obj,"close",0); - pop_stack(); - if(!THISOBJ->prog) - error("Pipe done callback destructed pipe.\n"); - destruct(o->obj); - } - free_object(o->obj); - noutputs--; - o->obj=NULL; - - THIS->living_outputs--; - - finished_p(); /* Moved by per, one line down.. :) */ - - free_object(THISOBJ); /* What? /Hubbe */ - } -} - -/* - * Try to write some data to our precious output - */ -static INLINE void output_try_write_some(struct object *obj) -{ - struct output *out; - struct pike_string *s; - unsigned long len; - INT32 ret; - - out=(struct output*)(obj->storage); - -#ifdef INSISTANT_WRITE - do - { -#endif - /* Get some data to write */ - s=gimme_some_data(out->pos); - if (!s) /* out of data */ - { - /* out of data, goto sleep */ - if (!THIS->firstinput || !out->obj->prog) /* end of life */ - { - output_finish(obj); - } - else - { -#if 0 - apply_low(out->obj, out->set_blocking_offset, 0); - pop_stack(); /* from apply */ -#endif - out->mode=O_SLEEP; - } - return; - } - len=s->len; - push_string(s); - apply_low(out->obj,out->write_offset,1); - out->mode=O_RUN; - - ret=-1; - if(sp[-1].type == T_INT) ret=sp[-1].u.integer; - pop_stack(); - - if (ret==-1) /* error, byebye */ - { - output_finish(obj); - return; - } - out->pos+=ret; - -#ifdef INSISTANT_WRITE - } while(ret == len); -#endif -} - -/********** methods *********************************************************/ - -/* Add an input to this pipe */ -static void pipe_input(INT32 args) -{ - struct input *i; - int fd=-1; /* Per, one less warning to worry about... */ - char *m; - struct stat s; - struct object *obj; - - if (args<1 || sp[-args].type != T_OBJECT) - error("Bad/missing argument 1 to pipe->input().\n"); - - obj=sp[-args].u.object; - if(!obj || !obj->prog) - error("pipe->input() on destructed object.\n"); - - push_int(0); - apply(sp[-args-1].u.object,"set_id", 1); - pop_stack(); - - i=new_input(); - -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) - - /* We do not handle mmaps if we have a buffer */ - if(THIS->fd == -1) - { - apply(obj, "query_fd", 0); - if(sp[-1].type == T_INT) fd=sp[-1].u.integer; - pop_stack(); - - if (fd != -1 && fstat(fd,&s)==0) - { - if(S_ISREG(s.st_mode) /* regular file */ - && ((long)(m=(char *)mmap(0,s.st_size,PROT_READ, - MAP_FILE|MAP_SHARED,fd,0))!=-1)) - { - mmapped += s.st_size; - - i->type=I_MMAP; - i->len=s.st_size; - i->u.mmap=m; - - pop_n_elems(args); - push_int(0); - return; - } - } - } -#endif - - i->u.obj=obj; - nobjects++; - i->type=I_OBJ; - i->u.obj->refs++; - i->set_nonblocking_offset=find_identifier("set_nonblocking",i->u.obj->prog); - i->set_blocking_offset=find_identifier("set_blocking",i->u.obj->prog); - - if (i->set_nonblocking_offset<0 || - i->set_blocking_offset<0) - { - free_object(i->u.obj); - i->u.obj=NULL; - i->type=I_NONE; - - nobjects--; - error("illegal file object%s%s\n", - ((i->set_nonblocking_offset<0)?"; no set_nonblocking":""), - ((i->set_blocking_offset<0)?"; no set_blocking":"")); - } - - if (i==THIS->firstinput) - { - push_callback(offset_input_read_callback); - push_int(0); - push_callback(offset_input_close_callback); - apply_low(i->u.obj,i->set_nonblocking_offset,3); - pop_stack(); - } - else - { - /* DOESN'T WORK!!! */ - push_int(0); - push_int(0); - push_callback(offset_input_close_callback); - apply_low(i->u.obj,i->set_nonblocking_offset,3); - pop_stack(); - } - - pop_n_elems(args); - push_int(0); -} - -static void pipe_write(INT32 args) -{ - struct input *i; - - if (args<1 || sp[-args].type!=T_STRING) - error("illegal argument to pipe->write()\n"); - - if (!THIS->firstinput) - { - append_buffer(sp[-args].u.string); - pop_n_elems(args); - push_int(0); - return; - } - - i=new_input(); - i->type=I_STRING; - nstrings++; - i->u.str=sp[-args].u.string; - i->u.str->refs++; - pop_n_elems(args-1); -} - -void f_mark_fd(INT32 args); - -static void pipe_output(INT32 args) -{ - struct object *obj; - struct output *o; - int fd; - struct stat s; - struct buffer *b; - - if (args<1 || - sp[-args].type != T_OBJECT || - !sp[-args].u.object || - !sp[-args].u.object->prog) - error("Bad/missing argument 1 to pipe->output().\n"); - - if (THIS->fd==-1) /* no buffer */ - { - /* test if usable as buffer */ - apply(sp[-args].u.object,"query_fd",0); - - if ((sp[-1].type==T_INT) - && (fd=sp[-1].u.integer)>=0 - && (fstat(fd,&s)==0) - && S_ISREG(s.st_mode) - && (THIS->fd=dup(fd))!=-1 ) - { - push_int(THIS->fd); - push_string(make_shared_string("pipe.c: file buffer")); - f_mark_fd(2); - pop_stack(); - - THIS->living_outputs++; - - while (THIS->firstbuffer) - { - b=THIS->firstbuffer; - THIS->firstbuffer=b->next; - lseek(THIS->fd,THIS->pos,0); - write(THIS->fd,b->s->str,b->s->len); - sbuffers-=b->s->len; - nbuffers--; - free_string(b->s); - free((char *)b); - } - THIS->lastbuffer=NULL; - - THIS->pos=0; - push_int(0); - apply(sp[-args-2].u.object,"set_id", 1); - pop_n_elems(args+2); /* ... and from apply x 2 */ - return; - } - pop_stack(); /* from apply */ - } - - THIS->living_outputs++; - THISOBJ->refs++; /* Weird */ - - /* Allocate a new struct output */ - obj=clone(output_program,0); - o=(struct output *)(obj->storage); - o->next=THIS->firstoutput; - THIS->firstoutput=obj; - noutputs++; - o->obj=NULL; - - o->obj=sp[-args].u.object; - o->obj->refs++; - - o->write_offset=find_identifier("write",o->obj->prog); - o->set_nonblocking_offset=find_identifier("set_nonblocking",o->obj->prog); - o->set_blocking_offset=find_identifier("set_blocking",o->obj->prog); - - if (o->write_offset<0 || o->set_nonblocking_offset<0 || - o->set_blocking_offset<0) - { - free_object(o->obj); - error("illegal file object%s%s%s\n", - ((o->write_offset<0)?"; no write":""), - ((o->set_nonblocking_offset<0)?"; no set_nonblocking":""), - ((o->set_blocking_offset<0)?"; no set_blocking":"")); - } - - o->mode=O_RUN; - o->pos=0; - - push_object(obj); - obj->refs++; - apply(o->obj,"set_id",1); - pop_stack(); - - push_int(0); - push_callback(offset_output_write_callback); - push_callback(offset_output_close_callback); - apply_low(o->obj,o->set_nonblocking_offset,3); - pop_stack(); - - pop_n_elems(args-1); -} - -static void pipe_set_done_callback(INT32 args) -{ - if (args==0) - { - free_svalue(&THIS->done_callback); - THIS->done_callback.type=T_INT; - return; - } - if (args<1 || (sp[-args].type!=T_FUNCTION && sp[-args].type!=T_ARRAY)) - error("Illegal argument to set_done_callback()\n"); - - if (args>1) - { - free_svalue(&THIS->id); - assign_svalue_no_free(&(THIS->id),sp-args+1); - } - - free_svalue(&THIS->done_callback); - assign_svalue_no_free(&(THIS->done_callback),sp-args); - pop_n_elems(args-1); -} - -static void pipe_set_output_closed_callback(INT32 args) -{ - if (args==0) - { - free_svalue(&THIS->done_callback); - THIS->output_closed_callback.type=T_INT; - return; - } - if (args<1 || (sp[-args].type!=T_FUNCTION && sp[-args].type!=T_ARRAY)) - error("Illegal argument to set_output_closed_callback()\n"); - - if (args>1) - { - free_svalue(&THIS->id); - assign_svalue_no_free(&(THIS->id),sp-args+1); - } - free_svalue(&THIS->output_closed_callback); - assign_svalue_no_free(&(THIS->output_closed_callback),sp-args); - pop_n_elems(args-1); -} - -static void pipe_finish(INT32 args) -{ - pop_n_elems(args); - push_int(0); - pipe_done(); -} - -static void pipe_start(INT32 args) /* force start */ -{ - low_start(); - if(args) - pop_n_elems(args-1); -} - -/********** callbacks *******************************************************/ - -static void pipe_write_output_callback(INT32 args) -{ - if (args<1 || sp[-args].type!=T_OBJECT) - error("Illegal argument to pipe->write_output_callback\n"); - - if(!sp[-args].u.object->prog) return; - - if(sp[-args].u.object->prog != output_program) - error("Illegal argument to pipe->write_output_callback\n"); - - output_try_write_some(sp[-args].u.object); - pop_n_elems(args-1); -} - -static void pipe_close_output_callback(INT32 args) -{ - struct output *o; - if (args<1 || sp[-args].type!=T_OBJECT) - - if(!sp[-args].u.object->prog) return; - - if(sp[-args].u.object->prog != output_program) - error("Illegal argument to pipe->close_output_callback\n"); - - o=(struct output *)(sp[-args].u.object->storage); - - if (THIS->output_closed_callback.type!=T_INT) - { - assign_svalue_no_free(sp++,&THIS->id); - push_object(o->obj); - apply_svalue(&(THIS->output_closed_callback),2); - pop_stack(); - } - - output_finish(sp[-args].u.object); - pop_n_elems(args-1); -} - -static void pipe_read_input_callback(INT32 args) -{ - struct input *i; - struct pike_string *s; - - if (args<2 || sp[1-args].type!=T_STRING) - error("Illegal argument to pipe->read_input_callback\n"); - - i=THIS->firstinput; - - if (!i) - error("Pipe read callback without any inputs left.\n"); - - s=sp[1-args].u.string; - - if(append_buffer(s)) - { - /* THIS DOES NOT WORK */ - push_int(0); - push_int(0); - push_callback(offset_input_close_callback); - apply_low(i->u.obj,i->set_nonblocking_offset,3); - pop_stack(); - THIS->sleeping=1; - } - - low_start(); - pop_n_elems(args-1); -} - -static void pipe_close_input_callback(INT32 args) -{ - struct input *i; - i=THIS->firstinput; - - if(!i) - error("Input close callback without inputs!\n"); - - if(i->type != I_OBJ) - error("Premature close callback on pipe!.\n"); - - if (i->u.obj->prog) - { -#ifdef BLOCKING_CLOSE - apply_low(i->u.obj,i->set_blocking_offset,0); - pop_stack(); -#endif - apply(i->u.obj,"close",0); - pop_stack(); - } - nobjects--; - free_object(i->u.obj); - i->type=I_NONE; - - input_finish(); - if(args) - pop_n_elems(args-1); -} - -static void pipe_version(INT32 args) -{ - pop_n_elems(args); - push_string(make_shared_string("PIPE ver 2.0")); -} - -/********** init/exit *******************************************************/ - -void close_and_free_everything(struct object *thisobj,struct pipe *p) -{ - struct buffer *b; - struct input *i; - struct output *o; - struct object *obj; - - p->done=1; - - if (thisobj) - thisobj->refs++; /* don't kill object during this */ - - while (p->firstbuffer) - { - b=p->firstbuffer; - p->firstbuffer=b->next; - sbuffers-=b->s->len; - nbuffers--; - free_string(b->s); - b->next=NULL; - free((char *)b); /* Hubbe */ - } - p->lastbuffer=NULL; - - - while (p->firstinput) - { - i=p->firstinput; - p->firstinput=i->next; - free_input(i); - } - p->lastinput=NULL; - - while (p->firstoutput) - { - obj=p->firstoutput; - o=(struct output *)(obj->storage); - p->firstoutput=o->next; - output_finish(obj); - free_object(obj); - } - if (p->fd!=-1) - { - close(p->fd); - p->fd=-1; - } - - p->living_outputs=0; - - if (thisobj) - free_object(thisobj); - - free_svalue(& p->done_callback); - free_svalue(& p->output_closed_callback); - free_svalue(& p->id); - - p->done_callback.type=T_INT; - p->output_closed_callback.type=T_INT; - p->id.type=T_INT; - - p->done=0; -} - -static void init_pipe_struct(struct object *o) -{ - THIS->firstbuffer=THIS->lastbuffer=NULL; - THIS->firstinput=THIS->lastinput=NULL; - THIS->firstoutput=NULL; - THIS->bytes_in_buffer=0; - THIS->pos=0; - THIS->sleeping=0; - THIS->done=0; - THIS->fd=-1; - THIS->done_callback.type=T_INT; - THIS->output_closed_callback.type=T_INT; - THIS->id.type=T_INT; - THIS->id.u.integer=0; - THIS->living_outputs=0; -} - -static void exit_pipe_struct(struct object *o) -{ - close_and_free_everything(NULL,THIS); -} - -static void exit_output_struct(struct object *obj) -{ - struct output *o; - - o=(struct output *)(fp->current_storage); - if (o->obj) - { - if(o->obj->prog) - { -#ifdef BLOCKING_CLOSE - apply_low(o->obj,o->set_blocking_offset,0); - pop_stack(); -#endif - push_int(0); - apply(o->obj,"set_id",1); - pop_stack(); - - apply(o->obj,"close",0); - pop_stack(); - - if(!THISOBJ->prog) - error("Pipe done callback destructed pipe.\n"); - } - free_object(o->obj); - noutputs--; - o->obj=0; - } -} - -static void init_output_struct(struct object *ob) -{ - struct output *o; - o=(struct output *)(fp->current_storage); - o->obj=0; -} - - -/********** Pike init *******************************************************/ - -void port_setup_program(void); - -void f__pipe_debug(INT32 args) -{ - pop_n_elems(args); - push_int(noutputs); - push_int(ninputs); - push_int(nstrings); - push_int(nobjects); - push_int(mmapped); - push_int(nbuffers); - push_int(sbuffers); - f_aggregate(7); -} - -void pike_module_init() -{ - start_new_program(); - add_storage(sizeof(struct pipe)); - add_efun("_pipe_debug", f__pipe_debug, "function(:array)", 0); - add_function("input",pipe_input,"function(object:void)",0); - add_function("output",pipe_output,"function(object:void)",0); - add_function("write",pipe_write,"function(string:void)",0); - - add_function("start",pipe_start,"function(:void)",0); - add_function("finish",pipe_finish,"function(:void)",0); - - add_function("set_output_closed_callback",pipe_set_output_closed_callback, - "function(void|function(mixed,object:mixed),void|mixed:void)",0); - add_function("set_done_callback",pipe_set_done_callback, - "function(void|function(mixed:mixed),void|mixed:void)",0); - - add_function("_output_close_callback",pipe_close_output_callback, - "function(int:void)",0); - add_function("_input_close_callback",pipe_close_input_callback, - "function(int:void)",0); - add_function("_output_write_callback",pipe_write_output_callback, - "function(int:void)",0); - add_function("_input_read_callback",pipe_read_input_callback, - "function(int,string:void)",0); - - add_function("version",pipe_version,"function(:string)",0); - - set_init_callback(init_pipe_struct); - set_exit_callback(exit_pipe_struct); - - pipe_program=end_program(); - add_program_constant("pipe",pipe_program, 0); - - offset_output_close_callback=find_identifier("_output_close_callback", - pipe_program); - offset_input_close_callback=find_identifier("_input_close_callback", - pipe_program); - offset_output_write_callback=find_identifier("_output_write_callback", - pipe_program); - offset_input_read_callback=find_identifier("_input_read_callback", - pipe_program); - - - start_new_program(); - add_storage(sizeof(struct output)); - set_init_callback(init_output_struct); - set_exit_callback(exit_output_struct); - output_program=end_program(); - add_program_constant("__output",output_program, 0); -} - -void pike_module_exit(void) -{ - if(pipe_program) free_program(pipe_program); - pipe_program=0; - if(output_program) free_program(output_program); - output_program=0; -} - - - - - - - diff --git a/src/modules/pipe/testsuite.in b/src/modules/pipe/testsuite.in deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/modules/readlinemod/.cvsignore b/src/modules/readlinemod/.cvsignore deleted file mode 100644 index 74ee34e458820cc9a20357e972f33acb4b423f03..0000000000000000000000000000000000000000 --- a/src/modules/readlinemod/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -.pure -Makefile -config.log -config.status -configure -dependencies -lib_dirs -linker_options -readline_machine.h -stamp-h diff --git a/src/modules/readlinemod/.gitignore b/src/modules/readlinemod/.gitignore deleted file mode 100644 index 85b1cf5830cd9ca112606ef69527ffa8b619bbbf..0000000000000000000000000000000000000000 --- a/src/modules/readlinemod/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/.pure -/Makefile -/config.log -/config.status -/configure -/dependencies -/lib_dirs -/linker_options -/readline_machine.h -/stamp-h diff --git a/src/modules/readlinemod/Makefile.in b/src/modules/readlinemod/Makefile.in deleted file mode 100644 index d16c08f3ad4f3ceeb4f81f7becad5a073452eff9..0000000000000000000000000000000000000000 --- a/src/modules/readlinemod/Makefile.in +++ /dev/null @@ -1,8 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -MODULE_CPPFLAGS=@CPPFLAGS@ -MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ -OBJS=readlinemod.o - -@dynamic_module_makefile@ -@dependencies@ diff --git a/src/modules/readlinemod/configure.in b/src/modules/readlinemod/configure.in deleted file mode 100644 index 2d27610c9c5ff16709debbe3e480da6bd5f4ae60..0000000000000000000000000000000000000000 --- a/src/modules/readlinemod/configure.in +++ /dev/null @@ -1,52 +0,0 @@ -AC_INIT(readlinemod.c) -AC_CONFIG_HEADER(readline_machine.h) -AC_ARG_WITH(readline,[ --with(out)-readline support command line editing],[],[with_readline=yes]) - -sinclude(../module_configure.in) - -if test x$with_readline = xyes ; then - AC_MSG_CHECKING(Checking for GNU directory) - - AC_CACHE_VAL(pike_cv_gnu_dir, [ - for pike_cv_gnu_dir in /usr/gnu /opt/gnu /usr/local/gnu /sw/gnu no; do - if test -d $pike_cv_gnu_dir/. ; then - break - else - : - fi - done - ]) - AC_MSG_RESULT($pike_cv_gnu_dir) - - if test x$pike_cv_gnu_dir != xno; then - if test -d $pike_cv_gnu_dir/include/. ; then - echo Adding $pike_cv_gnu_dir/include to the include path - CPPFLAGS="$CPPFLAGS -I$pike_cv_gnu_dir/include" - else - : - fi - if test -d $pike_cv_gnu_dir/lib/. ; then - echo Adding $pike_cv_gnu_dir/lib to the runtime link path - echo $pike_cv_gnu_dir/lib >lib_dirs - elif test -f lib_dirs ; then - rm lib_dirs - else - : - fi - else - : - fi - - AC_CHECK_HEADERS(readline.h history.h readline/readline.h history/history.h readline/history.h) - - if test $ac_cv_header_readline_h = yes -o $ac_cv_header_readline_readline_h = yes ; then - if test $ac_cv_header_history_h = yes -o $ac_cv_header_history_history_h = yes -o $ac_cv_header_readline_history_h = yes ; then - AC_CHECK_LIB(termcap, tputs) - AC_CHECK_LIB(readline, readline) - fi - fi -fi - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/readlinemod/readline_machine.h.in b/src/modules/readlinemod/readline_machine.h.in deleted file mode 100644 index 7ce5c2ec3ae6a7ec83311f5c10fc614513a3f908..0000000000000000000000000000000000000000 --- a/src/modules/readlinemod/readline_machine.h.in +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef GDBM_MACHINE_H -#define GDBM_MACHINE_H - -/* Define this if you have <readline.h> */ -#undef HAVE_READLINE_H -#undef HAVE_READLINE_READLINE_H - -/* Define this if you have <history.h> */ -#undef HAVE_HISTORY_H -#undef HAVE_HISTORY_HISTORY_H -#undef HAVE_READLINE_HISTORY_H - -/* Define this if you have -lreadline */ -#undef HAVE_LIBREADLINE - -/* Define this if you have -ltermcap */ -#undef HAVE_LIBTERMCAP - -#endif diff --git a/src/modules/readlinemod/readlinemod.c b/src/modules/readlinemod/readlinemod.c deleted file mode 100644 index ce29c9d6eb6f980a65ef3318088ce4ffba668737..0000000000000000000000000000000000000000 --- a/src/modules/readlinemod/readlinemod.c +++ /dev/null @@ -1,140 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#include "global.h" -#include "readline_machine.h" -#include "types.h" -#include "interpret.h" -#include "svalue.h" -#include "stralloc.h" -#include "array.h" -#include "object.h" -#include "macros.h" -#include "threads.h" - -#ifndef HAVE_LIBTERMCAP -#undef HAVE_LIBREADLINE -#endif - -#if !defined(HAVE_READLINE_H) && !defined(HAVE_READLINE_READLINE_H) -#undef HAVE_LIBREADLINE -#endif - -#if !defined(HAVE_HISTORY_H) && !defined(HAVE_READLINE_HISTORY_H) && !defined(HAVE_HISTORY_HISTORY_H) -#undef HAVE_LIBREADLINE -#endif - -#ifdef HAVE_LIBREADLINE - -#ifdef HAVE_READLINE_READLINE_H -#include <readline/readline.h> -#else -#ifdef HAVE_READLINE_H -#include <readline.h> -#endif -#endif - -#ifdef HAVE_READLINE_HISTORY_H -#include <readline/history.h> -#else -#ifdef HAVE_HISTORY_HISTORY_H -#include <history/history.h> -#else -#ifdef HAVE_HISTORY_H -#include <history.h> -#endif -#endif -#endif - -static void f_readline(INT32 args) -{ - char *r; - struct pike_string *str; - if(args < 1) - error("Too few arguments to readline().\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to readline()\n"); - - str=sp[-args].u.string; - THREADS_ALLOW(); - r=readline(str->str); - THREADS_DISALLOW(); - - pop_n_elems(args); - if(r) - { - if(*r) add_history(r); - push_string(make_shared_string(r)); - free(r); - } else { - push_int(0); - } -} - -void pike_module_init(void) -{ - rl_bind_key('\t', rl_insert); - add_efun("readline",f_readline,"function(string:string)",OPT_SIDE_EFFECT); -} - -#else - -#include <stdio.h> - -#define BLOCK 16384 - -static void f_readline(INT32 args) -{ - char *prompt; - int plen; - char line[BLOCK]; - char *r; - int tmp; - - if(args < 1) - error("Too few arguments to readline().\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to readline()\n"); - - prompt = sp[-args].u.string->str; - plen = sp[-args].u.string->len; - - THREADS_ALLOW(); - - write(1, prompt, plen); - r=fgets(line,BLOCK-1,stdin); /* Should probably get rid of this one */ - line[BLOCK-1] = '\0'; /* Always NUL-terminated */ - - THREADS_DISALLOW(); - - pop_n_elems(args); - - if (r) - { - INT32 len; - if ((len=strlen(line))) - { - if (line[len-1]=='\n') - { - push_string(make_shared_binary_string(line,len-1)); - return; - } - } - } - push_int(0); -} - -void pike_module_init(void) -{ - add_efun("readline",f_readline,"function(string:string)",OPT_SIDE_EFFECT); -} - -#endif - -void pike_module_exit(void) {} - - diff --git a/src/modules/readlinemod/testsuite.in b/src/modules/readlinemod/testsuite.in deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/modules/regexp/.cvsignore b/src/modules/regexp/.cvsignore deleted file mode 100644 index ed13e79dafb075dba9bee95ed9608b991ad17397..0000000000000000000000000000000000000000 --- a/src/modules/regexp/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.pure -Makefile -config.log -config.status -configure -dependencies -stamp-h diff --git a/src/modules/regexp/.gitignore b/src/modules/regexp/.gitignore deleted file mode 100644 index 2d448ae74bf4fb36f7a1db409d228c656ce05d72..0000000000000000000000000000000000000000 --- a/src/modules/regexp/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/.pure -/Makefile -/config.log -/config.status -/configure -/dependencies -/stamp-h diff --git a/src/modules/regexp/Makefile.in b/src/modules/regexp/Makefile.in deleted file mode 100644 index 21853b9fc4c4f4ec9110cbd08caed4824af78aa6..0000000000000000000000000000000000000000 --- a/src/modules/regexp/Makefile.in +++ /dev/null @@ -1,6 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -OBJS=regexp.o glue.o - -@dynamic_module_makefile@ -@dependencies@ \ No newline at end of file diff --git a/src/modules/regexp/configure.in b/src/modules/regexp/configure.in deleted file mode 100644 index ed3283c8eec415697210f9591f054dac166c5e4c..0000000000000000000000000000000000000000 --- a/src/modules/regexp/configure.in +++ /dev/null @@ -1,8 +0,0 @@ -AC_INIT(regexp.c) - -sinclude(../module_configure.in) - - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/regexp/glue.c b/src/modules/regexp/glue.c deleted file mode 100644 index 04cf266c257b4c2ef523bbf11179e346823adbf5..0000000000000000000000000000000000000000 --- a/src/modules/regexp/glue.c +++ /dev/null @@ -1,118 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#include "global.h" -#include "types.h" -#include "interpret.h" -#include "svalue.h" -#include "stralloc.h" -#include "array.h" -#include "object.h" -#include "macros.h" - -#include <regexp.h> - -struct regexp_glue -{ - struct regexp *regexp; -}; - -#define THIS ((struct regexp_glue *)(fp->current_storage)) - -static void do_free() -{ - if(THIS->regexp) - { - free((char *)THIS->regexp); - THIS->regexp=0; - } -} - -static void regexp_create(INT32 args) -{ - do_free(); - if(args) - { - if(sp[-args].type != T_STRING) - error("Bad argument 1 to regexp->create()\n"); - - THIS->regexp=regcomp(sp[-args].u.string->str, 0); - } -} - -static void regexp_match(INT32 args) -{ - int i; - if(!args) - error("Too few arguments to regexp->match()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to regexp->match()\n"); - - i=regexec(THIS->regexp, sp[-args].u.string->str); - pop_n_elems(args); - push_int(i); -} - -static void regexp_split(INT32 args) -{ - struct pike_string *s; - struct regexp *r; - if(!args) - error("Too few arguments to regexp->split()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to regexp->split()\n"); - - s=sp[-args].u.string; - if(regexec(r=THIS->regexp, s->str)) - { - int i,j; - s->refs++; - pop_n_elems(args); - for(j=i=1;i<NSUBEXP;i++) - { - if(!r->startp[i] || !r->endp[i]) - { - push_int(0); - }else{ - push_string(make_shared_binary_string(r->startp[i], - r->endp[i]-r->startp[i])); - j=i; - } - } - if(j<i-1) pop_n_elems(i-j-1); - push_array(aggregate_array(j)); - free_string(s); - }else{ - pop_n_elems(args); - push_int(0); - } -} - -static void init_regexp_glue(struct object *o) -{ - THIS->regexp=0; -} - -static void exit_regexp_glue(struct object *o) -{ - do_free(); -} - - -void pike_module_exit(void) {} - -void pike_module_init(void) -{ - add_storage(sizeof(struct regexp_glue)); - - add_function("create",regexp_create,"function(void|string:void)",0); - add_function("match",regexp_match,"function(string:int)",0); - add_function("split",regexp_split,"function(string:string*)",0); - - set_init_callback(init_regexp_glue); - set_exit_callback(exit_regexp_glue); -} diff --git a/src/modules/regexp/regexp.c b/src/modules/regexp/regexp.c deleted file mode 100644 index 08c988177cecbba9f3c2216dc13fc8095d3fa185..0000000000000000000000000000000000000000 --- a/src/modules/regexp/regexp.c +++ /dev/null @@ -1,1408 +0,0 @@ -/* - * - * regexp.c - regular expression matching - * - * DESCRIPTION - * - * Underneath the reformatting and comment blocks which were added to - * make it consistent with the rest of the code, you will find a - * modified version of Henry Specer's regular expression library. - * Henry's functions were modified to provide the minimal regular - * expression matching, as required by P1003. Henry's code was - * copyrighted, and copy of the copyright message and restrictions - * are provided, verbatim, below: - * - * Copyright (c) 1986 by University of Toronto. - * Written by Henry Spencer. Not derived from licensed software. - * - * Permission is granted to anyone to use this software for any - * purpose on any computer system, and to redistribute it freely, - * subject to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of - * this software, no matter how awful, even if they arise - * from defects in it. - * - * 2. The origin of this software must not be misrepresented, either - * by explicit claim or by omission. - * - * 3. Altered versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * - * This version modified by Ian Phillipps to return pointer to terminating - * NUL on substitution string. [ Temp mail address ex-igp@camcon.co.uk ] - * - * Altered by amylaar to support excompatible option and the - * operators \< and >\ . ( 7.Sep. 1991 ) - * - * regsub altered by amylaar to take an additional parameter specifying - * maximum number of bytes that can be written to the memory region - * pointed to by dest - * - * Also altered by Fredrik Hubinette to handle the + operator and - * eight-bit chars. Mars 22 1996 - * - * - * Beware that some of this code is subtly aware of the way operator - * precedence is structured in regular expressions. Serious changes in - * regular-expression syntax might require a total rethink. - * - * AUTHORS - * - * Mark H. Colburn, NAPS International (mark@jhereg.mn.org) - * Henry Spencer, University of Torronto (henry@utzoo.edu) - * - * Sponsored by The USENIX Association for public distribution. - * - */ - -/* Headers */ -#include "global.h" -#include <ctype.h> -#include "regexp.h" -#include "memory.h" -#include "error.h" - -/* - * The "internal use only" fields in regexp.h are present to pass info from - * compile to execute that permits the execute phase to run lots faster on - * simple cases. They are: - * - * regstart char that must begin a match; '\0' if none obvious - * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or NULL - * regmlen length of regmust string - * - * Regstart and reganch permit very fast decisions on suitable starting points - * for a match, cutting down the work a lot. Regmust permits fast rejection - * of lines that cannot possibly match. The regmust tests are costly enough - * that regcomp() supplies a regmust only if the r.e. contains something - * potentially expensive (at present, the only such thing detected is * or + - * at the start of the r.e., which can involve a lot of backup). Regmlen is - * supplied because the test in regexec() needs it and regcomp() is computing - * it anyway. - */ - -/* - * Structure for regexp "program". This is essentially a linear encoding - * of a nondeterministic finite-state machine (aka syntax charts or - * "railroad normal form" in parsing technology). Each node is an opcode - * plus a "nxt" pointer, possibly plus an operand. "Nxt" pointers of - * all nodes except BRANCH implement concatenation; a "nxt" pointer with - * a BRANCH on both ends of it is connecting two alternatives. (Here we - * have one of the subtle syntax dependencies: an individual BRANCH (as - * opposed to a collection of them) is never concatenated with anything - * because of operator precedence.) The operand of some types of node is - * a literal string; for others, it is a node leading into a sub-FSM. In - * particular, the operand of a BRANCH node is the first node of the branch. - * (NB this is *not* a tree structure: the tail of the branch connects - * to the thing following the set of BRANCHes.) The opcodes are: - */ - -/* definition number opnd? meaning */ -#define END 0 /* no End of program. */ -#define BOL 1 /* no Match "" at beginning of line. */ -#define EOL 2 /* no Match "" at end of line. */ -#define ANY 3 /* no Match any one character. */ -#define ANYOF 4 /* str Match any character in this string. */ -#define ANYBUT 5 /* str Match any character not in this - * string. */ -#define BRANCH 6 /* node Match this alternative, or the - * nxt... */ -#define BACK 7 /* no Match "", "nxt" ptr points backward. */ -#define EXACTLY 8 /* str Match this string. */ -#define NOTHING 9 /* no Match empty string. */ -#define STAR 10 /* node Match this (simple) thing 0 or more - * times. */ -#define WORDSTART 11 /* node matching a start of a word */ -#define WORDEND 12 /* node matching an end of a word */ -#define OPEN 20 /* no Mark this point in input as start of - * #n. */ - /* OPEN+1 is number 1, etc. */ -#define CLOSE 30 /* no Analogous to OPEN. */ - -/* - * Opcode notes: - * - * BRANCH The set of branches constituting a single choice are hooked - * together with their "nxt" pointers, since precedence prevents - * anything being concatenated to any individual branch. The - * "nxt" pointer of the last BRANCH in a choice points to the - * thing following the whole choice. This is also where the - * final "nxt" pointer of each individual branch points; each - * branch starts with the operand node of a BRANCH node. - * - * BACK Normal "nxt" pointers all implicitly point forward; BACK - * exists to make loop structures possible. - * - * STAR complex '*', are implemented as circular BRANCH structures - * using BACK. Simple cases (one character per match) are - * implemented with STAR for speed and to minimize recursive - * plunges. - * - * OPEN,CLOSE ...are numbered at compile time. - */ - -/* - * A node is one char of opcode followed by two chars of "nxt" pointer. - * "Nxt" pointers are stored as two 8-bit pieces, high order first. The - * value is a positive offset from the opcode of the node containing it. - * An operand, if any, simply follows the node. (Note that much of the - * code generation knows about this implicit relationship.) - * - * Using two bytes for the "nxt" pointer is vast overkill for most things, - * but allows patterns to get big without disasters. - */ -#define OP(p) (*(p)) -#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) -#define OPERAND(p) ((p) + 3) - -/* - * The first byte of the regexp internal "program" is actually this magic - * number; the start node begins in the second byte. - */ -#define MAGIC 0234 - -/* - * Utility definitions. - */ - -#define regerror(X) error("Regexp: %s\n",X); -#define SPECIAL 0x100 -#define LBRAC ('('|SPECIAL) -#define RBRAC (')'|SPECIAL) -#define ASTERIX ('*'|SPECIAL) -#define PLUS ('+'|SPECIAL) -#define OR_OP ('|'|SPECIAL) -#define DOLLAR ('$'|SPECIAL) -#define DOT ('.'|SPECIAL) -#define CARET ('^'|SPECIAL) -#define LSQBRAC ('['|SPECIAL) -#define RSQBRAC (']'|SPECIAL) -#define LSHBRAC ('<'|SPECIAL) -#define RSHBRAC ('>'|SPECIAL) -#define FAIL(m) { regerror(m); return(NULL); } -#define ISMULT(c) ((c) == ASTERIX || (c)==PLUS) -#define META "^$.[()|*+\\" -#ifndef CHARBITS -#define CHARBITS 0xff -#define UCHARAT(p) ((int)*(unsigned char *)(p)) -#else -#define UCHARAT(p) ((int)*(p)&CHARBITS) -#endif -#define ISWORDPART(c) ( isalnum(c) || (c) == '_' ) - -/* - * Flags to be passed up and down. - */ -#define HASWIDTH 01 /* Known never to match null string. */ -#define SIMPLE 02 /* Simple enough to be STAR operand. */ -#define SPSTART 04 /* Starts with * */ -#define WORST 0 /* Worst case. */ - -/* - * Global work variables for regcomp(). - */ -static short *regparse; /* Input-scan pointer. */ -static int regnpar; /* () count. */ -static char regdummy; -static char *regcode; /* Code-emit pointer; ®dummy = don't. */ -static long regsize; /* Code size. */ - -/* - * Forward declarations for regcomp()'s friends. - */ -#ifndef STATIC -#define STATIC static -#endif -STATIC char *reg(); -STATIC char *regbranch(); -STATIC char *regpiece(); -STATIC char *regatom(); -STATIC char *regnode(); -STATIC char *regnext(); -STATIC void regc(); -STATIC void reginsert(); -STATIC void regtail(); -STATIC void regoptail(); - -/* - - regcomp - compile a regular expression into internal code - * - * We can't allocate space until we know how big the compiled form will be, - * but we can't compile it (and thus know how big it is) until we've got a - * place to put the code. So we cheat: we compile it twice, once with code - * generation turned off and size counting turned on, and once "for real". - * This also means that we don't allocate space until we are sure that the - * thing really will compile successfully, and we never have to move the - * code and thus invalidate pointers into it. (Note that it has to be in - * one piece because free() must be able to free it all.) - * - * Beware that the optimization-preparation code in here knows about some - * of the structure of the compiled regexp. - */ -regexp *regcomp(exp,excompat) -char *exp; -int excompat; /* \( \) operators like in unix ex */ -{ - register regexp *r; - register char *scan; - register char *longest; - register int len; - int flags; - short *exp2,*dest,c; - - if (exp == (char *)NULL) - FAIL("NULL argument"); - - exp2=(short*)xalloc( (strlen(exp)+1) * (sizeof(short[8])/sizeof(char[8])) ); - for ( scan=exp,dest=exp2;( c= UCHARAT(scan++)); ) { - switch (c) { - case '(': - case ')': - *dest++ = excompat ? c : c | SPECIAL; - break; - case '.': - case '*': - case '+': - case '|': - case '$': - case '^': - case '[': - case ']': - *dest++ = c | SPECIAL; - break; - case '\\': - switch ( c = *scan++ ) { - case '(': - case ')': - *dest++ = excompat ? c | SPECIAL : c; - break; - case '<': - case '>': - *dest++ = c | SPECIAL; - break; - case '{': - case '}': - FAIL("sorry, unimplemented operator"); - case 'b': *dest++ = '\b'; break; - case 't': *dest++ = '\t'; break; - case 'r': *dest++ = '\r'; break; - default: - *dest++ = c; - } - break; - default: - *dest++ = c; - } - } - *dest=0; - /* First pass: determine size, legality. */ - regparse = exp2; - regnpar = 1; - regsize = 0L; - regcode = ®dummy; - regc(MAGIC); - if (reg(0, &flags) == (char *)NULL) - return ((regexp *)NULL); - - /* Small enough for pointer-storage convention? */ - if (regsize >= 32767L) /* Probably could be 65535L. */ - FAIL("regexp too big"); - - /* Allocate space. */ - r = (regexp *) xalloc(sizeof(regexp) + (unsigned) regsize); - if (r == (regexp *) NULL) - FAIL("out of space"); - - /* Second pass: emit code. */ - regparse = exp2; - regnpar = 1; - regcode = r->program; - regc(MAGIC); - if (reg(0, &flags) == NULL) - return ((regexp *) NULL); - - /* Dig out information for optimizations. */ - r->regstart = '\0'; /* Worst-case defaults. */ - r->reganch = 0; - r->regmust = NULL; - r->regmlen = 0; - scan = r->program + 1; /* First BRANCH. */ - if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ - scan = OPERAND(scan); - - /* Starting-point info. */ - if (OP(scan) == EXACTLY) - r->regstart = *OPERAND(scan); - else if (OP(scan) == BOL) - r->reganch++; - - /* - * If there's something expensive in the r.e., find the longest - * literal string that must appear and make it the regmust. Resolve - * ties in favor of later strings, since the regstart check works - * with the beginning of the r.e. and avoiding duplication - * strengthens checking. Not a strong reason, but sufficient in the - * absence of others. - */ - if (flags & SPSTART) { - longest = NULL; - len = 0; - for (; scan != NULL; scan = regnext(scan)) - if (OP(scan) == EXACTLY && - (int)strlen(OPERAND(scan)) >= len) { - longest = OPERAND(scan); - len = strlen(OPERAND(scan)); - } - r->regmust = longest; - r->regmlen = len; - } - } - free((char*)exp2); - return (r); -} - -/* - - reg - regular expression, i.e. main body or parenthesized thing - * - * Caller must absorb opening parenthesis. - * - * Combining parenthesis handling with the base level of regular expression - * is a trifle forced, but the need to tie the tails of the branches to what - * follows makes it hard to avoid. - */ -static char *reg(paren, flagp) -int paren; /* Parenthesized? */ -int *flagp; -{ - register char *ret; - register char *br; - register char *ender; - register int parno=0; /* make gcc happy */ - int flags; - - *flagp = HASWIDTH; /* Tentatively. */ - - /* Make an OPEN node, if parenthesized. */ - if (paren) { - if (regnpar >= NSUBEXP) - FAIL("too many ()"); - parno = regnpar; - regnpar++; - ret = regnode(OPEN + parno); - } else - ret = (char *)NULL; - - /* Pick up the branches, linking them together. */ - br = regbranch(&flags); - if (br == (char *)NULL) - return ((char *)NULL); - if (ret != (char *)NULL) - regtail(ret, br); /* OPEN -> first. */ - else - ret = br; - if (!(flags & HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags & SPSTART; - while (*regparse == OR_OP) { - regparse++; - br = regbranch(&flags); - if (br == (char *)NULL) - return ((char *)NULL); - regtail(ret, br); /* BRANCH -> BRANCH. */ - if (!(flags & HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags & SPSTART; - } - - /* Make a closing node, and hook it on the end. */ - ender = regnode((paren) ? CLOSE + parno : END); - regtail(ret, ender); - - /* Hook the tails of the branches to the closing node. */ - for (br = ret; br != (char *)NULL; br = regnext(br)) - regoptail(br, ender); - - /* Check for proper termination. */ - if (paren && *regparse++ != RBRAC) { - FAIL("unmatched ()"); - } else if (!paren && *regparse != '\0') { - if (*regparse == RBRAC) { - FAIL("unmatched ()"); - } else - FAIL("junk on end");/* "Can't happen". */ - /* NOTREACHED */ - } - return (ret); -} - -/* - - regbranch - one alternative of an | operator - * - * Implements the concatenation operator. - */ -static char *regbranch(flagp) -int *flagp; -{ - register char *ret; - register char *chain; - register char *latest; - int flags; - - *flagp = WORST; /* Tentatively. */ - - ret = regnode(BRANCH); - chain = (char *)NULL; - while (*regparse != '\0' && *regparse != OR_OP && *regparse != RBRAC) { - latest = regpiece(&flags); - if (latest == (char *)NULL) - return ((char *)NULL); - *flagp |= flags & HASWIDTH; - if (chain == (char *)NULL) /* First piece. */ - *flagp |= flags & SPSTART; - else - regtail(chain, latest); - chain = latest; - } - if (chain == (char *)NULL) /* Loop ran zero times. */ - regnode(NOTHING); - - return (ret); -} - -/* - - regpiece - something followed by possible [*] - * - * Note that the branching code sequence used for * is somewhat optimized: - * they use the same NOTHING node as both the endmarker for their branch - * list and the body of the last branch. It might seem that this node could - * be dispensed with entirely, but the endmarker role is not redundant. - */ -static char *regpiece(flagp) -int *flagp; -{ - register char *ret; - register short op; - /* register char *nxt; */ - int flags; - - ret = regatom(&flags); - if (ret == (char *)NULL) - return ((char *)NULL); - - op = *regparse; - if (!ISMULT(op)) { - *flagp = flags; - return (ret); - } - if (!(flags & HASWIDTH)) - FAIL("* or + operand could be empty"); - *flagp = (WORST | SPSTART); - - if(op == ASTERIX) - { - if (flags & SIMPLE) - { - reginsert(STAR, ret); - } - else - { - /* Emit x* as (x&|), where & means "self". */ - reginsert(BRANCH, ret); /* Either x */ - regoptail(ret, regnode(BACK)); /* and loop */ - regoptail(ret, ret); /* back */ - regtail(ret, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } - } - else if(op == PLUS) - { - /* Emit a+ as (a&) where & means "self" /Fredrik Hubinette */ - char *tmp; - tmp=regnode(BACK); - reginsert(BRANCH, tmp); - regtail(ret, tmp); - regoptail(tmp, ret); - regtail(ret, regnode(BRANCH)); - regtail(ret, regnode(NOTHING)); - } - - regparse++; - if (ISMULT(*regparse)) - FAIL("nested * or +"); - - return (ret); -} - - -/* - - regatom - the lowest level - * - * Optimization: gobbles an entire sequence of ordinary characters so that - * it can turn them into a single node, which is smaller to store and - * faster to run. - */ -static char *regatom(flagp) -int *flagp; -{ - register char *ret; - int flags; - - *flagp = WORST; /* Tentatively. */ - - switch (*regparse++) { - case CARET: - ret = regnode(BOL); - break; - case DOLLAR: - ret = regnode(EOL); - break; - case DOT: - ret = regnode(ANY); - *flagp |= HASWIDTH | SIMPLE; - break; - case LSHBRAC: - ret = regnode(WORDSTART); - break; - case RSHBRAC: - ret = regnode(WORDEND); - break; - case LSQBRAC:{ - register int class; - register int classend; - - if (*regparse == CARET) { /* Complement of range. */ - ret = regnode(ANYBUT); - regparse++; - } else - ret = regnode(ANYOF); - if (*regparse == RSQBRAC || *regparse == '-') - regc(*regparse++); - while (*regparse != '\0' && *regparse != RSQBRAC) { - if (*regparse == '-') { - regparse++; - if (*regparse == RSQBRAC || *regparse == '\0') - regc('-'); - else { - class = (CHARBITS & *(regparse - 2)) + 1; - classend = (CHARBITS & *(regparse)); - if (class > classend + 1) - FAIL("invalid [] range"); - for (; class <= classend; class++) - regc(class); - regparse++; - } - } else - regc(*regparse++); - } - regc('\0'); - if (*regparse != RSQBRAC) - FAIL("unmatched []"); - regparse++; - *flagp |= HASWIDTH | SIMPLE; - } - break; - case LBRAC: - ret = reg(1, &flags); - if (ret == (char *)NULL) - return ((char *)NULL); - *flagp |= flags & (HASWIDTH | SPSTART); - break; - case '\0': - case OR_OP: - case RBRAC: - FAIL("internal urp"); /* Supposed to be caught earlier. */ - - case ASTERIX: - FAIL("* follows nothing\n"); - - default:{ - register int len; - register short ender; - - regparse--; - for (len=0; regparse[len] && - !(regparse[len]&SPECIAL) && regparse[len] != RSQBRAC; len++) ; - if (len <= 0) - { - FAIL("internal disaster"); - } - ender = *(regparse + len); - if (len > 1 && ISMULT(ender)) - len--; /* Back off clear of * operand. */ - *flagp |= HASWIDTH; - if (len == 1) - *flagp |= SIMPLE; - ret = regnode(EXACTLY); - while (len > 0) { - regc(*regparse++); - len--; - } - regc('\0'); - } - break; - } - - return (ret); -} - -/* - - regnode - emit a node - */ -static char *regnode(op) -char op; -{ - register char *ret; - register char *ptr; - - ret = regcode; - if (ret == ®dummy) { - regsize += 3; - return (ret); - } - ptr = ret; - *ptr++ = op; - *ptr++ = '\0'; /* Null "nxt" pointer. */ - *ptr++ = '\0'; - regcode = ptr; - - return (ret); -} - -/* - - regc - emit (if appropriate) a byte of code - */ -static void regc(b) -char b; -{ - if (regcode != ®dummy) - *regcode++ = b; - else - regsize++; -} - -/* - - reginsert - insert an operator in front of already-emitted operand - * - * Means relocating the operand. - */ -static void reginsert(op, opnd) -char op; -char *opnd; -{ - register char *src; - register char *dst; - register char *place; - - if (regcode == ®dummy) { - regsize += 3; - return; - } - src = regcode; - regcode += 3; - dst = regcode; - while (src > opnd) - *--dst = *--src; - - place = opnd; /* Op node, where operand used to be. */ - *place++ = op; - *place++ = '\0'; - *place++ = '\0'; -} - -/* - - regtail - set the next-pointer at the end of a node chain - */ -static void regtail(p, val) -char *p; -char *val; -{ - register char *scan; - register char *temp; - register int offset; - - if (p == ®dummy) - return; - - /* Find last node. */ - scan = p; - for (;;) { - temp = regnext(scan); - if (temp == (char *)NULL) - break; - scan = temp; - } - - if (OP(scan) == BACK) - offset = scan - val; - else - offset = val - scan; - *(scan + 1) = (offset >> 8) & 0377; - *(scan + 2) = offset & 0377; -} - -/* - - regoptail - regtail on operand of first argument; nop if operandless - */ -static void regoptail(p, val) -char *p; -char *val; -{ - /* "Operandless" and "op != BRANCH" are synonymous in practice. */ - if (p == (char *)NULL || p == ®dummy || OP(p) != BRANCH) - return; - regtail(OPERAND(p), val); -} - -/* - * regexec and friends - */ - -/* - * Global work variables for regexec(). - */ -static char *reginput; /* String-input pointer. */ -static char *regbol; /* Beginning of input, for ^ check. */ -static char **regstartp; /* Pointer to startp array. */ -static char **regendp; /* Ditto for endp. */ - -/* - * Forwards. - */ -STATIC int regtry(); -STATIC int regmatch(); -STATIC int regrepeat(); - -#ifdef DEBUG -int regnarrate = 0; -void regdump(); -STATIC char *regprop(); -#endif - -/* - - regexec - match a regexp against a string - */ -int regexec(prog, string) -register regexp *prog; -register char *string; -{ - register char *s; - - /* Be paranoid... */ - if (prog == (regexp *)NULL || string == (char *)NULL) { - regerror("NULL parameter"); - return (0); - } - /* Check validity of program. */ - if (UCHARAT(prog->program) != MAGIC) { - regerror("corrupted program"); - return (0); - } - /* If there is a "must appear" string, look for it. */ - if (prog->regmust != (char *)NULL) { - s = string; - while ((s = STRCHR(s, prog->regmust[0])) != (char *)NULL) { - if (strncmp(s, prog->regmust, prog->regmlen) == 0) - break; /* Found it. */ - s++; - } - if (s == (char *)NULL) /* Not present. */ - return (0); - } - /* Mark beginning of line for ^ . */ - regbol = string; - - /* Simplest case: anchored match need be tried only once. */ - if (prog->reganch) - return (regtry(prog, string)); - - /* Messy cases: unanchored match. */ - s = string; - if (prog->regstart != '\0') - /* We know what char it must start with. */ - while ((s = STRCHR(s, prog->regstart)) != (char *)NULL) { - if (regtry(prog, s)) - return (1); - s++; - } - else - /* We don't -- general case. */ - do { - if (regtry(prog, s)) - return (1); - } while (*s++ != '\0'); - - /* Failure. */ - return (0); -} - -/* - - regtry - try match at specific point - */ -#ifdef __STDC__ - -static int regtry(regexp *prog, char *string) - -#else - -static int regtry(prog, string) -regexp *prog; -char *string; - -#endif -{ - register int i; - register char **sp; - register char **ep; - - reginput = string; - regstartp = prog->startp; - regendp = prog->endp; - - sp = prog->startp; - ep = prog->endp; - for (i = NSUBEXP; i > 0; i--) { - *sp++ = (char *)NULL; - *ep++ = (char *)NULL; - } - if (regmatch(prog->program + 1)) { - prog->startp[0] = string; - prog->endp[0] = reginput; - return (1); - } else - return (0); -} - -/* - - regmatch - main matching routine - * - * Conceptually the strategy is simple: check to see whether the current - * node matches, call self recursively to see whether the rest matches, - * and then act accordingly. In practice we make some effort to avoid - * recursion, in particular by going through "ordinary" nodes (that don't - * need to know whether the rest of the match failed) by a loop instead of - * by recursion. - */ -#ifdef __STDC__ - -static int regmatch(char *prog) - -#else - -static int regmatch(prog) -char *prog; - -#endif -{ - register char *scan; /* Current node. */ - char *nxt; /* nxt node. */ - - scan = prog; -#ifdef DEBUG - if (scan != (char *)NULL && regnarrate) - fprintf(stderr, "%s(\n", regprop(scan)); -#endif - while (scan != (char *)NULL) { -#ifdef DEBUG - if (regnarrate) - fprintf(stderr, "%s...\n", regprop(scan)); -#endif - nxt = regnext(scan); - - switch (OP(scan)) { - case BOL: - if (reginput != regbol) - return (0); - break; - case EOL: - if (*reginput != '\0') - return (0); - break; - case ANY: - if (*reginput == '\0') - return (0); - reginput++; - break; - case WORDSTART: - if (reginput == regbol) - break; - if (*reginput == '\0' || - ISWORDPART( *(reginput-1) ) || !ISWORDPART( *reginput ) ) - return (0); - break; - case WORDEND: - if (*reginput == '\0') - break; - if ( reginput == regbol || - !ISWORDPART( *(reginput-1) ) || ISWORDPART( *reginput ) ) - return (0); - break; - case EXACTLY:{ - register int len; - register char *opnd; - - opnd = OPERAND(scan); - /* Inline the first character, for speed. */ - if (*opnd != *reginput) - return (0); - len = strlen(opnd); - if (len > 1 && strncmp(opnd, reginput, len) != 0) - return (0); - reginput += len; - } - break; - case ANYOF: - if (*reginput == '\0' || - STRCHR(OPERAND(scan), *reginput) == (char *)NULL) - return (0); - reginput++; - break; - case ANYBUT: - if (*reginput == '\0' || - STRCHR(OPERAND(scan), *reginput) != (char *)NULL) - return (0); - reginput++; - break; - case NOTHING: - break; - case BACK: - break; - case OPEN + 1: - case OPEN + 2: - case OPEN + 3: - case OPEN + 4: - case OPEN + 5: - case OPEN + 6: - case OPEN + 7: - case OPEN + 8: - case OPEN + 9:{ - register int no; - register char *save; - - no = OP(scan) - OPEN; - save = reginput; - - if (regmatch(nxt)) { - /* - * Don't set startp if some later invocation of the same - * parentheses already has. - */ - if (regstartp[no] == (char *)NULL) - regstartp[no] = save; - return (1); - } else - return (0); - } - - case CLOSE + 1: - case CLOSE + 2: - case CLOSE + 3: - case CLOSE + 4: - case CLOSE + 5: - case CLOSE + 6: - case CLOSE + 7: - case CLOSE + 8: - case CLOSE + 9:{ - register int no; - register char *save; - - no = OP(scan) - CLOSE; - save = reginput; - - if (regmatch(nxt)) { - /* - * Don't set endp if some later invocation of the same - * parentheses already has. - */ - if (regendp[no] == (char *)NULL) - regendp[no] = save; - return (1); - } else - return (0); - } - - case BRANCH:{ - register char *save; - - if (OP(nxt) != BRANCH) /* No choice. */ - nxt = OPERAND(scan); /* Avoid recursion. */ - else { - do { - save = reginput; - if (regmatch(OPERAND(scan))) - return (1); - reginput = save; - scan = regnext(scan); - } while (scan != (char *)NULL && OP(scan) == BRANCH); - return (0); - /* NOTREACHED */ - } - } - break; - case STAR:{ - register char nextch; - register int no; - register char *save; - register int minimum; - - /* - * Lookahead to avoid useless match attempts when we know - * what character comes next. - */ - nextch = '\0'; - if (OP(nxt) == EXACTLY) - nextch = *OPERAND(nxt); - minimum = (OP(scan) == STAR) ? 0 : 1; - save = reginput; - no = regrepeat(OPERAND(scan)); - while (no >= minimum) { - /* If it could work, try it. */ - if (nextch == '\0' || *reginput == nextch) - if (regmatch(nxt)) - return (1); - /* Couldn't or didn't -- back up. */ - no--; - reginput = save + no; - } - return (0); - } - - case END: - return (1); /* Success! */ - - default: - regerror("memory corruption"); - return (0); - - } - - scan = nxt; - } - - /* - * We get here only if there's trouble -- normally "case END" is the - * terminating point. - */ - regerror("corrupted pointers"); - return (0); -} - -/* - - regrepeat - repeatedly match something simple, report how many - */ -#ifdef __STDC__ - -static int regrepeat(char *p) - -#else - -static int regrepeat(p) -char *p; - -#endif -{ - register int count = 0; - register char *scan; - register char *opnd; - - scan = reginput; - opnd = OPERAND(p); - switch (OP(p)) { - case ANY: - count = strlen(scan); - scan += count; - break; - case EXACTLY: - while (*opnd == *scan) { - count++; - scan++; - } - break; - case ANYOF: - while (*scan != '\0' && STRCHR(opnd, *scan) != (char *)NULL) { - count++; - scan++; - } - break; - case ANYBUT: - while (*scan != '\0' && STRCHR(opnd, *scan) == (char *)NULL) { - count++; - scan++; - } - break; - default: /* Oh dear. Called inappropriately. */ - regerror("internal foulup"); - count = 0; /* Best compromise. */ - break; - } - reginput = scan; - - return (count); -} - - -/* - - regnext - dig the "nxt" pointer out of a node - */ -#ifdef __STDC__ - -static char *regnext(register char *p) - -#else - -static char *regnext(p) -register char *p; - -#endif -{ - register int offset; - - if (p == ®dummy) - return ((char *)NULL); - - offset = NEXT(p); - if (offset == 0) - return ((char *)NULL); - - if (OP(p) == BACK) - return (p - offset); - else - return (p + offset); -} - -#ifdef DEBUG - -STATIC char *regprop(); - -/* - - regdump - dump a regexp onto stdout in vaguely comprehensible form - */ -#ifdef __STDC__ - -void regdump(regexp *r) - -#else - -void regdump(r) -regexp *r; - -#endif -{ - register char *s; - register char op = EXACTLY; /* Arbitrary non-END op. */ - register char *nxt; - - s = r->program + 1; - while (op != END) { /* While that wasn't END last time... */ - op = OP(s); - printf("%2ld%s", (long)(s - r->program), regprop(s)); /* Where, what. */ - nxt = regnext(s); - if (nxt == (char *)NULL) /* nxt ptr. */ - printf("(0)"); - else - printf("(%ld)", (long)( (s - r->program) + (nxt - s))); - s += 3; - if (op == ANYOF || op == ANYBUT || op == EXACTLY) { - /* Literal string, where present. */ - while (*s != '\0') { - putchar(*s); - s++; - } - s++; - } - putchar('\n'); - } - - /* Header fields of interest. */ - if (r->regstart != '\0') - printf("start `%c' ", r->regstart); - if (r->reganch) - printf("anchored "); - if (r->regmust != (char *)NULL) - printf("must have \"%s\"", r->regmust); - printf("\n"); -} - -/* - - regprop - printable representation of opcode - */ -#ifdef __STDC__ - -static char *regprop(char *op) - -#else - -static char *regprop(op) -char *op; - -#endif -{ - register char *p; - static char buf[50]; - - strcpy(buf, ":"); - - switch (OP(op)) { - case BOL: - p = "BOL"; - break; - case EOL: - p = "EOL"; - break; - case ANY: - p = "ANY"; - break; - case ANYOF: - p = "ANYOF"; - break; - case ANYBUT: - p = "ANYBUT"; - break; - case BRANCH: - p = "BRANCH"; - break; - case EXACTLY: - p = "EXACTLY"; - break; - case NOTHING: - p = "NOTHING"; - break; - case BACK: - p = "BACK"; - break; - case END: - p = "END"; - break; - case OPEN + 1: - case OPEN + 2: - case OPEN + 3: - case OPEN + 4: - case OPEN + 5: - case OPEN + 6: - case OPEN + 7: - case OPEN + 8: - case OPEN + 9: - sprintf(buf + strlen(buf), "OPEN%d", OP(op) - OPEN); - p = (char *)NULL; - break; - case CLOSE + 1: - case CLOSE + 2: - case CLOSE + 3: - case CLOSE + 4: - case CLOSE + 5: - case CLOSE + 6: - case CLOSE + 7: - case CLOSE + 8: - case CLOSE + 9: - sprintf(buf + strlen(buf), "CLOSE%d", OP(op) - CLOSE); - p = (char *)NULL; - break; - case STAR: - p = "STAR"; - break; - default: - regerror("corrupted opcode"); - p=(char *)NULL; - break; - } - if (p != (char *)NULL) - strcat(buf, p); - return (buf); -} -#endif - -/* - - regsub - perform substitutions after a regexp match - */ -#ifdef __STDC__ - -char *regsub(regexp *prog, char *source, char *dest, int n) - -#else - -char *regsub(prog, source, dest, n) -regexp *prog; -char *source; -char *dest; -int n; - -#endif -{ - register char *src; - register char *dst; - register char c; - register int no; - register int len; -#ifndef strncpy - extern char *strncpy(); -#endif - - if (prog == (regexp *)NULL || - source == (char *)NULL || dest == (char *)NULL) { - regerror("NULL parm to regsub"); - return NULL; - } - if (UCHARAT(prog->program) != MAGIC) { - regerror("damaged regexp fed to regsub"); - return NULL; - } - src = source; - dst = dest; - while ((c = *src++) != '\0') { - if (c == '&') - no = 0; - else if (c == '\\' && '0' <= *src && *src <= '9') - no = *src++ - '0'; - else - no = -1; - - if (no < 0) { /* Ordinary character. */ - if (c == '\\' && (*src == '\\' || *src == '&')) - c = *src++; - if (--n < 0) { /* amylaar */ - regerror("line too long"); - return NULL; - } - *dst++ = c; - } else if (prog->startp[no] != (char *)NULL && - prog->endp[no] != (char *)NULL) { - len = prog->endp[no] - prog->startp[no]; - if ( (n-=len) < 0 ) { /* amylaar */ - regerror("line too long"); - return NULL; - } - strncpy(dst, prog->startp[no], len); - dst += len; - if (len != 0 && *(dst - 1) == '\0') { /* strncpy hit NUL. */ - regerror("damaged match string"); - return NULL; - } - } - } - if (--n < 0) { /* amylaar */ - regerror("line too long"); - return NULL; - } - *dst = '\0'; - return dst; -} - - -#if 0 /* Use the local regerror() in ed.c */ -#ifdef __STDC__ - -void regerror(char *s) - -#else - -void regerror(s) -char *s; - -#endif -{ - fprintf(stderr, "regexp(3): %s", s); - exit(1); -} -#endif /* 0 */ diff --git a/src/modules/regexp/regexp.h b/src/modules/regexp/regexp.h deleted file mode 100644 index 5fa51439e9d3a849345c4e2039523083d5f85639..0000000000000000000000000000000000000000 --- a/src/modules/regexp/regexp.h +++ /dev/null @@ -1,33 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#ifndef REGEXP_H -#define REGEXP_H -/* - * Definitions etc. for regexp(3) routines. - * - * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], - * not the System V one. - */ - -#define NSUBEXP 40 -typedef struct regexp -{ - char *startp[NSUBEXP]; - char *endp[NSUBEXP]; - char regstart; /* Internal use only. */ - char reganch; /* Internal use only. */ - char *regmust; /* Internal use only. */ - int regmlen; /* Internal use only. */ - char program[1]; /* Unwarranted chumminess with compiler. */ -} regexp; - - - -extern regexp *regcomp(); -extern int regexec(); -extern char *regsub(); -extern void regerror(); -#endif diff --git a/src/modules/regexp/testsuite.in b/src/modules/regexp/testsuite.in deleted file mode 100644 index 860677c2d6213fea4919fdb35d610dd014501cbc..0000000000000000000000000000000000000000 --- a/src/modules/regexp/testsuite.in +++ /dev/null @@ -1,33 +0,0 @@ -// - Here we try the regexp module -test_true(programp((program)"/precompiled/regexp")) -test_any(object o; o=clone((program)"/precompiled/regexp"); destruct(o); return 1,1) - -// regexp->create -test_any(object o; o=clone((program)"/precompiled/regexp","^.*$"); destruct(o); return 1,1) - -// regexp->match -test_eq(clone((program)"/precompiled/regexp","^.*$")->match(""),1) -test_eq(clone((program)"/precompiled/regexp","^.*$")->match("a"),1) -test_eq(clone((program)"/precompiled/regexp","^.*$")->match("-"),1) -test_eq(clone((program)"/precompiled/regexp","^$")->match(""),1) -test_eq(clone((program)"/precompiled/regexp","^.$")->match("a"),1) -test_eq(clone((program)"/precompiled/regexp","^.$")->match("-"),1) -test_eq(clone((program)"/precompiled/regexp","^[abc]$")->match("-"),0) -test_eq(clone((program)"/precompiled/regexp","^[abc]$")->match("a"),1) -test_eq(clone((program)"/precompiled/regexp","^[abc]$")->match("c"),1) -test_eq(clone((program)"/precompiled/regexp","^[^abc]$")->match("-"),1) -test_eq(clone((program)"/precompiled/regexp","^[^abc]$")->match("a"),0) -test_eq(clone((program)"/precompiled/regexp","^[^abc]$")->match("c"),0) -test_eq(clone((program)"/precompiled/regexp","^a*$")->match("aaaa"),1) -test_eq(clone((program)"/precompiled/regexp","^(a|bb)*$")->match("aabbabb"),1) -test_eq(clone((program)"/precompiled/regexp","^(a|bb)*$")->match(""),1) -test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match(""),0) -test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match("aaa"),1) -test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match("bbb"),0) -test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match("bbaabba"),1) -test_eq(clone((program)"/precompiled/regexp","^a|b$")->match("a"),1) -test_eq(clone((program)"/precompiled/regexp","^a|b$")->match("b"),1) - -// regexp->split -test_equal(clone((program)"/precompiled/regexp","^(a*)[^a]*$")->split("aaabbb"),({"aaa"})) - diff --git a/src/modules/ssleay/.cvsignore b/src/modules/ssleay/.cvsignore deleted file mode 100644 index c0bdcf80041cb0f78811b96239afcd83ff815c06..0000000000000000000000000000000000000000 --- a/src/modules/ssleay/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.pure -Makefile -config.log -config.status -configure -dependencies -linker_options -stamp-h diff --git a/src/modules/ssleay/.gitignore b/src/modules/ssleay/.gitignore deleted file mode 100644 index 7ed24cbd425f9796f4d1a7b2a62674aa61cf4353..0000000000000000000000000000000000000000 --- a/src/modules/ssleay/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/.pure -/Makefile -/config.log -/config.status -/configure -/dependencies -/linker_options -/stamp-h diff --git a/src/modules/ssleay/Makefile.in b/src/modules/ssleay/Makefile.in deleted file mode 100644 index 03ef9ccd3254f8908ade770b9461f417c89c36b6..0000000000000000000000000000000000000000 --- a/src/modules/ssleay/Makefile.in +++ /dev/null @@ -1,9 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -MODULE_CLAGS=@DEFS@ @CPPFLAGS@ -OBJS=ssleay.o -MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ - -@dynamic_module_makefile@ -@dependencies@ - diff --git a/src/modules/ssleay/configure.in b/src/modules/ssleay/configure.in deleted file mode 100644 index dedd922090f9bce519a760d803e963ca3327c34a..0000000000000000000000000000000000000000 --- a/src/modules/ssleay/configure.in +++ /dev/null @@ -1,61 +0,0 @@ -AC_INIT(ssleay.c) - -sinclude(../module_configure.in) - -AC_ARG_WITH(ssleay, [ --without-ssleay no support for the secure socket protocol],[],[with_ssleay=yes]) - -if test x$with_ssleay = xyes; then - OLD_LDFLAGS=$LDFLAGS - OLD_CPPFLAGS=$CPPFLAGS - OLD_LIBS=$LIBS - - AC_MSG_CHECKING(Checking for existance of SSLeay) - - AC_CACHE_VAL(pike_cv_ssleay_exists, - [ - if test -d /usr/local/ssl ; then - pike_cv_ssleay_exists="yes" - else - pike_cv_ssleay_exists="no" - fi - ]) - - AC_MSG_RESULT($pike_cv_ssleay_exists) - - if test x$pike_cv_ssleay_exists = xyes; then - - if test -d /usr/local/ssl/lib ; then - echo Added /usr/local/ssl/lib to the library search path. - LDFLAGS="-L/usr/local/ssl/lib ${LDFLAGS}" - # link with libc first, so we get the right definition - # of crypt() - LDFLAGS="-lc ${LDFLAGS}" - fi - - if test -d /usr/local/ssl/include ; then - echo Added /usr/local/ssl/include to the include search path. - CPPFLAGS="-I/usr/local/ssl/include ${CPPFLAGS}" - fi - - pike_cv_ssleay="yes" - - AC_CHECK_LIB(crypto, ERR_print_errors_fp, [], [ pike_cv_ssleay="no" ]) - AC_CHECK_LIB(ssl, SSL_use_PrivateKey_file, [], [ pike_cv_ssleay="no" ]) - - AC_MSG_CHECKING(Supported version of SSLeay) - - AC_MSG_RESULT($pike_cv_ssleay) - - if test x$pike_cv_ssleay = xyes; then - AC_DEFINE(HAVE_SSLEAY) - else - # Restore variables, so we don't link with unnessesary libs - - LIBS=$OLD_LIBS - CPPFLAGS=$OLD_CPPFLAGS - LDFLAGS=$OLD_LDFLAGS - fi - fi -fi - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) diff --git a/src/modules/ssleay/ssleay.c b/src/modules/ssleay/ssleay.c deleted file mode 100644 index 6c9bc50da078ea4188dc32d8ae869a6c0d4d91a6..0000000000000000000000000000000000000000 --- a/src/modules/ssleay/ssleay.c +++ /dev/null @@ -1,313 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ - -#include "global.h" -RCSID("$Id: ssleay.c,v 1.9 1997/02/07 00:45:45 hubbe Exp $"); -#include "types.h" -#include "interpret.h" -#include "svalue.h" -#include "stralloc.h" -#include "array.h" -#include "object.h" -#include "macros.h" -#include "backend.h" -#include "program.h" -#include "threads.h" - -#ifdef HAVE_SYS_TYPE_H -#include <sys/types.h> -#endif - -#ifdef HAVE_SSLEAY - -#include <ssl.h> -#include <crypto.h> -#include <pem.h> -#include <err.h> -#include <x509.h> - -/* SSLeay defines _ as a macro. That's Puckat(TM). */ -#undef _ - -struct ssleay_context -{ - SSL_CTX *shared; -}; - -struct ssleay_connection -{ - SSL *con; -}; - - -#define THISOBJ (fp->current_object) -#define CON (((struct ssleay_connection *) (fp->current_storage))->con) -#define CTX (((struct ssleay_context *) (fp->current_storage))->shared) - -#endif /* HAVE_SSLEAY */ - -static struct program *ssleay_program; -static struct program *ssleay_connection_program; - -#ifdef HAVE_SSLEAY - -/* Methods for ssleay_connection objects */ - -/* Arg is an ssleay object */ -void ssleay_connection_create(INT32 args) -{ - if (args < 1) - error("ssleay_connection->create: no context given\n"); - if ((sp[-args].type != T_OBJECT) - || (sp[-args].u.object->prog != ssleay_program)) - error("ssleay_connection->create: invalid argument\n"); - if (CON) - SSL_free(CON); - CON = SSL_new( ( (struct ssleay_context *) sp[-args].u.object->storage) - -> shared); - if (!CON) - { - ERR_print_errors_fp(stderr); - error("ssleay_connection->create: Could not allocate new connection\n"); - } - SSL_clear(CON); -} - -void ssleay_connection_set_fd(INT32 args) -{ - if ((args < 1) || (sp[-args].type != T_INT)) - error("ssleay_connection->set_fd: wrong type\n"); - SSL_set_fd(CON, sp[-args].u.integer); - pop_n_elems(args); -} - -void ssleay_connection_accept(INT32 args) -{ - int res; - - pop_n_elems(args); - THREADS_ALLOW(); - res = SSL_accept(CON); - THREADS_DISALLOW(); - push_int(res); -} - -void ssleay_connection_read(INT32 args) -{ - struct pike_string *s; - INT32 len; - INT32 count; - - if ((args < 1) || (sp[-args].type != T_INT)) - error("ssleay_connection->read: wrong type\n"); - len = sp[-args].u.integer; - - if (len < 0) - error("ssleay_connection->read: invalid argument\n"); - pop_n_elems(args); - - s = begin_shared_string(len); - if (len) - { - THREADS_ALLOW(); - count = SSL_read(CON, s->str, len); - THREADS_DISALLOW(); - if (count < 0) - { - free_string(end_shared_string(s)); - push_int(count); - } - else - { - s->len = count; - push_string(end_shared_string(s)); - } - } -} - -void ssleay_connection_write(INT32 args) -{ - INT32 res; - - if ((args < 1) || (sp[-args].type != T_STRING)) - error("ssleay_connection->write: wrong argument\n"); - THREADS_ALLOW(); - res = SSL_write(CON, sp[-args].u.string->str, sp[-args].u.string->len); - THREADS_DISALLOW(); - pop_n_elems(args); - push_int(res); -} - -void ssleay_connection_werror(INT32 args) -{ - ERR_print_errors_fp(stderr); - pop_n_elems(args); -} - -/* Methods for ssleay context objects */ - -static void ssleay_create(INT32 args) -{ - if (CTX) - SSL_CTX_free(CTX); - CTX = SSL_CTX_new(); - if (!CTX) - error("ssleay->create: couldn't allocate new ssl context\n"); - pop_n_elems(args); -} - -static void ssleay_use_certificate_file(INT32 args) -{ - if (sp[-args].type != T_STRING) - error("ssleay->use_certificate_file: wrong type"); - if (SSL_CTX_use_certificate_file(CTX, sp[-args].u.string->str, SSL_FILETYPE_PEM) <= 0) - { - ERR_print_errors_fp(stderr); - error("ssleay->use_certificate_file: unable to use certificate"); - } - pop_n_elems(args); -} - -static void ssleay_use_private_key_file(INT32 args) -{ - if (sp[-args].type != T_STRING) - error("ssleay->use_private_key_file: wrong type"); - if (SSL_CTX_use_PrivateKey_file(CTX, sp[-args].u.string->str, SSL_FILETYPE_PEM) <= 0) - { - ERR_print_errors_fp(stderr); - error("ssleay->use_private_key_file: unable to use private_key\n"); - } - pop_n_elems(args); -} - -/* open(int fd, string mode) where mode is "s" for server - * or "c" for client */ -static void ssleay_new(INT32 args) -{ - struct object *res; - -#if 0 - if (strcmp(sp[-args+1].u.string->str, "s") == 0) - is_server = 1; - else - { - if (strcmp(sp[-args+1].u.string->str, "c") == 0) - error("ssleay->open: client mode not implemented\n") - else - error("ssleay->open: invalid mode\n"); - } -#endif - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); - push_object(clone(ssleay_connection_program, 1)); -} - - -/* Thread stuff */ -#ifdef _REENTRANT - -static MUTEX_T ssleay_locks[CRYPTO_NUM_LOCKS]; - -static void ssleay_locking_callback(int mode, int type, char *file, int line) -{ - if (mode & CRYPTO_LOCK) - mt_lock(ssleay_locks + type); - else - mt_unlock(ssleay_locks + type); -} - -static unsigned long ssleay_thread_id(void) -{ - return th_self(); -} - -static void ssleay_init_threads() -{ - int i; - for (i = 0; i<CRYPTO_NUM_LOCKS; i++) - mt_init(ssleay_locks + i); - CRYPTO_set_id_callback(ssleay_thread_id); - CRYPTO_set_locking_callback(ssleay_locking_callback); -} -#endif /* _REENTRANT */ - -/* Initializing etc */ -void init_context(struct object *o) -{ - CTX = NULL; -} - -void exit_context(struct object *o) -{ - if (CTX) - SSL_CTX_free(CTX); -} - -void init_connection(struct object *o) -{ - CON = NULL; -} - -void exit_connection(struct object *o) -{ - if (CON) - SSL_free(CON); -} - -#endif /* HAVE_SSLEAY */ - -void pike_module_exit() -{ -#ifdef HAVE_SSLEAY - free_program(ssleay_connection_program); - free_program(ssleay_program); - ssleay_connection_program=0; - ssleay_program=0; -#endif -} - -void pike_module_init(void) -{ -#ifdef HAVE_SSLEAY - ERR_load_ERR_strings(); - ERR_load_SSL_strings(); - ERR_load_crypto_strings(); -#ifdef _REENTRANT - ssleay_init_threads(); -#endif /* _REENTRANT */ - start_new_program(); - add_storage(sizeof(struct ssleay_context)); - - add_function("create", ssleay_create, "function(void:void)",0); - add_function("use_certificate_file", ssleay_use_certificate_file, "function(string:void)", 0); - add_function("use_private_key_file", ssleay_use_private_key_file, "function(string:void)", 0); - add_function("new", ssleay_new, "function(void:object)", 0); - - set_init_callback(init_context); - set_exit_callback(exit_context); - - ssleay_program=end_program(); - add_program_constant("ssleay",ssleay_program); - - start_new_program(); - add_storage(sizeof(struct ssleay_connection)); - - add_function("create", ssleay_connection_create, "function(object:void)",0); - add_function("accept", ssleay_connection_accept, "function(void:int)", 0); - add_function("read",ssleay_connection_read,"function(int,int|void:int|string)",0); - add_function("write",ssleay_connection_write,"function(string:int)",0); - add_function("set_fd",ssleay_connection_set_fd,"function(int:void)",0); - add_function("ssleay_werror", ssleay_connection_werror, "function(void:void)", 0); - set_init_callback(init_connection); - set_exit_callback(exit_connection); - - ssleay_connection_program=end_program(); - add_program_constant("connection",ssleay_program); -#endif /* HAVE_SSLEAY */ -} - - diff --git a/src/modules/zlibmod/.cvsignore b/src/modules/zlibmod/.cvsignore deleted file mode 100644 index b60f1913a1ded943910c93507177d28ab055c55c..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.pure -Makefile -config.log -config.status -configure -dependencies -linker_options -stamp-h -zlib_machine.h diff --git a/src/modules/zlibmod/.gitignore b/src/modules/zlibmod/.gitignore deleted file mode 100644 index f4cfce0a1e458466cce958d18029e91a3f73c208..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.pure -/Makefile -/config.log -/config.status -/configure -/dependencies -/linker_options -/stamp-h -/zlib_machine.h diff --git a/src/modules/zlibmod/Makefile.in b/src/modules/zlibmod/Makefile.in deleted file mode 100644 index 77326ae1469f9fd62b7ee2669ea147482d594afc..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/Makefile.in +++ /dev/null @@ -1,7 +0,0 @@ -SRCDIR=@srcdir@ -VPATH=@srcdir@:@srcdir@/../..:../.. -OBJS=zlibmod.o -MODULE_LDFLAGS=@LIBS@ - -@static_module_makefile@ -@dependencies@ diff --git a/src/modules/zlibmod/configure.in b/src/modules/zlibmod/configure.in deleted file mode 100644 index 4576722861dd7696625c27fd835ae06a51a20b63..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/configure.in +++ /dev/null @@ -1,17 +0,0 @@ -AC_INIT(zlibmod.c) -AC_CONFIG_HEADER(zlib_machine.h) -AC_ARG_WITH(zlib, [ --with(out)-zlib Support gzip compression],[],[with_zlib=yes]) - -sinclude(../module_configure.in) - -if test x$with_zlib = xyes ; then - AC_CHECK_HEADERS(zlib.h) - if test $ac_cv_header_zlib_h = yes ; then - AC_CHECK_LIB(z, compress, [[LIBS="${LIBS-} -lz"]], - AC_CHECK_LIB(gz, compress)) - fi -fi - -AC_OUTPUT(Makefile,echo FOO >stamp-h ) - - diff --git a/src/modules/zlibmod/testsuite.in b/src/modules/zlibmod/testsuite.in deleted file mode 100644 index fdc03eb7f782e65352f30754796b29a963041b48..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/testsuite.in +++ /dev/null @@ -1,17 +0,0 @@ -cond([[ master()->programs["/precompiled/gz_inflate"] ]], -[[ - test_true(Gz_deflate()) - test_true(Gz_deflate()->deflate) - test_true(Gz_inflate()) - test_true(Gz_inflate()->inflate) -define(dotest,[[ - test_true(Gz_deflate(1)->deflate($1)) - test_eq(Gz_inflate()->inflate(Gz_deflate(1)->deflate($1)),$1) - test_eq(Gz_inflate()->inflate(Gz_deflate(9)->deflate($1)),$1) - test_any([[object o=Gz_deflate(); return Gz_inflate()->inflate(o->deflate($1,o->PARTIAL_FLUSH) + o->deflate($1,o->FINISH))]], [[($1)+($1)]]) -]]) - dotest("") - dotest("foo") - dotest(sprintf("%'fomp'1000n")) - dotest(sprintf("%'fomp'100000n")) -]]) diff --git a/src/modules/zlibmod/zlib_machine.h.in b/src/modules/zlibmod/zlib_machine.h.in deleted file mode 100644 index 7751a13fcd8c43413bf8bea820c72dfc7e0659ea..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/zlib_machine.h.in +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef GMP_MACHINE_H -#define GMP_MACHINE_H - -/* Define this if you have <libz.h> */ -#undef HAVE_ZLIB_H - -/* Define this if you have -lz */ -#undef HAVE_LIBZ - -/* Define this if you have -lgz */ -#undef HAVE_LIBGZ - -#endif diff --git a/src/modules/zlibmod/zlibmod.c b/src/modules/zlibmod/zlibmod.c deleted file mode 100644 index d1e557d1c732096c9593264d27438dee36c49967..0000000000000000000000000000000000000000 --- a/src/modules/zlibmod/zlibmod.c +++ /dev/null @@ -1,373 +0,0 @@ -/*\ -||| This file a part of Pike, and is copyright by Fredrik Hubinette -||| Pike is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#include "global.h" -RCSID("$Id: zlibmod.c,v 1.3 1997/02/07 00:46:53 hubbe Exp $"); - -#include "zlib_machine.h" -#include "types.h" - -#if !defined(HAVE_LIBZ) && !defined(HAVE_LIBGZ) -#undef HAVE_ZLIB_H -#endif - -#ifdef HAVE_ZLIB_H - -#include "interpret.h" -#include "svalue.h" -#include "stralloc.h" -#include "array.h" -#include "macros.h" -#include "program.h" -#include "stralloc.h" -#include "object.h" -#include "pike_types.h" -#include "threads.h" -#include "dynamic_buffer.h" - -#include <zlib.h> - -struct zipper -{ - struct z_stream_s gz; - DEFINE_MUTEX(lock); -}; - -#define BUF 16384 - -#define THIS ((struct zipper *)(fp->current_storage)) - -static void gz_deflate_create(INT32 args) -{ - int level=Z_DEFAULT_COMPRESSION; - - if(THIS->gz.state) - { - mt_lock(& this->lock); - deflateEnd(&THIS->gz); - mt_unlock(& this->lock); - } - - if(args) - { - if(sp[-args].type != T_INT) - error("Bad argument 1 to gz->create()\n"); - if(sp[-args].u.integer < Z_NO_COMPRESSION || - sp[-args].u.integer > Z_BEST_COMPRESSION) - { - error("Compression level out of range for gz_deflate->create()\n"); - } - } - - THIS->gz.zalloc=Z_NULL; - THIS->gz.zfree=Z_NULL; - THIS->gz.opaque=THIS; - - pop_n_elems(args); - mt_lock(& THIS->lock); - level=deflateInit(&THIS->gz, level); - mt_unlock(& THIS->lock); - switch(level) - { - case Z_OK: - return; - - case Z_VERSION_ERROR: - error("libz not compatible with zlib.h!!!\n"); - break; - - default: - if(THIS->gz.msg) - error("Failed to initialize gz_deflate: %s\n",THIS->gz.msg); - else - error("Failed to initialize gz_deflate\n"); - } -} - -static int do_deflate(dynamic_buffer *buf, - struct zipper *this, - int flush) -{ - int fail=0; - - THREADS_ALLOW(); - mt_lock(& this->lock); - if(!this->gz.state) - { - fail=Z_STREAM_ERROR; - }else{ - do - { - char *loc; - int ret; - loc=low_make_buf_space(BUF,buf); - this->gz.next_out=(Bytef *)loc; - this->gz.avail_out=BUF; - ret=deflate(& this->gz, flush); - low_make_buf_space(-this->gz.avail_out,buf); - if(ret != Z_OK) - { - fail=ret; - break; - } - } while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in); - } - - mt_unlock(& this->lock); - THREADS_DISALLOW(); - return fail; -} - -static void gz_deflate(INT32 args) -{ - struct pike_string *data; - int flush, fail; - struct zipper *this=THIS; - dynamic_buffer buf; - - if(!THIS->gz.state) - error("gz_deflate not initialized or destructed\n"); - - initialize_buf(&buf); - - if(args<1) - error("Too few arguments to gz_deflate->deflate()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gz_deflate->deflate()\n"); - - data=sp[-args].u.string; - - if(args>1) - { - if(sp[1-args].type != T_INT) - error("Bad argument 2 to gz_deflate->deflate()\n"); - - flush=sp[1-args].u.integer; - - switch(flush) - { - case Z_PARTIAL_FLUSH: - case Z_FINISH: - case Z_SYNC_FLUSH: - case Z_NO_FLUSH: - break; - - defualt: - error("Argument 2 to gz_deflate->deflate() out of range.\n"); - } - }else{ - flush=Z_FINISH; - } - - this->gz.next_in=(Bytef *)data->str; - this->gz.avail_in=data->len; - - fail=do_deflate(&buf,this,flush); - pop_n_elems(args); - - if(fail != Z_OK && fail != Z_STREAM_END) - { - free(buf.s.str); - if(THIS->gz.msg) - error("Error in gz_deflate->deflate(): %s\n",THIS->gz.msg); - else - error("Error in gz_deflate->deflate(): %d\n",fail); - } - - push_string(low_free_buf(&buf)); -} - - -static void init_gz_deflate(struct object *o) -{ - mt_init(& THIS->locked); - MEMSET(& THIS->gz, 0, sizeof(THIS->gz)); - THIS->gz.zalloc=Z_NULL; - THIS->gz.zfree=Z_NULL; - THIS->gz.opaque=THIS; - deflateInit(& THIS->gz, Z_DEFAULT_COMPRESSION); -} - -static void exit_gz_deflate(struct object *o) -{ - mt_lock(& THIS->lock); - deflateEnd(&THIS->gz); - mt_unlock(& THIS->lock); -} - -/*******************************************************************/ - - -static void gz_inflate_create(INT32 args) -{ - int tmp; - if(THIS->gz.state) - { - mt_lock(this->lock); - inflateEnd(&THIS->gz); - mt_unlock(this->lock); - } - - - THIS->gz.zalloc=Z_NULL; - THIS->gz.zfree=Z_NULL; - THIS->gz.opaque=THIS; - - pop_n_elems(args); - mt_lock(THIS->lock); - tmp=inflateInit(& THIS->gz); - mt_unlock(THIS->lock); - switch(tmp) - { - case Z_OK: - return; - - case Z_VERSION_ERROR: - error("libz not compatible with zlib.h!!!\n"); - break; - - default: - if(THIS->gz.msg) - error("Failed to initialize gz_inflate: %s\n",THIS->gz.msg); - else - error("Failed to initialize gz_inflate\n"); - } -} - -static int do_inflate(dynamic_buffer *buf, - struct zipper *this, - int flush) -{ - int fail=0; - - THREADS_ALLOW(); - mt_lock(this->lock); - if(!this->gz.state) - { - fail=Z_STREAM_ERROR; - }else{ - do - { - char *loc; - int ret; - loc=low_make_buf_space(BUF,buf); - this->gz.next_out=(Bytef *)loc; - this->gz.avail_out=BUF; - ret=inflate(& this->gz, flush); - low_make_buf_space(-this->gz.avail_out,buf); - if(ret != Z_OK) - { - fail=ret; - break; - } - } while(!this->gz.avail_out || flush==Z_FINISH || this->gz.avail_in); - } - mt_unlock(this->lock); - THREADS_DISALLOW(); - return fail; -} - -static void gz_inflate(INT32 args) -{ - struct pike_string *data; - int fail; - struct zipper *this=THIS; - dynamic_buffer buf; - - if(!THIS->gz.state) - error("gz_inflate not initialized or destructed\n"); - - initialize_buf(&buf); - - if(args<1) - error("Too few arguments to gz_inflate->inflate()\n"); - - if(sp[-args].type != T_STRING) - error("Bad argument 1 to gz_inflate->inflate()\n"); - - data=sp[-args].u.string; - - this->gz.next_in=(Bytef *)data->str; - this->gz.avail_in=data->len; - - fail=do_inflate(&buf,this,Z_PARTIAL_FLUSH); - pop_n_elems(args); - - if(fail != Z_OK && fail != Z_STREAM_END) - { - free(buf.s.str); - if(THIS->gz.msg) - error("Error in gz_inflate->inflate(): %s\n",THIS->gz.msg); - else - error("Error in gz_inflate->inflate(): %d\n",fail); - } - push_string(low_free_buf(&buf)); - if(fail != Z_STREAM_END && fail!=Z_OK && !sp[-1].u.string->len) - { - pop_stack(); - push_int(0); - } -} - -static void init_gz_inflate(struct object *o) -{ - mt_init(THIS->locked); - MEMSET(& THIS->gz, 0, sizeof(THIS->gz)); - THIS->gz.zalloc=Z_NULL; - THIS->gz.zfree=Z_NULL; - THIS->gz.opaque=0; - inflateInit(&THIS->gz); - inflateEnd(&THIS->gz); -} - -static void exit_gz_inflate(struct object *o) -{ - mt_lock(& THIS->lock); - inflateEnd(& THIS->gz); - mt_unlock(& THIS->lock); -} - -#endif - -void pike_module_exit(void) {} - -void pike_module_init(void) -{ -#ifdef HAVE_ZLIB_H - start_new_program(); - add_storage(sizeof(struct zipper)); - - add_function("create",gz_deflate_create,"function(int|void:void)",0); - add_function("deflate",gz_deflate,"function(string,int|void:string)",0); - - add_integer_constant("NO_FLUSH",Z_NO_FLUSH,0); - add_integer_constant("PARTIAL_FLUSH",Z_PARTIAL_FLUSH,0); - add_integer_constant("SYNC_FLUSH",Z_SYNC_FLUSH,0); - add_integer_constant("FINISH",Z_FINISH,0); - - set_init_callback(init_gz_deflate); - set_exit_callback(exit_gz_deflate); - - end_class("deflate"); - - start_new_program(); - add_storage(sizeof(struct zipper)); - - add_function("create",gz_inflate_create,"function(int|void:void)",0); - add_function("inflate",gz_inflate,"function(string:string)",0); - - add_integer_constant("NO_FLUSH",Z_NO_FLUSH,0); - add_integer_constant("PARTIAL_FLUSH",Z_PARTIAL_FLUSH,0); - add_integer_constant("SYNC_FLUSH",Z_SYNC_FLUSH,0); - add_integer_constant("FINISH",Z_FINISH,0); - - set_init_callback(init_gz_inflate); - set_exit_callback(exit_gz_inflate); - - end_class("inflate"); -#endif -} -