From f9fb3941f8211e190c4b139819056c872112e6ac Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 2 Dec 2002 23:39:26 +0000 Subject: [PATCH] move eet to HEAD SVN revision: 6469 --- legacy/eet/.cvsignore | 2 + legacy/eet/ChangeLog | 0 legacy/eet/INSTALL | 14 + legacy/eet/Makefile.am | 10 + legacy/eet/NEWS | 0 legacy/eet/acconfig.h | 3 + legacy/eet/autogen.sh | 137 +++ legacy/eet/configure.ac | 75 ++ legacy/eet/configure.in | 75 ++ legacy/eet/debian/.cvsignore | 7 + legacy/eet/debian/changelog | 6 + legacy/eet/debian/control | 29 + legacy/eet/debian/copyright | 32 + legacy/eet/debian/eet-config.1 | 27 + legacy/eet/debian/eet.1 | 61 + legacy/eet/debian/libeet0-dev.files | 4 + legacy/eet/debian/libeet0.files | 2 + legacy/eet/debian/rules | 74 ++ legacy/eet/eet-config.in | 59 + legacy/eet/eet.spec | 63 + legacy/eet/src/.cvsignore | 3 + legacy/eet/src/Makefile.am | 3 + legacy/eet/src/bin/.cvsignore | 3 + legacy/eet/src/bin/Makefile.am | 12 + legacy/eet/src/bin/eet_main.c | 420 +++++++ legacy/eet/src/lib/.cvsignore | 3 + legacy/eet/src/lib/Eet.h | 268 ++++ legacy/eet/src/lib/Makefile.am | 20 + legacy/eet/src/lib/eet_data.c | 1765 +++++++++++++++++++++++++++ legacy/eet/src/lib/eet_lib.c | 889 ++++++++++++++ 30 files changed, 4066 insertions(+) create mode 100644 legacy/eet/.cvsignore create mode 100644 legacy/eet/ChangeLog create mode 100644 legacy/eet/INSTALL create mode 100644 legacy/eet/Makefile.am create mode 100644 legacy/eet/NEWS create mode 100644 legacy/eet/acconfig.h create mode 100755 legacy/eet/autogen.sh create mode 100644 legacy/eet/configure.ac create mode 100644 legacy/eet/configure.in create mode 100644 legacy/eet/debian/.cvsignore create mode 100644 legacy/eet/debian/changelog create mode 100644 legacy/eet/debian/control create mode 100644 legacy/eet/debian/copyright create mode 100644 legacy/eet/debian/eet-config.1 create mode 100644 legacy/eet/debian/eet.1 create mode 100644 legacy/eet/debian/libeet0-dev.files create mode 100644 legacy/eet/debian/libeet0.files create mode 100644 legacy/eet/debian/rules create mode 100644 legacy/eet/eet-config.in create mode 100644 legacy/eet/eet.spec create mode 100644 legacy/eet/src/.cvsignore create mode 100644 legacy/eet/src/Makefile.am create mode 100644 legacy/eet/src/bin/.cvsignore create mode 100644 legacy/eet/src/bin/Makefile.am create mode 100644 legacy/eet/src/bin/eet_main.c create mode 100644 legacy/eet/src/lib/.cvsignore create mode 100644 legacy/eet/src/lib/Eet.h create mode 100644 legacy/eet/src/lib/Makefile.am create mode 100644 legacy/eet/src/lib/eet_data.c create mode 100644 legacy/eet/src/lib/eet_lib.c diff --git a/legacy/eet/.cvsignore b/legacy/eet/.cvsignore new file mode 100644 index 0000000000..2b9156e6be --- /dev/null +++ b/legacy/eet/.cvsignore @@ -0,0 +1,2 @@ +.config +build-stamp diff --git a/legacy/eet/ChangeLog b/legacy/eet/ChangeLog new file mode 100644 index 0000000000..e69de29bb2 diff --git a/legacy/eet/INSTALL b/legacy/eet/INSTALL new file mode 100644 index 0000000000..3a3ad7ed8f --- /dev/null +++ b/legacy/eet/INSTALL @@ -0,0 +1,14 @@ +COMPILING and INSTALLING: + +If you got a official release tar archive do: + ./configure + +( otherwise if you got this from enlightenment cvs do: ./autogen.sh ) + +Then to compile: + make + +To install (run this as root, or the user who handles installs): + make install + +NOTE: You MUST make install Eet for it to run properly. diff --git a/legacy/eet/Makefile.am b/legacy/eet/Makefile.am new file mode 100644 index 0000000000..7e766defc9 --- /dev/null +++ b/legacy/eet/Makefile.am @@ -0,0 +1,10 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = src + +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \ + config.h.in config.sub configure install-sh \ + ltconfig ltmain.sh missing mkinstalldirs \ + stamp-h.in + +EXTRA_DIST = README AUTHORS COPYING eet.spec diff --git a/legacy/eet/NEWS b/legacy/eet/NEWS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/legacy/eet/acconfig.h b/legacy/eet/acconfig.h new file mode 100644 index 0000000000..bd2bb91752 --- /dev/null +++ b/legacy/eet/acconfig.h @@ -0,0 +1,3 @@ +#undef PACKAGE_SOURCE_DIR +#undef PACKAGE_BIN_DIR +#undef PACKAGE_LIB_DIR diff --git a/legacy/eet/autogen.sh b/legacy/eet/autogen.sh new file mode 100755 index 0000000000..9226176c74 --- /dev/null +++ b/legacy/eet/autogen.sh @@ -0,0 +1,137 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +PKG_NAME="the package." + +DIE=0 + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`autoconf' installed to." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && { + (libtool --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`libtool' installed." + echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + } +} + +grep "^AM_GNU_GETTEXT" $srcdir/configure.in >/dev/null && { + grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \ + (gettext --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`gettext' installed." + echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + } +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`automake' installed." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + NO_AUTOMAKE=yes +} + + +# if no automake, don't bother testing for aclocal +test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing \`aclocal'. The version of \`automake'" + echo "installed doesn't appear recent enough." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test -z "$*"; then + echo "**Warning**: I am going to run \`configure' with no arguments." + echo "If you wish to pass any to it, please specify them on the" + echo \`$0\'" command line." + echo +fi + +case $CC in +xlc ) + am_opt=--include-deps;; +esac + +for coin in `find $srcdir -name configure.in -print` +do + dr=`dirname $coin` + if test -f $dr/NO-AUTO-GEN; then + echo skipping $dr -- flagged as no auto-gen + else + echo processing $dr + macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin` + ( cd $dr + aclocalinclude="$ACLOCAL_FLAGS" + for k in $macrodirs; do + if test -d $k; then + aclocalinclude="$aclocalinclude -I $k" + ##else + ## echo "**Warning**: No such directory \`$k'. Ignored." + fi + done + if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then + if grep "sed.*POTFILES" configure.in >/dev/null; then + : do nothing -- we still have an old unmodified configure.in + else + echo "Creating $dr/aclocal.m4 ..." + test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 + echo "Running gettextize... Ignore non-fatal messages." + echo "no" | gettextize --force --copy + echo "Making $dr/aclocal.m4 writable ..." + test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 + fi + fi + if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then + echo "Creating $dr/aclocal.m4 ..." + test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 + echo "Running gettextize... Ignore non-fatal messages." + echo "no" | gettextize --force --copy + echo "Making $dr/aclocal.m4 writable ..." + test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 + fi + if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then + echo "Running libtoolize..." + libtoolize --force --copy + fi + echo "Running aclocal $aclocalinclude ..." + aclocal $aclocalinclude + if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then + echo "Running autoheader..." + autoheader + fi + echo "Running automake --gnu $am_opt ..." + automake --add-missing --gnu $am_opt + echo "Running autoconf ..." + autoconf + ) + fi +done + +#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c + +if test x$NOCONFIGURE = x; then + echo Running $srcdir/configure $conf_flags "$@" ... + $srcdir/configure $conf_flags "$@" \ + && echo Now type \`make\' to compile $PKG_NAME +else + echo Skipping configure process. +fi diff --git a/legacy/eet/configure.ac b/legacy/eet/configure.ac new file mode 100644 index 0000000000..a391da6e45 --- /dev/null +++ b/legacy/eet/configure.ac @@ -0,0 +1,75 @@ +dnl Process this file with autoconf to produce a configure script. + +# get rid of that stupid cache mechanism +rm -f config.cache + +AC_INIT(configure.in) +AM_INIT_AUTOMAKE(eet, 0.0.1) +AM_CONFIG_HEADER(config.h) + +AC_ISC_POSIX +AC_PROG_CC +AM_PROG_CC_STDC +AC_HEADER_STDC +AC_C_CONST +AM_ENABLE_SHARED +AM_PROG_LIBTOOL + +if test "x${exec_prefix}" = "xNONE"; then + if test "x${prefix}" = "xNONE"; then + bindir="${ac_default_prefix}/bin"; + else + bindir="${prefix}/bin"; + fi +else + if test "x${prefix}" = "xNONE"; then + bindir="${ac_default_prefix}/bin"; + else + bindir="${prefix}/bin"; + fi +fi + +if test "x${exec_prefix}" = "xNONE"; then + if test "x${prefix}" = "xNONE"; then + libdir="${ac_default_prefix}/lib"; + else + libdir="${prefix}/lib"; + fi +else + if test "x${prefix}" = "xNONE"; then + libdir="${ac_default_prefix}/lib"; + else + libdir="${prefix}/lib"; + fi +fi + +dnl Set PACKAGE_BIN_DIR in config.h. +if test "x${bindir}" = 'xNONE'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${ac_default_prefix}/bin") + else + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${prefix}/bin") + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${bindir}") +fi + +dnl Set PACKAGE_LIB_DIR in config.h. +if test "x${libdir}" = 'xNONE'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${ac_default_prefix}/lib") + else + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${prefix}/lib") + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${libdir}") +fi + +dnl Set PACKAGE_SOURCE_DIR in config.h. +packagesrcdir=`cd $srcdir && pwd` +AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}") + +AC_OUTPUT([ +Makefile src/Makefile src/lib/Makefile src/bin/Makefile +]) + diff --git a/legacy/eet/configure.in b/legacy/eet/configure.in new file mode 100644 index 0000000000..a391da6e45 --- /dev/null +++ b/legacy/eet/configure.in @@ -0,0 +1,75 @@ +dnl Process this file with autoconf to produce a configure script. + +# get rid of that stupid cache mechanism +rm -f config.cache + +AC_INIT(configure.in) +AM_INIT_AUTOMAKE(eet, 0.0.1) +AM_CONFIG_HEADER(config.h) + +AC_ISC_POSIX +AC_PROG_CC +AM_PROG_CC_STDC +AC_HEADER_STDC +AC_C_CONST +AM_ENABLE_SHARED +AM_PROG_LIBTOOL + +if test "x${exec_prefix}" = "xNONE"; then + if test "x${prefix}" = "xNONE"; then + bindir="${ac_default_prefix}/bin"; + else + bindir="${prefix}/bin"; + fi +else + if test "x${prefix}" = "xNONE"; then + bindir="${ac_default_prefix}/bin"; + else + bindir="${prefix}/bin"; + fi +fi + +if test "x${exec_prefix}" = "xNONE"; then + if test "x${prefix}" = "xNONE"; then + libdir="${ac_default_prefix}/lib"; + else + libdir="${prefix}/lib"; + fi +else + if test "x${prefix}" = "xNONE"; then + libdir="${ac_default_prefix}/lib"; + else + libdir="${prefix}/lib"; + fi +fi + +dnl Set PACKAGE_BIN_DIR in config.h. +if test "x${bindir}" = 'xNONE'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${ac_default_prefix}/bin") + else + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${prefix}/bin") + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${bindir}") +fi + +dnl Set PACKAGE_LIB_DIR in config.h. +if test "x${libdir}" = 'xNONE'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${ac_default_prefix}/lib") + else + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${prefix}/lib") + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${libdir}") +fi + +dnl Set PACKAGE_SOURCE_DIR in config.h. +packagesrcdir=`cd $srcdir && pwd` +AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}") + +AC_OUTPUT([ +Makefile src/Makefile src/lib/Makefile src/bin/Makefile +]) + diff --git a/legacy/eet/debian/.cvsignore b/legacy/eet/debian/.cvsignore new file mode 100644 index 0000000000..a0c9d092bf --- /dev/null +++ b/legacy/eet/debian/.cvsignore @@ -0,0 +1,7 @@ +files +libeet0 +libeet0-dev +libeet0.postinst.debhelper +libeet0.postrm.debhelper +libeet0.substvars +tmp diff --git a/legacy/eet/debian/changelog b/legacy/eet/debian/changelog new file mode 100644 index 0000000000..1201b206ea --- /dev/null +++ b/legacy/eet/debian/changelog @@ -0,0 +1,6 @@ +libeet (0.0.0-0cvs20021005) unstable; urgency=low + + * a CVS release + + -- Sytse Wielinga Sat, 5 Oct 2002 12:12:06 +0200 + diff --git a/legacy/eet/debian/control b/legacy/eet/debian/control new file mode 100644 index 0000000000..f8ea80e99c --- /dev/null +++ b/legacy/eet/debian/control @@ -0,0 +1,29 @@ +Source: libeet +Section: libs +Priority: optional +Maintainer: Sytse Wielinga +Build-Depends: debhelper (>> 3.0.0), libz-dev, libjpeg-dev +Standards-Version: 3.5.7.0 + +Package: libeet0-dev +Section: devel +Architecture: any +Depends: libeet0 (= ${Source-Version}) +Provides: libeet-dev +Conflicts: libeet-dev +Description: Enlightenment file chunk reading/writing library development files + This package contains headers and static libraries for development with + libeet. + +Package: libeet0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends} +Description: Enlightenment file chunk reading/writing library + Eet is a tiny library designed to write an arbitary set of chunks of data to a + file and optionally compress each chunk (very much like a zip file) and allow + fast random-access reading of the file later on. It does not do zip as zip + itself has more complexity than we need, and it was much simpler to implement + this once here. + . + It's small, fast, and does a job. It's heavily commented and fully documented. diff --git a/legacy/eet/debian/copyright b/legacy/eet/debian/copyright new file mode 100644 index 0000000000..daf5283b6b --- /dev/null +++ b/legacy/eet/debian/copyright @@ -0,0 +1,32 @@ +This package was debianized by Sytse Wielinga on +Thu, 3 Oct 2002 12:08:24 +0200. + +The source is downloaded from the e17/libs/eet module of the enlightenment CVS +tree. For more information, see: + + http://www.enlightenment.org/cvs.html + +Upstream Author(s): Enlightenment team + +Copyright: + +Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software, its documentation and marketing & publicity +materials, and acknowledgment shall be given in the documentation, materials +and software packages that this Software was used. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/legacy/eet/debian/eet-config.1 b/legacy/eet/debian/eet-config.1 new file mode 100644 index 0000000000..b64bb228a5 --- /dev/null +++ b/legacy/eet/debian/eet-config.1 @@ -0,0 +1,27 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH EET 1 "oktober 3, 2002" +.SH NAME +eet-config \- script to get information about the installed version of Eet +.SH SYNOPSIS +.B eet-config [\-\-version] [\-\-libs] [\-\-cflags] +.SH DESCRIPTION +\fIeet-config\fP is a tool that is used by configure to determine the +availability of eet and the compiler and linker flags that should be used to +compile programs using it. +.SH OPTIONS +\fIeet-config\fP accepts the following options: +.TP +.B \-\-version +Print the currently installed version of \fIeet\fP on the standard output. +.TP +.B \-\-libs +Print the linker flags that are necessary to link a \fIeet\fP\-program. +.TP +.B \-\-cflags +Print the compiler flags that are necessary to link a \fIeet\fP\-program. +.SH SEE ALSO +.BR eet (1). +.SH AUTHOR +This manual page was written by Sytse Wielinga + for the Debian GNU/Linux system (but may be +used by others). diff --git a/legacy/eet/debian/eet.1 b/legacy/eet/debian/eet.1 new file mode 100644 index 0000000000..f0f43f7376 --- /dev/null +++ b/legacy/eet/debian/eet.1 @@ -0,0 +1,61 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH EET 1 "oktober 3, 2002" +.SH NAME +eet \- program for editing eet files +.SH SYNOPSIS +.B eet +-l in_file +.br +.B eet +-d in_file +.br +.B eet +-c out_file [-nz glob [-nz glob ...]] dir_file1 [dir_file2 ...] +.SH DESCRIPTION +This manual page documents briefly the +.B eet +command. +This manual page was written for the Debian distribution +because the original program does not have a manual page. +.PP +.B eet +is a program for viewing, unpacking and adding files to eet files, which are +containers for optionally compressed data, allowing for fast random-access +reading. These files are mostly used by the enlightenment project. See +.B www.enlightenment.org +for more details about this project. +.SH OPTIONS +.TP +.B \-l in_file +List the contents of an eet file +.TP +.B \-d in_file +Unpack an eet file +.TP +.B \-c out_file +Create an eet file +.TP +.B \-nz match +Store files matching match glob uncompressed +.SH SEE ALSO +.BR eet-config (1). +.PP +For more information, have a look at the sources of libeet. To get them, have +a look at the website +.B www.enlightenment.org +or execute the following commands: +.TP +.B export CVSROOT=:pserver:anonymous@cvs.enlightenment.sourceforge.net:/cvsroot/enlightenment +If this is command is broken among multiple lines because your terminal is not +as wide as the command, please don't include the minus sign into the command. +.TP +.B cvs login +Just hit enter if it asks about a password for anonymous. +.TP +.B cvs co -r SPLIT e17/libs/eet +This command should create the directory e17/libs/eet, containing the latest +sources of eet. +.SH AUTHOR +This manual page was written by Sytse Wielinga + for the Debian GNU/Linux system (but may be +used by others). diff --git a/legacy/eet/debian/libeet0-dev.files b/legacy/eet/debian/libeet0-dev.files new file mode 100644 index 0000000000..606c89f00a --- /dev/null +++ b/legacy/eet/debian/libeet0-dev.files @@ -0,0 +1,4 @@ +usr/bin/eet-config +usr/include/* +usr/lib/lib*.a +usr/lib/lib*.so diff --git a/legacy/eet/debian/libeet0.files b/legacy/eet/debian/libeet0.files new file mode 100644 index 0000000000..31a86abefe --- /dev/null +++ b/legacy/eet/debian/libeet0.files @@ -0,0 +1,2 @@ +usr/bin/eet +usr/lib/lib*.so.* diff --git a/legacy/eet/debian/rules b/legacy/eet/debian/rules new file mode 100644 index 0000000000..171d5dc8e8 --- /dev/null +++ b/legacy/eet/debian/rules @@ -0,0 +1,74 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatibility version to use. +export DH_COMPAT=3 + + +ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) + CFLAGS += -g +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +version=`ls src/.libs/lib*.so.* | \ + awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'` +major=`ls src/.libs/lib*.so.* | \ + awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'` + +build: build-stamp +build-stamp: + dh_testdir + + ./configure --prefix=/usr build + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + -./configure clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + ./configure --prefix=$(CURDIR)/debian/tmp/usr install + + +binary-indep: build install + +binary-arch: build install + dh_testdir + dh_testroot + dh_movefiles + + dh_installdocs -plibeet0 README AUTHORS + dh_installdocs -plibeet0-dev + dh_installman -plibeet0 debian/eet.1 + dh_installman -plibeet0-dev debian/eet-config.1 + dh_installchangelogs + dh_link + dh_strip + dh_compress + dh_fixperms + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/legacy/eet/eet-config.in b/legacy/eet/eet-config.in new file mode 100644 index 0000000000..d80b8724f5 --- /dev/null +++ b/legacy/eet/eet-config.in @@ -0,0 +1,59 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage="\ +Usage: evas-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]" + +if test $# -eq 0; then + echo "${usage}" 1>&2 + exit 1 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @VERSION@ + ;; + --cflags) + if test @includedir@ != /usr/include ; then + includes=-I@includedir@ + fi + echo $includes + ;; + --libs) + libdirs=-L@libdir@ + echo $libdirs -leet -ljpeg -lz + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done + +exit 0 diff --git a/legacy/eet/eet.spec b/legacy/eet/eet.spec new file mode 100644 index 0000000000..419d95fa3c --- /dev/null +++ b/legacy/eet/eet.spec @@ -0,0 +1,63 @@ +# Note that this is NOT a relocatable package +%define ver 0.0.1 +%define rel 1 +%define prefix /usr/local + +Summary: eet +Name: eet +Version: %ver +Release: %rel +Copyright: BSD +Group: Base/Group +Source: ftp://ftp.enlightenment.org/pub/eet/eet-%{ver}.tar.gz +BuildRoot: /var/tmp/eet-root +Packager: The Rasterman +URL: http://www.enlightenment.org/ +Requires: libjpeg +Requires: zlib + +Docdir: %{prefix}/doc + +%description +Eet + +%prep +%setup + +%build +./configure --prefix=%prefix + +if [ "$SMP" != "" ]; then + (make "MAKE=make -k -j $SMP"; exit 0) + make +else + make +fi +########################################################################### + +%install +rm -rf $RPM_BUILD_ROOT +make prefix=$RPM_BUILD_ROOT%{prefix} install + +%clean +rm -rf $RPM_BUILD_ROOT + +%post + +%postun + +%files +%defattr(-,root,root) +%doc README COPYING ChangeLog +%attr(755,root,root) %{prefix}/bin/* +%attr(755,root,root) %{prefix}/lib/* +%{prefix}/share/* + +%doc AUTHORS +%doc COPYING +%doc README + +%changelog +* Sat Jun 23 2001 The Rasterman +- Created spec file + diff --git a/legacy/eet/src/.cvsignore b/legacy/eet/src/.cvsignore new file mode 100644 index 0000000000..2fa80b7761 --- /dev/null +++ b/legacy/eet/src/.cvsignore @@ -0,0 +1,3 @@ +eet +eet-config +libeet.so.0.0.0 diff --git a/legacy/eet/src/Makefile.am b/legacy/eet/src/Makefile.am new file mode 100644 index 0000000000..7b45af65b2 --- /dev/null +++ b/legacy/eet/src/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = lib bin diff --git a/legacy/eet/src/bin/.cvsignore b/legacy/eet/src/bin/.cvsignore new file mode 100644 index 0000000000..2fa80b7761 --- /dev/null +++ b/legacy/eet/src/bin/.cvsignore @@ -0,0 +1,3 @@ +eet +eet-config +libeet.so.0.0.0 diff --git a/legacy/eet/src/bin/Makefile.am b/legacy/eet/src/bin/Makefile.am new file mode 100644 index 0000000000..49b8604e3e --- /dev/null +++ b/legacy/eet/src/bin/Makefile.am @@ -0,0 +1,12 @@ +## Process this file with automake to produce Makefile.in + +INCLUDES = \ + -I../lib + +bin_PROGRAMS = eet + +eet_SOURCES = \ +eet_main.c + +eet_LDADD = $(top_builddir)/src/lib/libeet.la +eet_DEPENDANCIES = $(top_builddir)/src/lib/libeet.la diff --git a/legacy/eet/src/bin/eet_main.c b/legacy/eet/src/bin/eet_main.c new file mode 100644 index 0000000000..0bf1a717cb --- /dev/null +++ b/legacy/eet/src/bin/eet_main.c @@ -0,0 +1,420 @@ +#include "Eet.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* just some sample code on how to use encoder/decoders */ +#if 0 +#include + +typedef struct _blah2 +{ + char *string; +} +Blah2; + +typedef struct _blah3 +{ + char *string; +} +Blah3; + +typedef struct _blah +{ + char character; + short sixteen; + int integer; + long long lots; + float floating; + double floating_lots; + char *string; + Blah2 *blah2; + Evas_List *blah3; +} +Blah; + +void +encdectest(void) +{ + Blah blah; + Blah2 blah2; + Blah3 blah3; + Eet_Data_Descriptor *edd, *edd2, *edd3; + void *data; + int size; + FILE *f; + Blah *blah_in; + + edd3 = eet_data_descriptor_new("blah3", sizeof(Blah3), + evas_list_next, + evas_list_append, + evas_list_data, + evas_hash_foreach, + evas_hash_add); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd3, Blah3, "string3", string, EET_T_STRING); + + edd2 = eet_data_descriptor_new("blah2", sizeof(Blah2), + evas_list_next, + evas_list_append, + evas_list_data, + evas_hash_foreach, + evas_hash_add); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd2, Blah2, "string2", string, EET_T_STRING); + + edd = eet_data_descriptor_new("blah", sizeof(Blah), + evas_list_next, + evas_list_append, + evas_list_data, + evas_hash_foreach, + evas_hash_add); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "character", character, EET_T_CHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "sixteen", sixteen, EET_T_SHORT); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "integer", integer, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "lots", lots, EET_T_LONG_LONG); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "floating", floating, EET_T_FLOAT); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "floating_lots", floating_lots, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "string", string, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_SUB (edd, Blah, "blah2", blah2, edd2); + EET_DATA_DESCRIPTOR_ADD_LIST (edd, Blah, "blah3", blah3, edd3); + + blah3.string="PANTS"; + + blah2.string="subtype string here!"; + + blah.character='7'; + blah.sixteen=0x7777; + blah.integer=0xc0def00d; + blah.lots=0xdeadbeef31337777; + blah.floating=3.141592654; + blah.floating_lots=0.777777777777777; + blah.string="bite me like a turnip"; + blah.blah2 = &blah2; + blah.blah3 = evas_list_append(NULL, &blah3); + blah.blah3 = evas_list_append(blah.blah3, &blah3); + blah.blah3 = evas_list_append(blah.blah3, &blah3); + blah.blah3 = evas_list_append(blah.blah3, &blah3); + blah.blah3 = evas_list_append(blah.blah3, &blah3); + blah.blah3 = evas_list_append(blah.blah3, &blah3); + blah.blah3 = evas_list_append(blah.blah3, &blah3); + + data = eet_data_descriptor_encode(edd, &blah, &size); + f = fopen("out", "w"); + if (f) + { + fwrite(data, size, 1, f); + fclose(f); + } + printf("-----DECODING\n"); + blah_in = eet_data_descriptor_decode(edd, data, size); + printf("-----DECODED!\n"); + printf("%c\n", blah_in->character); + printf("%x\n", (int)blah_in->sixteen); + printf("%x\n", blah_in->integer); + printf("%lx\n", blah_in->lots); + printf("%f\n", (double)blah_in->floating); + printf("%f\n", (double)blah_in->floating_lots); + printf("%s\n", blah_in->string); + printf("%p\n", blah_in->blah2); + printf(" %s\n", blah_in->blah2->string); + { + Evas_List *l; + + for (l = blah_in->blah3; l; l = l->next) + { + Blah3 *blah3_in; + + blah3_in = l->data; + printf("%p\n", blah3_in); + printf(" %s\n", blah3_in->string); + } + } + eet_data_descriptor_free(edd); + eet_data_descriptor_free(edd2); + eet_data_descriptor_free(edd3); + + exit(0); +} +#endif + +int eet_mkdir(char *dir); +void eet_mkdirs(char *s); + +void depak_file(Eet_File *ef, char *file); +void depack(char *pak_file); + +void list(char *pak_file); + +void pak_file(Eet_File *ef, char *file, char **noz, int noz_num); +void pak_dir(Eet_File *ef, char *dir, char **noz, int noz_num); +void pack(char *pak_file, char **files, int count, char **noz, int noz_num); + +static mode_t default_mode = +S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + +int +eet_mkdir(char *dir) +{ + if (mkdir(dir, default_mode) < 0) return 0; + return 1; +} + +void +eet_mkdirs(char *s) +{ + char ss[PATH_MAX]; + int i, ii; + + i = 0; + ii = 0; + while (s[i]) + { + ss[ii++] = s[i]; + ss[ii] = 0; + if (s[i] == '/') eet_mkdir(ss); + i++; + } +} + +void +depak_file(Eet_File *ef, char *file) +{ + void *data; + int size; + char *last; + + data = eet_read(ef, file, &size); + if (data) + { + FILE *f; + char buf[PATH_MAX]; + + strcpy(buf, file); + last = strrchr(buf, '/'); + if (last) + { + last[1] = 0; + eet_mkdirs(buf); + } + + f = fopen(file, "w"); + if (f) + { + fwrite(data, 1, size, f); + fclose(f); + printf("exported: %s\n", file); + } + else + printf("error exporting: %s\n", file); + free(data); + } + else + { + printf("error reading: %s\n", file); + } +} + +void +depack(char *pak_file) +{ + int i, num; + char **list; + Eet_File *ef; + + ef = eet_open(pak_file, EET_FILE_MODE_READ); + if (!ef) + { + printf("cannot open for reading: %s\n", pak_file); + return; + } + list = eet_list(ef, "*", &num); + if (list) + { + for (i = 0; i < num; i++) + depak_file(ef, list[i]); + free(list); + } + eet_close(ef); +} + +void +list(char *pak_file) +{ + int i, num; + char **list; + Eet_File *ef; + + ef = eet_open(pak_file, EET_FILE_MODE_READ); + if (!ef) + { + printf("cannot open for reading: %s\n", pak_file); + return; + } + list = eet_list(ef, "*", &num); + if (list) + { + for (i = 0; i < num; i++) + printf("%s\n",list[i]); + free(list); + } + eet_close(ef); +} + +void +pak_file(Eet_File *ef, char *file, char **noz, int noz_num) +{ + struct stat st; + + if (stat(file, &st) >= 0) + { + void *buf; + + buf = malloc(st.st_size); + if (buf) + { + FILE *f; + + f = fopen(file, "r"); + if (f) + { + int compress = 1; + int i; + + for (i = 0; i < noz_num; i++) + { + if (!fnmatch(noz[i], file, 0)) + { + compress = 0; + break; + } + } + fread(buf, 1, st.st_size, f); + if (!eet_write(ef, file, buf, st.st_size, compress)) + printf("error importing: %s\n", file); + else + { + if (compress) + printf("compress: %s\n", file); + else + printf("imported: %s\n", file); + } + fclose(f); + } + free(buf); + } + } +} + +void +pak_dir(Eet_File *ef, char *dir, char **noz, int noz_num) +{ + DIR *dirp; + struct dirent *dp; + + dirp = opendir(dir); + if (!dirp) + pak_file(ef, dir, noz, noz_num); + else + { + while ((dp = readdir(dirp))) + { + char buf[PATH_MAX]; + + if ((!strcmp(".", dp->d_name)) || (!strcmp("..", dp->d_name))) + { + } + else + { + snprintf(buf, sizeof(buf), "%s/%s", dir, dp->d_name); + pak_dir(ef, buf, noz, noz_num); + } + } + } +} + +void +pack(char *pak_file, char **files, int count, char **noz, int noz_num) +{ + Eet_File *ef; + int i; + + ef = eet_open(pak_file, EET_FILE_MODE_WRITE); + if (!ef) + { + printf("cannot open for writing: %s\n", pak_file); + return; + } + for (i = 0; i < count; i++) pak_dir(ef, files[i], noz, noz_num); + printf("done.\n"); + eet_close(ef); +} + +int +main(int argc, char **argv) +{ + if (argc == 3) + { + if (!strcmp(argv[1], "-d")) + { + depack(argv[2]); + return 0; + } + else if (!strcmp(argv[1], "-l")) + { + list(argv[2]); + return 0; + } + } + else if (argc > 3) + { + char **noz = NULL; + int noz_num = 0; + + if (!strcmp(argv[1], "-c")) + { + int i; + + for (i = 3; i < argc; i++) + { + if (!strcmp(argv[i], "-nz")) + { + if (i < (argc - 1)) + { + i++; + noz_num++; + noz = realloc(noz, noz_num * sizeof(char *)); + noz[noz_num - 1] = argv[i]; + } + } + else + break; + } + pack(argv[2], &(argv[i]), argc - i, noz, noz_num); + return 0; + } + } + printf("usage:\n" + " %s -l in_file\n" + " %s -d in_file\n" + " %s -c out_file [-nz glob [-nz glob ...]] dir_file1 [dir_file2 ...]\n" + "\n" + "where:\n" + " -l in_file list contents of eet file\n" + " -d in_file unpack eet file\n" + " -c out_file pack up eet file\n" + " -nz match don't compress files matching match glob\n" + "\n" + "example:\n" + " %s -c out.eet -nz \"*.jpg\" things/\n" + " %s -l out.eet\n" + " %s -d out.eet\n", + argv[0], argv[0], argv[0], + argv[0], argv[0], argv[0]); + return -1; +} diff --git a/legacy/eet/src/lib/.cvsignore b/legacy/eet/src/lib/.cvsignore new file mode 100644 index 0000000000..2fa80b7761 --- /dev/null +++ b/legacy/eet/src/lib/.cvsignore @@ -0,0 +1,3 @@ +eet +eet-config +libeet.so.0.0.0 diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h new file mode 100644 index 0000000000..57e231f89f --- /dev/null +++ b/legacy/eet/src/lib/Eet.h @@ -0,0 +1,268 @@ +#ifndef _EET_H +#define _EET_H + +/***************************************************************************/ + +/* + * EET - E file chunk reading/writing library + * + * What is it? + * It is a tiny library designed to write an arbitary set of chunks of data + * to a file and optionally compress each chunk (very much like a zip file) + * and allow fast random-access reading of the file later on. It does not + * do zip as zip itself has more complexity than we need, and it was much + * simpler to impliment this once here. + * + */ + +/***************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************/ + +#define EET_T_UNKNOW 0 +#define EET_T_CHAR 1 +#define EET_T_SHORT 2 +#define EET_T_INT 3 +#define EET_T_LONG_LONG 4 +#define EET_T_FLOAT 5 +#define EET_T_DOUBLE 6 +#define EET_T_UCHAR 7 +#define EET_T_USHORT 8 +#define EET_T_UINT 9 +#define EET_T_ULONG_LONG 10 +#define EET_T_STRING 11 +#define EET_T_LAST 12 + +#define EET_G_UNKNOWN 100 +#define EET_G_ARRAY 101 +#define EET_G_VAR_ARRAY 102 +#define EET_G_LIST 103 +#define EET_G_HASH 104 +#define EET_G_LAST 105 + +/***************************************************************************/ + + enum _Eet_File_Mode + { + EET_FILE_MODE_READ, + EET_FILE_MODE_WRITE + }; + + typedef enum _Eet_File_Mode Eet_File_Mode; + + typedef struct _Eet_File Eet_File; + typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor; + + +/***************************************************************************/ + + /* eet_open - Open an eet file on disk, and returns a handle to it. + * @file: The file path to the eet file. eg: "/tmp/file.eet". + * @mode: The mode for opening. Either EET_FILE_MODE_READ or EET_FILE_MODE_WRITE, but not both. + * + * This function will open an exiting eet file for reading, and build + * the directory table in memory and return a handle to the file, if it + * exists and can be read, and no memory errors occur on the way, otherwise + * NULL will be returned. + * + * It will also open an eet file for writing. This will, if successful, + * delete the original file and replace it with a new empty file, till + * the eet file handle is closed or flushed. If it cannot be opened for + * writing or a memory error occurs, NULL is returned. + */ + Eet_File *eet_open (char *file, Eet_File_Mode mode); + /* eet_close - Close an eet file handle and flush and writes pending. + * @ef: A valid eet file handle. + * + * This function will flush any pending writes to disk if the eet file + * was opened for write, and free all data associated with the file handle + * and file, and close the file. + * + * If the eet file handle is not valid nothing will be done. + */ + void eet_close (Eet_File *ef); + /* eet_read - Read a specified entry from an eet file and return data + * @ef: A valid eet file handle opened for reading. + * @name: Name of the entry. eg: "/base/file_i_want". + * @size_ret: Number of bytes read from entry and returned. + * + * This function finds an entry in the eet file that is stored under the + * name specified, and returns that data, decompressed, if successfule. + * NULL is retuurned if the lookup fails or if memory errors are + * encountered. It is the job of the calling program to call free() on + * the returned data. The number of bytes in the returned data chunk are + * placed in size_ret. + * + * If the eet file handle is not valid NULl is returned and size_ret is + * filled with 0. + */ + void *eet_read (Eet_File *ef, char *name, int *size_ret); + /* eet_write - Write a specified entry to an eet file handle + * @ef: A valid eet file handle opened for writing. + * @name: Name of the entry. eg: "/base/file_i_want". + * @data: Pointer to the data to be stored. + * @size: Length in bytes in the data to be stored. + * @compress: Compression flags (1 == compress, 0 = don't compress). + * + * This function will write the specified chunk of data to the eet file + * and return 1 on success. 0 will be returned on failure. + * + * The eet file handle must be a valid file handle for an eet file opened + * for writing. If it is not, 0 will be returned and no action will be + * performed. + * + * Name, and data must not be NULL, and size must be > 0. If these + * conditions are not met, 0 will be returned. + * + * The data will be copied (and optionally compressed) in ram, pending + * a flush to disk (it will stay in ram till the eet file handle is + * closed though). + */ + int eet_write (Eet_File *ef, char *name, void *data, int size, int compress); + /* eet_list - List all entries in eet file matching shell glob. + * @ef: A valid eet file handle. + * @glob: A shell glob to match against. + * @count_ret: number of entries foudn to match. + * + * This function will list all entries in the eet file matching the + * supplied shell glob and return an allocated list of their names, if + * there are any, and if no memory errors occur. + * + * The eet file handle must be valid and glob must not be NULL, or NULL + * will be returned and count_ret will be filled with 0. + * + * The calling program must call free() on the array returned, but NOT + * on the string pointers in the array. They are taken as read-only + * internals from the eet file handle. They are only valid as long as + * the file handle is not closed. When it is closed those pointers in the + * array are now not valid and should not be used. + * + * On success the array returned will have a list of string pointers + * that are the names of the entries that matched, and count_ret will have + * the number of entries in this array placed in it. + * + * Hint: an easy way to list all entries in an eet file is to use a glob + * value of "*". + */ + char **eet_list (Eet_File *ef, char *glob, int *count_ret); + +/***************************************************************************/ + + /* eet_data_image_read - Read image data from the named key in the eet file. + * @ef: A valid eet file handle opened for reading. + * @name: Name of the entry. eg: "/base/file_i_want". + * @w: A pointer to the int to hold the width in pixels. + * @h: A pointer to the int to hold the height in pixels. + * @alpha: A pointer to the int to hold the alpha flag. + * @compress: A pointer to the int to hold the compression amount. + * @quality: A pointer to the int to hold the quality amount. + * @lossy: A pointer to the int to hold the lossiness flag. + * + * This function reads an image from an eet file stored under the named + * key in the eet file and return a pointer to the decompressed pixel data. + * + * The other parameters of the image (width, height etc.) are placed into + * the values pointed to (they must be supplied). The pixel data is a linear + * array of pixels starting from the top-left of the image scanning row by + * row from left to right. Each piel is a 32bit value, with the high byte + * being the alpha channel, the next being red, then green, and the low byte + * being blue. The width and height are measured in pixels and will be + * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes + * that the alpha channel is not used. 1 denoties that it is significant. + * Compress is fiulled with the compression value/amount the image was + * stored with. The quality value si fileld with the quality encoding of + * the image file (0 - 100). The lossy flags is either 0 or 1 as to if + * the image was encoded lossily or not. + * + * On success the function returns a pointer to the image data decoded. The + * calling application is responsible for calling free() on the image data + * when it is done with it. On failure NULL is returned and the parameter + * values may not contain any sensible data. + */ + void *eet_data_image_read(Eet_File *ef, char *name, int *w, int *h, int *alpha, int *compress, int *quality, int *lossy); + /* eet_data_image_write - Write image data to the named key in an eet file. + * @ef: A valid eet file handle opened for writing. + * @name: Name of the entry. eg: "/base/file_i_want". + * @data: A pointer to the image pixel data. + * @w: The width of the image in pixels. + * @h: The height of the image in pixels. + * @alpha: The alpha channel flag. + * @compress: The compression amount. + * @quality: The quality encoding amount. + * @lossy: The lossiness flag. + * + * This function dates image pixel data and encodes it in an eet file + * stored under the supplied name key, and returns how many bytes were + * actually written to encode the image data. + * + * The data expected is the same format as returned by eet_data_image_read. + * If this is not the case wierd things may happen. Width and height must + * be between 1 and 8000 pixels. The alpha flags can be 0 or 1 (0 meaning + * the alpha values are not useful and 1 meaning they are). Compress can + * be from 0 to 9 (0 meaning no compression, 9 meaning full compression). + * This is only used if the image is not lossily encoded. Quality is used on + * lossy compression and shoudl be a value from 0 to 100. The lossy flag + * can be 0 or 1. 0 means encode losslessly and 1 means to encode with + * image quality loss (but then have a much smaller encoding). + * + * On success this function rtuens the numebr fo bytes that were required + * to encode the image data, or on failure it returns 0. + */ + int eet_data_image_write(Eet_File *ef, char *name, void *data, int w, int h, int alpha, int compress, int quality, int lossy); + + /* To Be Documented + * + */ + void *eet_data_image_encode(void *data, int *size_ret, int w, int h, int alpha, int compress, int quality, int lossy); + void *eet_data_image_decode(void *data, int size, int *w, int *h, int *alpha, int *compress, int *quality, int *lossy); +/***************************************************************************/ + + /* To Be Documented + * + */ + Eet_Data_Descriptor *eet_data_descriptor_new(char *name, int size, void *(*func_list_next) (void *l), void *(*func_list_append) (void *l, void *d), void *(*func_list_data) (void *l), void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt), void *(*func_hash_add) (void *h, const char *k, void *d)); + void eet_data_descriptor_free(Eet_Data_Descriptor *edd); + + void eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, char *name, int type, int group_type, int offset, int count, char *counter_name, Eet_Data_Descriptor *subtype); + + void *eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, char *name); + int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, char *name, void *data, int compress); + + void *eet_data_descriptor_decode(Eet_Data_Descriptor *edd, void *data_in, int size_in); + void *eet_data_descriptor_encode(Eet_Data_Descriptor *edd, void *data_in, int *size_ret); + +#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type) \ + { \ + struct_type ___ett; \ + \ + eet_data_descriptor_element_add(edd, name, type, EET_G_UNKNOWN, \ + (char *)(&(___ett.member)) - (char *)(&(___ett)), \ + 0, NULL, NULL); \ + } +#define EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct_type, name, member, subtype) \ + { \ + struct_type ___ett; \ + \ + eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_UNKNOWN, \ + (char *)(&(___ett.member)) - (char *)(&(___ett)), \ + 0, NULL, subtype); \ + } +#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype) \ + { \ + struct_type ___ett; \ + \ + eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_LIST, \ + (char *)(&(___ett.member)) - (char *)(&(___ett)), \ + 0, NULL, subtype); \ + } + +/***************************************************************************/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/legacy/eet/src/lib/Makefile.am b/legacy/eet/src/lib/Makefile.am new file mode 100644 index 0000000000..9477e0075d --- /dev/null +++ b/legacy/eet/src/lib/Makefile.am @@ -0,0 +1,20 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = 1.4 foreign + +# A list of all the files in the current directory which can be regenerated +MAINTAINERCLEANFILES = Makefile.in + +LDFLAGS = -L/usr/local/lib +INCLUDES = -I/usr/local/include \ + -I$(includedir) + +lib_LTLIBRARIES = libeet.la +include_HEADERS = Eet.h +libeet_la_SOURCES = \ +eet_lib.c \ +eet_data.c + +libeet_la_LIBADD = $(LDFLAGS) -lz -ljpeg +libeet_la_DEPENDENCIES = $(top_builddir)/config.h +libeet_la_LDFLAGS = -version-info 0:1:0 diff --git a/legacy/eet/src/lib/eet_data.c b/legacy/eet/src/lib/eet_data.c new file mode 100644 index 0000000000..d82b72b463 --- /dev/null +++ b/legacy/eet/src/lib/eet_data.c @@ -0,0 +1,1765 @@ +#include "Eet.h" +#define _GNU_SOURCE /* need this for fmemopen & open_memstream */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * rotuines for doing data -> struct and struct -> data conversion + * + * types: + * + * basic types: + * a sequence of... + * + * char + * short + * int + * long long + * float + * double + * unsigned char + * unsigned short + * unsigned int + * unsgined long long + * string + * + * groupings: + * multiple entries ordered as... + * + * fixed size array [ of basic types ] + * variable size array [ of basic types ] + * linked list [ of basic types ] + * hash table [ of basic types ] + * + * need to provide builder/accessor funcs for: + * + * list_next + * list_append + * + * hash_foreach + * hash_add + * + */ + +/*---*/ + +typedef struct _Eet_Data_Element Eet_Data_Element; +typedef struct _Eet_Data_Basic_Type_Decoder Eet_Data_Basic_Type_Decoder; +typedef struct _Eet_Data_Chunk Eet_Data_Chunk; +typedef struct _Eet_Data_Stream Eet_Data_Stream; +typedef struct _JPEG_error_mgr *emptr; + +/*---*/ + +struct _Eet_Data_Basic_Type_Decoder +{ + int size; + int (*get) (void *src, void *src_end, void *dest); + void *(*put) (void *src, int *size_ret); +}; + +struct _Eet_Data_Chunk +{ + char *name; + int size; + void *data; +}; + +struct _Eet_Data_Stream +{ + void *data; + int size; + int pos; +}; + +struct _Eet_Data_Descriptor +{ + char *name; + int size; + struct { + void *(*list_next) (void *l); + void *(*list_append) (void *l, void *d); + void *(*list_data) (void *l); + void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt); + void *(*hash_add) (void *h, const char *k, void *d); + } func; + struct { + int num; + Eet_Data_Element *set; + } elements; +}; + +struct _Eet_Data_Element +{ + char *name; + int type; + int group_type; + int offset; + int count; + char *counter_name; + Eet_Data_Descriptor *subtype; +}; + +struct _JPEG_error_mgr +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +/*---*/ + +static void _JPEGFatalErrorHandler(j_common_ptr cinfo); +static void _JPEGErrorHandler(j_common_ptr cinfo); +static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level); + +static void *eet_data_image_jpeg_rgb_decode(void *data, int size, int *w, int *h); +static void *eet_data_image_jpeg_alpha_decode(void *data, int size, unsigned int *d, int *w, int *h); +static void *eet_data_image_lossless_convert(int *size, void *data, int w, int h, int alpha); +static void *eet_data_image_lossless_compressed_convert(int *size, void *data, int w, int h, int alpha, int compression); +static void *eet_data_image_jpeg_convert(int *size, void *data, int w, int h, int alpha, int quality); +static void *eet_data_image_jpeg_alpha_convert(int *size, void *data, int w, int h, int alpha, int quality); + +static int eet_data_get_char(void *src, void *src_end, void *dest); +static void *eet_data_put_char(void *src, int *size_ret); +static int eet_data_get_short(void *src, void *src_end, void *dest); +static void *eet_data_put_short(void *src, int *size_ret); +static int eet_data_get_int(void *src, void *src_end, void *dest); +static void *eet_data_put_int(void *src, int *size_ret); +static int eet_data_get_long_long(void *src, void *src_end, void *dest); +static void *eet_data_put_long_long(void *src, int *size_ret); +static int eet_data_get_float(void *src, void *src_end, void *dest); +static void *eet_data_put_float(void *src, int *size_ret); +static int eet_data_get_double(void *src, void *src_end, void *dest); +static void *eet_data_put_double(void *src, int *size_ret); +static int eet_data_get_string(void *src, void *src_end, void *dest); +static void *eet_data_put_string(void *src, int *size_ret); + +static int eet_data_get_type(int type, void *src, void *src_end, void *dest); +static void *eet_data_put_type(int type, void *src, int *size_ret); + +static Eet_Data_Chunk *eet_data_chunk_get(void *src, int size); +static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, char *name); +static void eet_data_chunk_free(Eet_Data_Chunk *chnk); + +static Eet_Data_Stream *eet_data_stream_new(void); +static void eet_data_stream_write(Eet_Data_Stream *ds, void *data, int size); +static void eet_data_stream_free(Eet_Data_Stream *ds); + +static void eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds); + +/*---*/ + +const Eet_Data_Basic_Type_Decoder eet_coder[] = +{ + {sizeof(char), eet_data_get_char, eet_data_put_char }, + {sizeof(short), eet_data_get_short, eet_data_put_short }, + {sizeof(int), eet_data_get_int, eet_data_put_int }, + {sizeof(long long), eet_data_get_long_long, eet_data_put_long_long}, + {sizeof(float), eet_data_get_float, eet_data_put_float }, + {sizeof(double), eet_data_get_double, eet_data_put_double }, + {sizeof(char), eet_data_get_char, eet_data_put_char }, + {sizeof(short), eet_data_get_short, eet_data_put_short }, + {sizeof(int), eet_data_get_int, eet_data_put_int }, + {sizeof(long long), eet_data_get_long_long, eet_data_put_long_long}, + {sizeof(char *), eet_data_get_string, eet_data_put_string } +}; + +static int words_bigendian = -1; + +/*---*/ + +#define SWAP64(x) (x) = \ + ((((x) & 0x00000000000000ff ) << 56) |\ + (((x) & 0x000000000000ff00 ) << 40) |\ + (((x) & 0x0000000000ff0000 ) << 24) |\ + (((x) & 0x00000000ff000000 ) << 8) |\ + (((x) & 0x000000ff00000000 ) >> 8) |\ + (((x) & 0x0000ff0000000000 ) >> 24) |\ + (((x) & 0x00ff000000000000 ) >> 40) |\ + (((x) & 0xff00000000000000 ) >> 56)) +#define SWAP32(x) (x) = \ + ((((x) & 0x000000ff ) << 24) |\ + (((x) & 0x0000ff00 ) << 8) |\ + (((x) & 0x00ff0000 ) >> 8) |\ + (((x) & 0xff000000 ) >> 24)) +#define SWAP16(x) (x) = \ + ((((x) & 0x00ff ) << 8) |\ + (((x) & 0xff00 ) >> 8)) + +#define CONV8(x) +#define CONV16(x) {if (words_bigendian) SWAP16(x);} +#define CONV32(x) {if (words_bigendian) SWAP32(x);} +#define CONV64(x) {if (words_bigendian) SWAP64(x);} + +/*---*/ + +static void +_JPEGFatalErrorHandler(j_common_ptr cinfo) +{ + emptr errmgr; + + errmgr = (emptr) cinfo->err; + /* cinfo->err->output_message(cinfo);*/ + longjmp(errmgr->setjmp_buffer, 1); + return; +} + +static void +_JPEGErrorHandler(j_common_ptr cinfo) +{ + emptr errmgr; + + errmgr = (emptr) cinfo->err; + /* cinfo->err->output_message(cinfo);*/ + /* longjmp(errmgr->setjmp_buffer, 1);*/ + return; +} + +static void +_JPEGErrorHandler2(j_common_ptr cinfo, int msg_level) +{ + emptr errmgr; + + errmgr = (emptr) cinfo->err; + /* cinfo->err->output_message(cinfo);*/ + /* longjmp(errmgr->setjmp_buffer, 1);*/ + return; + msg_level = 0; +} + +static void * +eet_data_image_jpeg_rgb_decode(void *data, int size, int *w, int *h) +{ + unsigned int *d; + struct jpeg_decompress_struct cinfo; + struct _JPEG_error_mgr jerr; + unsigned char *ptr, *line[16], *tdata; + unsigned int *ptr2; + int x, y, l, i, scans, count, prevy; + FILE *f; + + f = fmemopen(data, (size_t)size, "r"); + if (!f) return NULL; + cinfo.err = jpeg_std_error(&(jerr.pub)); + jerr.pub.error_exit = _JPEGFatalErrorHandler; + jerr.pub.emit_message = _JPEGErrorHandler2; + jerr.pub.output_message = _JPEGErrorHandler; + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, f); + jpeg_read_header(&cinfo, TRUE); + cinfo.do_fancy_upsampling = FALSE; + cinfo.do_block_smoothing = FALSE; + jpeg_start_decompress(&cinfo); + + /* head decoding */ + *w = cinfo.output_width; + *h = cinfo.output_height; + /* end head decoding */ + /* data decoding */ + if (cinfo.rec_outbuf_height > 16) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + tdata = malloc((*w) * 16 * 3); + if (!tdata) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + d = malloc((*w) * (*h) * 4); + if (!d) + { + free(tdata); + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + ptr2 = d; + count = 0; + prevy = 0; + if (cinfo.output_components == 3) + { + for (i = 0; i < cinfo.rec_outbuf_height; i++) + line[i] = tdata + (i * (*w) * 3); + for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + { + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); + scans = cinfo.rec_outbuf_height; + if (((*h) - l) < scans) scans = (*h) - l; + ptr = tdata; + for (y = 0; y < scans; y++) + { + for (x = 0; x < (*w); x++) + { + *ptr2 = + (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]); + ptr += 3; + ptr2++; + } + } + } + } + else if (cinfo.output_components == 1) + { + for (i = 0; i < cinfo.rec_outbuf_height; i++) + line[i] = tdata + (i * (*w)); + for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + { + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); + scans = cinfo.rec_outbuf_height; + if (((*h) - l) < scans) scans = (*h) - l; + ptr = tdata; + for (y = 0; y < scans; y++) + { + for (x = 0; x < (*w); x++) + { + *ptr2 = + (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]); + ptr++; + ptr2++; + } + } + } + } + free(tdata); + fclose(f); + /* end data decoding */ + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return d; +} + +static void * +eet_data_image_jpeg_alpha_decode(void *data, int size, unsigned int *d, int *w, int *h) +{ + struct jpeg_decompress_struct cinfo; + struct _JPEG_error_mgr jerr; + unsigned char *ptr, *line[16], *tdata; + unsigned int *ptr2; + int x, y, l, i, scans, count, prevy; + FILE *f; + + f = fmemopen(data, (size_t)size, "r"); + if (!f) return NULL; + cinfo.err = jpeg_std_error(&(jerr.pub)); + jerr.pub.error_exit = _JPEGFatalErrorHandler; + jerr.pub.emit_message = _JPEGErrorHandler2; + jerr.pub.output_message = _JPEGErrorHandler; + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, f); + jpeg_read_header(&cinfo, TRUE); + cinfo.do_fancy_upsampling = FALSE; + cinfo.do_block_smoothing = FALSE; + jpeg_start_decompress(&cinfo); + + /* head decoding */ + if ((*w) != cinfo.output_width) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + if ((*h) != cinfo.output_height) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + *w = cinfo.output_width; + *h = cinfo.output_height; + /* end head decoding */ + /* data decoding */ + if (cinfo.rec_outbuf_height > 16) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + tdata = malloc((*w) * 16 * 3); + if (!tdata) + { + jpeg_destroy_decompress(&cinfo); + fclose(f); + return NULL; + } + ptr2 = d; + count = 0; + prevy = 0; + if (cinfo.output_components == 3) + { + for (i = 0; i < cinfo.rec_outbuf_height; i++) + line[i] = tdata + (i * (*w) * 3); + for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + { + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); + scans = cinfo.rec_outbuf_height; + if (((*h) - l) < scans) scans = (*h) - l; + ptr = tdata; + for (y = 0; y < scans; y++) + { + for (x = 0; x < (*w); x++) + { + *ptr2 = + ((*ptr2) & 0x00ffffff) | + (((ptr[0] + ptr[1] + ptr[2]) / 3) << 24); + ptr += 3; + ptr2++; + } + } + } + } + else if (cinfo.output_components == 1) + { + for (i = 0; i < cinfo.rec_outbuf_height; i++) + line[i] = tdata + (i * (*w)); + for (l = 0; l < (*h); l += cinfo.rec_outbuf_height) + { + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); + scans = cinfo.rec_outbuf_height; + if (((*h) - l) < scans) scans = (*h) - l; + ptr = tdata; + for (y = 0; y < scans; y++) + { + for (x = 0; x < (*w); x++) + { + *ptr2 = + ((*ptr2) & 0x00ffffff) | + ((ptr[0]) << 24); + ptr++; + ptr2++; + } + } + } + } + free(tdata); + fclose(f); + /* end data decoding */ + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return d; +} + +static void * +eet_data_image_lossless_convert(int *size, void *data, int w, int h, int alpha) +{ + if (words_bigendian == -1) + { + unsigned long int v; + + v = htonl(0x12345678); + if (v == 0x12345678) words_bigendian = 1; + else words_bigendian = 0; + } + { + unsigned char *d; + int *header; + + d = malloc((w * h * 4) + (8 * 4)); + if (!d) return NULL; + header = (int *)d; + header[0] = 0xac1dfeed; + header[1] = w; + header[2] = h; + header[3] = alpha; + header[4] = 0; + memcpy(d + 32, data, w * h * 4); + + if (words_bigendian) + { + int i; + + for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]); + } + *size = ((w * h * 4) + (8 * 4)); + return d; + } +} + +static void * +eet_data_image_lossless_compressed_convert(int *size, void *data, int w, int h, int alpha, int compression) +{ + if (words_bigendian == -1) + { + unsigned long int v; + + v = htonl(0x12345678); + if (v == 0x12345678) words_bigendian = 1; + else words_bigendian = 0; + } + + { + unsigned char *d; + unsigned char *comp; + int *header; + int ret; + uLongf buflen; + + d = malloc((w * h * 4) + (8 * 4)); + if (!d) return NULL; + buflen = (((w * h * 101) / 100) + 3) * 4; + comp = malloc(buflen); + if (!comp) + { + free(d); + return NULL; + } + header = (int *)d; + header[0] = 0xac1dfeed; + header[1] = w; + header[2] = h; + header[3] = alpha; + header[4] = compression; + memcpy(d + 32, data, w * h * 4); + + if (words_bigendian) + { + int i; + + for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]); + } + ret = compress2((Bytef *)comp, &buflen, + (Bytef *)(d + 32), + (uLong)(w * h * 4), + compression); + if (buflen > (w * h * 4)) + { + free(comp); + *size = ((w * h * 4) + (8 * 4)); + return d; + } + memcpy(d + 32, comp, buflen); + *size = (8 * 4) + buflen; + free(comp); + return d; + } +} + +static void * +eet_data_image_jpeg_convert(int *size, void *data, int w, int h, int alpha, int quality) +{ + int *ptr; + char *d = NULL; + size_t sz = 0; + struct _JPEG_error_mgr jerr; + JSAMPROW *jbuf; + struct jpeg_compress_struct cinfo; + FILE *f; + unsigned char *buf; + + f = open_memstream(&d, &sz); + if (!f) return NULL; + + buf = malloc(3 * w); + if (!buf) + { + fclose(f); + if (d) free(d); + return NULL; + } + + cinfo.err = jpeg_std_error(&(jerr.pub)); + jerr.pub.error_exit = _JPEGFatalErrorHandler; + jerr.pub.emit_message = _JPEGErrorHandler2; + jerr.pub.output_message = _JPEGErrorHandler; + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_compress(&cinfo); + if (buf) free(buf); + fclose(f); + if (d) free(d); + return NULL; + } + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, f); + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + + ptr = data; + while (cinfo.next_scanline < cinfo.image_height) + { + int i, j; + + /* convert scaline from ARGB to RGB packed */ + for (j = 0, i = 0; i < w; i++) + { + buf[j++] = ((*ptr) >> 16) & 0xff; + buf[j++] = ((*ptr) >> 8) & 0xff; + buf[j++] = ((*ptr)) & 0xff; + ptr++; + } + jbuf = (JSAMPROW *) (&buf); + jpeg_write_scanlines(&cinfo, jbuf, 1); + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + *size = sz; + if (buf) free(buf); + fclose(f); + return d; +} + +static void * +eet_data_image_jpeg_alpha_convert(int *size, void *data, int w, int h, int alpha, int quality) +{ + unsigned char *d1, *d2; + unsigned char *d; + int *header; + int sz1, sz2; + + if (words_bigendian == -1) + { + unsigned long int v; + + v = htonl(0x12345678); + if (v == 0x12345678) words_bigendian = 1; + else words_bigendian = 0; + } + + { + int *ptr; + char *d = NULL; + size_t sz = 0; + struct _JPEG_error_mgr jerr; + JSAMPROW *jbuf; + struct jpeg_compress_struct cinfo; + FILE *f; + unsigned char *buf; + + f = open_memstream(&d, &sz); + if (!f) return NULL; + + buf = malloc(3 * w); + if (!buf) + { + fclose(f); + if (d) free(d); + return NULL; + } + + cinfo.err = jpeg_std_error(&(jerr.pub)); + jerr.pub.error_exit = _JPEGFatalErrorHandler; + jerr.pub.emit_message = _JPEGErrorHandler2; + jerr.pub.output_message = _JPEGErrorHandler; + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_compress(&cinfo); + if (buf) free(buf); + fclose(f); + if (d) free(d); + return NULL; + } + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, f); + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + + ptr = data; + while (cinfo.next_scanline < cinfo.image_height) + { + int i, j; + + /* convert scaline from ARGB to RGB packed */ + for (j = 0, i = 0; i < w; i++) + { + buf[j++] = ((*ptr) >> 16) & 0xff; + buf[j++] = ((*ptr) >> 8) & 0xff; + buf[j++] = ((*ptr)) & 0xff; + ptr++; + } + jbuf = (JSAMPROW *) (&buf); + jpeg_write_scanlines(&cinfo, jbuf, 1); + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + if (buf) free(buf); + fclose(f); + d1 = d; + sz1 = sz; + } + { + int *ptr; + char *d = NULL; + size_t sz = 0; + struct _JPEG_error_mgr jerr; + JSAMPROW *jbuf; + struct jpeg_compress_struct cinfo; + FILE *f; + unsigned char *buf; + + f = open_memstream(&d, &sz); + if (!f) + { + free(d1); + return NULL; + } + + buf = malloc(3 * w); + if (!buf) + { + fclose(f); + if (d) free(d); + free(d1); + return NULL; + } + + cinfo.err = jpeg_std_error(&(jerr.pub)); + jerr.pub.error_exit = _JPEGFatalErrorHandler; + jerr.pub.emit_message = _JPEGErrorHandler2; + jerr.pub.output_message = _JPEGErrorHandler; + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_compress(&cinfo); + if (buf) free(buf); + fclose(f); + if (d) free(d); + free(d1); + return NULL; + } + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, f); + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 1; + cinfo.in_color_space = JCS_GRAYSCALE; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + + ptr = data; + while (cinfo.next_scanline < cinfo.image_height) + { + int i, j; + + /* convert scaline from ARGB to RGB packed */ + for (j = 0, i = 0; i < w; i++) + { + buf[j++] = ((*ptr) >> 24) & 0xff; + ptr++; + } + jbuf = (JSAMPROW *) (&buf); + jpeg_write_scanlines(&cinfo, jbuf, 1); + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + if (buf) free(buf); + fclose(f); + d2 = d; + sz2 = sz; + } + d = malloc(12 + sz1 + sz2); + if (!d) + { + free(d1); + free(d2); + return NULL; + } + header = (int *)d; + header[0] = 0xbeeff00d; + header[1] = sz1; + header[2] = sz2; + if (words_bigendian) + { + int i; + + for (i = 0; i < ((w * h) + 3); i++) SWAP32(header[i]); + } + memcpy(d + 12, d1, sz1); + memcpy(d + 12 + sz1, d2, sz2); + + free(d1); + free(d2); + *size = 12 + sz1 + sz2; + return d; +} + + +/* CHAR TYPE */ +static int +eet_data_get_char(void *src, void *src_end, void *dst) +{ + char *s, *d; + + if ((src + sizeof(char)) > src_end) return -1; + s = (char *)src; + d = (char *)dst; + *s = *d; + CONV8(*s); + return sizeof(char); +} + +static void * +eet_data_put_char(void *src, int *size_ret) +{ + char *s, *d; + + d = (char *)malloc(sizeof(char)); + if (!d) return NULL; + s = (char *)src; + *d = *s; + CONV8(*d); + *size_ret = sizeof(char); + return d; +} + +/* SHORT TYPE */ +static int +eet_data_get_short(void *src, void *src_end, void *dst) +{ + short *s, *d; + short tmp; + + if ((src + sizeof(short)) > src_end) return -1; + s = (short *)src; + d = (short *)dst; + /* alignment fixup */ + if ((int)s & (sizeof(short) - 1)) + { + memcpy(&tmp, s, sizeof(short)); + s = &tmp; + } + *d = *s; + CONV16(*d); + return sizeof(short); +} + +static void * +eet_data_put_short(void *src, int *size_ret) +{ + short *s, *d; + + d = (short *)malloc(sizeof(short)); + if (!d) return NULL; + s = (short *)src; + *d = *s; + CONV16(*d); + *size_ret = sizeof(short); + return d; +} + +/* INT TYPE */ +static int +eet_data_get_int(void *src, void *src_end, void *dst) +{ + int *s, *d; + int tmp; + + if ((src + sizeof(int)) > src_end) return -1; + s = (int *)src; + d = (int *)dst; + /* alignment fixup */ + if ((int)s & (sizeof(int) - 1)) + { + memcpy(&tmp, s, sizeof(int)); + s = &tmp; + } + *d = *s; + CONV32(*d); + return sizeof(int); +} + +static void * +eet_data_put_int(void *src, int *size_ret) +{ + int *s, *d; + + d = (int *)malloc(sizeof(int)); + if (!d) return NULL; + s = (int *)src; + *d = *s; + CONV32(*d); + *size_ret = sizeof(int); + return d; +} + +/* LONG LONG TYPE */ +static int +eet_data_get_long_long(void *src, void *src_end, void *dst) +{ + long long *s, *d; + long long tmp; + + if ((src + sizeof(long long)) > src_end) return -1; + s = (long long *)src; + d = (long long *)dst; + /* alignment fixup */ + if ((int)s & (sizeof(long long) - 1)) + { + memcpy(&tmp, s, sizeof(long long)); + s = &tmp; + } + *d = *s; + CONV64(*d); + return sizeof(long long); +} + +static void * +eet_data_put_long_long(void *src, int *size_ret) +{ + long long *s, *d; + + d = (long long *)malloc(sizeof(long long)); + if (!d) return NULL; + s = (long long *)src; + *d = *s; + CONV64(*d); + *size_ret = sizeof(long long); + return d; +} + +/* STRING TYPE */ +static int +eet_data_get_string(void *src, void *src_end, void *dst) +{ + char *s, **d, *p; + int len; + + s = (char *)src; + d = (char **)dst; + p = s; + len = 0; + while ((p < (char *)src_end) && (*p != 0)) {len++; p++;} + *d = malloc(len + 1); + if (!(*d)) return -1; + memcpy(*d, s, len); + (*d)[len] = 0; + return len + 1; +} + +static void * +eet_data_put_string(void *src, int *size_ret) +{ + char *s, *d; + int len; + + if (!src) src = ""; + s = (char *)(*((char **)src)); + len = strlen(s); + d = malloc(len + 1); + if (!d) return NULL; + strcpy(d, s); + *size_ret = len + 1; + return d; +} + +/* FLOAT TYPE */ +static int +eet_data_get_float(void *src, void *src_end, void *dst) +{ + float *d; + char *s, *str, *p, *prev_locale; + int len; + + s = (char *)src; + d = (float *)dst; + p = s; + len = 0; + while ((p < (char *)src_end) && (*p != 0)) {len++; p++;} + str = malloc(len + 1); + if (!str) return -1; + memcpy(str, s, len); + str[len] = 0; + + prev_locale = setlocale(LC_NUMERIC, "C"); + *d = (float)atof(str); + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + + free(str); + return len + 1; +} + +static void * +eet_data_put_float(void *src, int *size_ret) +{ + float *s; + char *d, buf[64], *prev_locale; + int len; + + s = (float *)src; + prev_locale = setlocale(LC_NUMERIC, "C"); + snprintf(buf, sizeof(buf), "%16.16f", (double)(*s)); + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + len = strlen(buf); + d = malloc(len + 1); + if (!d) return NULL; + strcpy(d, buf); + *size_ret = len + 1; + return d; +} + +/* DOUBLE TYPE */ +static int +eet_data_get_double(void *src, void *src_end, void *dst) +{ + double *d; + char *s, *str, *p, *prev_locale; + int len; + + s = (char *)src; + d = (double *)dst; + p = s; + len = 0; + while ((p < (char *)src_end) && (*p != 0)) {len++; p++;} + str = malloc(len + 1); + if (!str) return -1; + memcpy(str, s, len); + str[len] = 0; + + prev_locale = setlocale(LC_NUMERIC, "C"); + *d = (double)atof(str); + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + + free(str); + return len + 1; +} + +static void * +eet_data_put_double(void *src, int *size_ret) +{ + double *s; + char *d, buf[128], *prev_locale; + int len; + + s = (double *)src; + prev_locale = setlocale(LC_NUMERIC, "C"); + snprintf(buf, sizeof(buf), "%32.32f", (double)(*s)); + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + len = strlen(buf); + d = malloc(len + 1); + if (!d) return NULL; + strcpy(d, buf); + *size_ret = len + 1; + return d; +} + +static int +eet_data_get_type(int type, void *src, void *src_end, void *dest) +{ + int ret; + + ret = eet_coder[type - 1].get(src, src_end, dest); + return ret; +} + +static void * +eet_data_put_type(int type, void *src, int *size_ret) +{ + void *ret; + + ret = eet_coder[type - 1].put(src, size_ret); + return ret; +} + +/* chunk format... + * + * char[4] = "CHnK"; + * int = chunk size (including magic string); + * char[] = chuck magic/name string (0 byte terminated); + * ... sub-chunks (a chunk can contain chuncks recusrively) ... + * or + * ... payload data ... + * + */ + +static Eet_Data_Chunk * +eet_data_chunk_get(void *src, int size) +{ + Eet_Data_Chunk *chnk; + char *s; + int ret1, ret2; + + if (!src) return NULL; + if (size <= 8) return NULL; + + chnk = calloc(1, sizeof(Eet_Data_Chunk)); + if (!chnk) return NULL; + + s = src; + if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K')) + { + free(chnk); + return NULL; + } + ret1 = eet_data_get_type(EET_T_INT, (void *)(s + 4), (void *)(s + size), &(chnk->size)); + if (ret1 <= 0) + { + free(chnk); + return NULL; + } + if ((chnk->size < 0) || ((chnk->size + 8) > size)) + { + free(chnk); + return NULL; + } + ret2 = eet_data_get_type(EET_T_STRING, (void *)(s + 8), (void *)(s + size), &(chnk->name)); + if (ret2 <= 0) + { + free(chnk); + return NULL; + } + chnk->data = src + 4 + ret1 + ret2; + chnk->size -= ret2; + return chnk; +} + +static Eet_Data_Chunk * +eet_data_chunk_new(void *data, int size, char *name) +{ + Eet_Data_Chunk *chnk; + + if (!name) return NULL; + chnk = calloc(1, sizeof(Eet_Data_Chunk)); + if (!chnk) return NULL; + + chnk->name = strdup(name); + chnk->size = size; + chnk->data = data; + + return chnk; +} + +static void +eet_data_chunk_free(Eet_Data_Chunk *chnk) +{ + if (chnk->name) free(chnk->name); + free(chnk); +} + +static Eet_Data_Stream * +eet_data_stream_new(void) +{ + Eet_Data_Stream *ds; + + ds = calloc(1, sizeof(Eet_Data_Stream)); + if (!ds) return NULL; + return ds; +} + +static void +eet_data_stream_free(Eet_Data_Stream *ds) +{ + if (ds->data) free(ds->data); + free(ds); +} + +static void +eet_data_stream_write(Eet_Data_Stream *ds, void *data, int size) +{ + char *p; + + if ((ds->pos + size) > ds->size) + { + ds->data = realloc(ds->data, ds->size + size + 256); + if (!ds->data) + { + ds->pos = 0; + ds->size = 0; + return; + } + ds->size = ds->size + size + 256; + } + p = ds->data; + memcpy(p + ds->pos, data, size); + ds->pos += size; +} + +static void +eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds) +{ + int *size; + int s; + int size_ret; + + if (!chnk->data) return; + /* chunk head */ + eet_data_stream_write(ds, "CHnK", 4); + /* size of chunk payload data + name */ + s = strlen(chnk->name) + 1 + chnk->size; + size = eet_data_put_int(&s, &size_ret); + if (size) + { + eet_data_stream_write(ds, size, size_ret); + free(size); + } + /* write chunk name */ + eet_data_stream_write(ds, chnk->name, strlen(chnk->name) + 1); + /* write payload */ + eet_data_stream_write(ds, chnk->data, chnk->size); +} + +/*---*/ + +int +eet_data_image_write(Eet_File *ef, char *name, + void *data, int w, int h, int alpha, + int compress, int quality, int lossy) +{ + void *d = NULL; + int size = 0; + + d = eet_data_image_encode(data, &size, w, h, alpha, compress, quality, lossy); + if (d) + { + int v; + + v = eet_write(ef, name, d, size, 0); + free(d); + return v; + } + return 0; +} + +void * +eet_data_image_read(Eet_File *ef, char *name, + int *w, int *h, int *alpha, + int *compress, int *quality, int *lossy) +{ + void *data; + int size; + unsigned int *d = NULL; + int header[8]; + + data = eet_read(ef, name, &size); + if (!data) return NULL; + d = eet_data_image_decode(data, size, w, h, alpha, compress, quality, lossy); + free(data); + return d; +} + +void * +eet_data_image_encode(void *data, int *size_ret, int w, int h, int alpha, int compress, int quality, int lossy) +{ + void *d = NULL; + int size = 0; + + if (lossy == 0) + { + if (compress <= 0) + d = eet_data_image_lossless_convert(&size, data, w, h, alpha); + else + d = eet_data_image_lossless_compressed_convert(&size, data, w, h, alpha, compress); + } + else + { + if (!alpha) + d = eet_data_image_jpeg_convert(&size, data, w, h, alpha, quality); + else + d = eet_data_image_jpeg_alpha_convert(&size, data, w, h, alpha, quality); + } + if (size_ret) *size_ret = size; + return d; +} + +void * +eet_data_image_decode(void *data, int size, int *w, int *h, int *alpha, int *compress, int *quality, int *lossy) +{ + unsigned int *d = NULL; + int header[8]; + + if (words_bigendian == -1) + { + unsigned long int v; + + v = htonl(0x12345678); + if (v == 0x12345678) words_bigendian = 1; + else words_bigendian = 0; + } + + if (size < 32) return NULL; + + memcpy(header, data, 32); + if (words_bigendian) + { + int i; + + for (i = 0; i < 8; i++) SWAP32(header[i]); + } + if (header[0] == 0xac1dfeed) + { + int iw, ih, al, cp; + unsigned int *body; + + iw = header[1]; + ih = header[2]; + al = header[3]; + cp = header[4]; + if ((iw > 8192) || (ih > 8192)) return NULL; + if ((cp == 0) && (size < ((iw * ih * 4) + 32))) return NULL; + body = ((unsigned int *)data) + 8; + d = malloc(iw * ih * 4); + if (!d) return NULL; + if (!cp) + { + memcpy(d, body, iw * ih * 4); + if (words_bigendian) + { + int x; + + for (x = 0; x < (iw * ih); x++) SWAP32(d[x]); + } + } + else + { + uLongf dlen; + + dlen = iw * ih * 4; + uncompress((Bytef *)d, &dlen, (Bytef *)body, + (uLongf)(size - 32)); + if (words_bigendian) + { + int x; + + for (x = 0; x < (iw * ih); x++) SWAP32(d[x]); + } + } + if (d) + { + if (w) *w = iw; + if (h) *h = ih; + if (alpha) *alpha = al; + if (compress) *compress = cp; + if (lossy) *lossy = 0; + if (quality) *quality = 100; + } + } + else if (header[0] == 0xbeeff00d) + { + int iw = 0, ih = 0; + int sz1, sz2; + unsigned char *dt; + + sz1 = header[1]; + sz2 = header[2]; + dt = data; + dt += 12; + d = eet_data_image_jpeg_rgb_decode(dt, sz1, &iw, &ih); + if (d) + { + dt += sz1; + eet_data_image_jpeg_alpha_decode(dt, sz2, d, &iw, &ih); + } + if (d) + { + if (w) *w = iw; + if (h) *h = ih; + if (alpha) *alpha = 1; + if (compress) *compress = 0; + if (lossy) *lossy = 1; + if (quality) *quality = 75; + } + } + else + { + int iw = 0, ih = 0; + + d = eet_data_image_jpeg_rgb_decode(data, size, &iw, &ih); + if (d) + { + if (w) *w = iw; + if (h) *h = ih; + if (alpha) *alpha = 0; + if (compress) *compress = 0; + if (lossy) *lossy = 1; + if (quality) *quality = 75; + } + } + return d; +} + +Eet_Data_Descriptor * +eet_data_descriptor_new(char *name, + int size, + void *(*func_list_next) (void *l), + void *(*func_list_append) (void *l, void *d), + void *(*func_list_data) (void *l), + void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt), + void *(*func_hash_add) (void *h, const char *k, void *d)) +{ + Eet_Data_Descriptor *edd; + + edd = calloc(1, sizeof(Eet_Data_Descriptor)); + edd->name = strdup(name); + edd->size = size; + edd->func.list_next = func_list_next; + edd->func.list_append = func_list_append; + edd->func.list_data = func_list_data; + edd->func.hash_foreach = func_hash_foreach; + edd->func.hash_add = func_hash_add; + return edd; +} + +void +eet_data_descriptor_free(Eet_Data_Descriptor *edd) +{ + int i; + + if (edd->name) free(edd->name); + for (i = 0; i < edd->elements.num; i++) + { + if (edd->elements.set[i].name) free(edd->elements.set[i].name); + if (edd->elements.set[i].counter_name) free(edd->elements.set[i].counter_name); + } + if (edd->elements.set) free(edd->elements.set); + free(edd); +} + +void +eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, char *name, int type, + int group_type, + int offset, + int count, char *counter_name, + Eet_Data_Descriptor *subtype) +{ + Eet_Data_Element *ede; + + edd->elements.num++; + edd->elements.set = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element)); + if (!edd->elements.set) return; + ede = &(edd->elements.set[edd->elements.num - 1]); + ede->name = strdup(name); + ede->type = type; + ede->group_type = group_type; + ede->offset = offset; + ede->count = count; + if (counter_name) + ede->counter_name = strdup(counter_name); + else ede->counter_name = NULL; + ede->subtype = subtype; +} + +void * +eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, char *name) +{ + void *data_dec; + void *data; + int size; + + data = eet_read(ef, name, &size); + if (!data) return NULL; + data_dec = eet_data_descriptor_decode(edd, data, size); + free(data); + return data_dec; +} + +int +eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, char *name, void *data, int compress) +{ + void *data_enc; + int size; + int val; + + data_enc = eet_data_descriptor_encode(edd, data, &size); + if (!data_enc) return 0; + val = eet_write(ef, name, data_enc, size, compress); + free(data_enc); + return val; +} + +void * +eet_data_descriptor_decode(Eet_Data_Descriptor *edd, + void *data_in, + int size_in) +{ + void *data; + char *p; + int size; + Eet_Data_Chunk *chnk; + + if (words_bigendian == -1) + { + unsigned long int v; + + v = htonl(0x12345678); + if (v == 0x12345678) words_bigendian = 1; + else words_bigendian = 0; + } + + data = calloc(1, edd->size); + if (!data) return NULL; + chnk = eet_data_chunk_get(data_in, size_in); + if (!chnk) + { + free(data); + return NULL; + } + if (strcmp(chnk->name, edd->name)) + { + eet_data_chunk_free(chnk); + free(data); + return NULL; + } + p = chnk->data; + size = size_in - (4 + 4 + strlen(chnk->name) + 1); + while (size > 0) + { + Eet_Data_Chunk *echnk; + int i; + + /* get next data chunk */ + echnk = eet_data_chunk_get(p, size); + if (!echnk) + { + /* FIXME: partially built data struct - leak!!!! */ + free(data); + eet_data_chunk_free(chnk); + return NULL; + } + for (i = 0; i < edd->elements.num; i++) + { + Eet_Data_Element *ede; + + ede = &(edd->elements.set[i]); + if (!strcmp(echnk->name, ede->name)) + { + if (ede->group_type == EET_G_UNKNOWN) + { + int ret; + void *data_ret; + + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) + { + ret = eet_data_get_type(ede->type, + echnk->data, + ((char *)echnk->data) + echnk->size, + ((char *)data) + ede->offset); + } + else if (ede->subtype) + { + void **ptr; + + data_ret = eet_data_descriptor_decode(ede->subtype, + echnk->data, + echnk->size); + ptr = (void **)(((char *)data) + ede->offset); + *ptr = (void *)data_ret; + } + } + else + { + switch (ede->group_type) + { + case EET_G_ARRAY: + case EET_G_VAR_ARRAY: + { + printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n"); + } + break; + case EET_G_LIST: + { + int ret; + void *list = NULL; + void **ptr; + void *data_ret; + + ptr = (void **)(((char *)data) + ede->offset); + list = *ptr; + data_ret = NULL; + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) + { + data_ret = calloc(1, eet_coder[ede->type].size); + if (data_ret) + { + ret = eet_data_get_type(ede->type, + echnk->data, + ((char *)echnk->data) + echnk->size, + data_ret); + if (ret <= 0) + { + free(data_ret); + data_ret = NULL; + } + } + } + else if (ede->subtype) + { + data_ret = eet_data_descriptor_decode(ede->subtype, + echnk->data, + echnk->size); + } + if (data_ret) + { + list = edd->func.list_append(list, data_ret); + *ptr = list; + } + } + break; + case EET_G_HASH: + printf("HASH TYPE NOT IMPLIMENTED YET!!!\n"); + break; + default: + break; + } + } + break; + } + } + /* advance to next chunk */ + p += (4 + 4 + strlen(echnk->name) + 1 + echnk->size); + size -= (4 + 4 + strlen(echnk->name) + 1 + echnk->size); + eet_data_chunk_free(echnk); + } + eet_data_chunk_free(chnk); + return data; +} + +void * +eet_data_descriptor_encode(Eet_Data_Descriptor *edd, + void *data_in, + int *size_ret) +{ + Eet_Data_Chunk *chnk; + Eet_Data_Stream *ds; + int i; + void *cdata; + int csize; + + if (words_bigendian == -1) + { + unsigned long int v; + + v = htonl(0x12345678); + if (v == 0x12345678) words_bigendian = 1; + else words_bigendian = 0; + } + + ds = eet_data_stream_new(); + for (i = 0; i < edd->elements.num; i++) + { + Eet_Data_Element *ede; + Eet_Data_Chunk *echnk; + void *data; + int size; + + ede = &(edd->elements.set[i]); + data = NULL; + if (ede->group_type == EET_G_UNKNOWN) + { + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) + data = eet_data_put_type(ede->type, + ((char *)data_in) + ede->offset, + &size); + else if (ede->subtype) + data = eet_data_descriptor_encode(ede->subtype, + *((char **)(((char *)data_in) + ede->offset)), + &size); + if (data) + { + echnk = eet_data_chunk_new(data, size, ede->name); + eet_data_chunk_put(echnk, ds); + eet_data_chunk_free(echnk); + free(data); + data = NULL; + } + } + else + { + switch (ede->group_type) + { + case EET_G_ARRAY: + case EET_G_VAR_ARRAY: + { + printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n"); + } + break; + case EET_G_LIST: + { + void *l; + + l = *((void **)(((char *)data_in) + ede->offset)); + for (; l; l = edd->func.list_next(l)) + { + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) + data = eet_data_put_type(ede->type, + edd->func.list_data(l), + &size); + else if (ede->subtype) + data = eet_data_descriptor_encode(ede->subtype, + edd->func.list_data(l), + &size); + if (data) + { + echnk = eet_data_chunk_new(data, size, ede->name); + eet_data_chunk_put(echnk, ds); + eet_data_chunk_free(echnk); + free(data); + data = NULL; + } + } + } + break; + case EET_G_HASH: + { + printf("HASH TYPE NOT IMPLIMENTED YET!!!\n"); + } + break; + default: + break; + } + } + } + chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name); + ds->data = NULL; + ds->size = 0; + eet_data_stream_free(ds); + + ds = eet_data_stream_new(); + eet_data_chunk_put(chnk, ds); + cdata = ds->data; + csize = ds->pos; + + ds->data = NULL; + ds->size = 0; + eet_data_stream_free(ds); + *size_ret = csize; + eet_data_chunk_free(chnk); + + return cdata; +} diff --git a/legacy/eet/src/lib/eet_lib.c b/legacy/eet/src/lib/eet_lib.c new file mode 100644 index 0000000000..e1cef9d880 --- /dev/null +++ b/legacy/eet/src/lib/eet_lib.c @@ -0,0 +1,889 @@ +#include "Eet.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EET_MAGIC_FILE 0x1ee7ff00 +#define EET_MAGIC_FILE_HEADER 0x1ee7ff01 +#define EET_MAGIC_FILE_NODE 0x1ee7ff02 +#define EET_MAGIC_FILE_DIRECTORY 0x1ee7ff03 +#define EET_MAGIC_FILE_DIRECTORY_HASH 0x1ee7ff04 + +typedef struct _Eet_File_Header Eet_File_Header; +typedef struct _Eet_File_Node Eet_File_Node; +typedef struct _Eet_File_Directory Eet_File_Directory; +typedef struct _Eet_File_Directory_Hash Eet_File_Directory_Hash; + +struct _Eet_File +{ + int magic; + int references; + + char *path; + char *real_path; + + FILE *fp; + Eet_File_Mode mode; + + int writes_pending : 1; + + Eet_File_Header *header; +}; +struct _Eet_File_Header +{ + int magic; + Eet_File_Directory *directory; +}; +struct _Eet_File_Node +{ + char *name; + int offset; + int compression; + int size; + int data_size; + void *data; +}; +struct _Eet_File_Directory +{ + int size; + Eet_File_Directory_Hash *hash; +}; +struct _Eet_File_Directory_Hash +{ + int size; + Eet_File_Node *node; +}; + +#if 0 +/* NB: all int's are stored in network byte order on disk */ +/* file format: */ +int magic; /* magic number ie 0x1ee7ff00 */ +int num_directory_entries; /* number of directory entries to follow */ +int bytes_directory_entries; /* bytes of directory entries to follow */ +struct +{ + int offset; /* bytes offset into file for data chunk */ + int flags; /* flags - for now 0 = uncompressed, 1 = compressed */ + int size; /* size of the data chunk */ + int data_size; /* size of the (uncompressed) data chunk */ + int name_size; /* length in bytes of the name field */ + char name[name_size]; /* name string (variable length) */ +} directory[num_directory_entries]; +/* and now startes the data stream... */ +#endif + +/* prototypes of internal calls */ +static Eet_File *eet_cache_find(char *real_path, Eet_File **cache, int cache_num); +static void eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num); +static void eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num); +static int eet_string_match(char *s1, char *s2); +static int eet_hash_gen(char *key, int hash_size); +static void eet_flush(Eet_File *ef); + +/* cache. i don't expect this to ever be large, so arrays will do */ +static int eet_writers_num = 0; +static Eet_File **eet_writers = NULL; +static int eet_readers_num = 0; +static Eet_File **eet_readers = NULL; + +/* find an eet file in the currently in use cache */ +static Eet_File * +eet_cache_find(char *real_path, Eet_File **cache, int cache_num) +{ + int i; + + /* walk list */ + for (i = 0; i < cache_num; i++) + { + /* if matches real path - return it */ + if (eet_string_match(cache[i]->real_path, real_path)) return cache[i]; + } + /* not found */ + return NULL; +} + +/* add to end of cache */ +static void +eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num) +{ + Eet_File **new_cache; + int new_cache_num; + + new_cache_num = *cache_num; + new_cache = *cache; + new_cache_num++; + new_cache = realloc(new_cache, new_cache_num * sizeof(Eet_File *)); + if (!new_cache) return; + new_cache[new_cache_num - 1] = ef; + *cache = new_cache; + *cache_num = new_cache_num; +} + +/* delete from cache */ +static void +eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num) +{ + Eet_File **new_cache; + int new_cache_num; + int i, j; + + new_cache_num = *cache_num; + new_cache = *cache; + if (new_cache_num <= 0) return; + for (i = 0; i < new_cache_num; i++) + { + if (new_cache[i] == ef) break; + } + if (i >= new_cache_num) return; + new_cache_num--; + for (j = i; j < new_cache_num; j++) new_cache[j] = new_cache[j + 1]; + new_cache = realloc(new_cache, new_cache_num * sizeof(Eet_File *)); + *cache_num = new_cache_num; + if ((new_cache_num > 0) && (!new_cache)) return; + *cache = new_cache; +} + +/* internal string match. bails out at first mismatch - not comparing all */ +/* bytes in strings */ +static int +eet_string_match(char *s1, char *s2) +{ + /* both null- no match */ + if ((!s1) || (!s2)) return 0; + /* go thru - first mismatch - exit with 0 */ + do + { + if (*s1 != *s2) return 0; + s1++; + s2++; + } + while ((*s1) || (*s2)); + /* got this far. match */ + return 1; +} + +/* caluclate hash table entry valu with bitmask size of hash_size */ +static int +eet_hash_gen(char *key, int hash_size) +{ + int hash_num = 0; + unsigned char *ptr; + const int masks[9] = + { + 0x00, + 0x01, + 0x03, + 0x07, + 0x0f, + 0x1f, + 0x3f, + 0x7f, + 0xff + }; + + /* no string - index 0 */ + if (!key) return 0; + + /* calc hash num */ + for (ptr = key; *ptr; ptr++) hash_num ^= (int)(*ptr); + + /* mask it */ + hash_num &= masks[hash_size]; + /* return it */ + return hash_num; +} + +/* flush out writes to an eet file */ +static void +eet_flush(Eet_File *ef) +{ + int i, j, count, size, num, offset; + int head[3]; + unsigned long int i1, i2; + + /* check to see its' an eet file pointer */ + if ((!ef) || (ef->magic != EET_MAGIC_FILE)) + return; + if (ef->mode != EET_FILE_MODE_WRITE) return; + if (!ef->writes_pending) return; + + /* calculate total size in bytes of directory block */ + size = 0; + count = 0; + num = (1 << (ef->header->directory->size - 1)); + for (i = 0; i < num; i++) + { + for (j = 0; j < ef->header->directory->hash[i].size; j++) + { + size += 20 + strlen(ef->header->directory->hash[i].node[j].name); + count++; + } + } + /* caluclate offsets per entry */ + offset = 0; + for (i = 0; i < num; i++) + { + for (j = 0; j < ef->header->directory->hash[i].size; j++) + { + ef->header->directory->hash[i].node[j].offset = 12 + size + offset; + offset += ef->header->directory->hash[i].node[j].size; + } + } + /* go thru and write the header */ + i1 = (unsigned long int)EET_MAGIC_FILE; + i2 = htonl(i1); + head[0] = (int)i2; + i1 = (unsigned long int)count; + i2 = htonl(i1); + head[1] = (int)i2; + i1 = (unsigned long int)size; + i2 = htonl(i1); + head[2] = (int)i2; + fseek(ef->fp, 0, SEEK_SET); + if (fwrite(head, 12, 1, ef->fp) != 1) return; + offset = 12; + for (i = 0; i < num; i++) + { + for (j = 0; j < ef->header->directory->hash[i].size; j++) + { + unsigned char *buf; + int buf_size; + int name_size; + + name_size = strlen(ef->header->directory->hash[i].node[j].name); + buf_size = 20 + name_size; + buf = malloc(buf_size); + if (!buf) return; + i1 = (unsigned long int)ef->header->directory->hash[i].node[j].offset; + i2 = htonl(i1); + *((int *)(buf + 0)) = (int)i2; + i1 = (unsigned long int)ef->header->directory->hash[i].node[j].compression; + i2 = htonl(i1); + *((int *)(buf + 4)) = (int)i2; + i1 = (unsigned long int)ef->header->directory->hash[i].node[j].size; + i2 = htonl(i1); + *((int *)(buf + 8)) = (int)i2; + i1 = (unsigned long int)ef->header->directory->hash[i].node[j].data_size; + i2 = htonl(i1); + *((int *)(buf + 12)) = (int)i2; + i1 = (unsigned long int)name_size; + i2 = htonl(i1); + *((int *)(buf + 16)) = (int)i2; + memcpy(buf + 20, ef->header->directory->hash[i].node[j].name, name_size); + if (fwrite(buf, buf_size, 1, ef->fp) != 1) + { + free(buf); + return; + } + offset += buf_size; + free(buf); + } + } + /* write data */ + for (i = 0; i < num; i++) + { + for (j = 0; j < ef->header->directory->hash[i].size; j++) + { + if (fwrite(ef->header->directory->hash[i].node[j].data, + ef->header->directory->hash[i].node[j].size, + 1, ef->fp) != 1) + return; + } + } + /* no more writes pending */ + ef->writes_pending = 0; +} + +Eet_File * +eet_open(char *file, Eet_File_Mode mode) +{ + Eet_File *ef; + char buf[PATH_MAX]; + + /* in case this is a symlink... find out where it REALLY points */ + if (!realpath(file, buf)) + { + if (mode == EET_FILE_MODE_READ) return NULL; + } + + /* find the current file handle in cache*/ + ef = NULL; + if (mode == EET_FILE_MODE_READ) + ef = eet_cache_find(buf, eet_readers, eet_readers_num); + else if (mode == EET_FILE_MODE_WRITE) + ef = eet_cache_find(buf, eet_writers, eet_writers_num); + /* we found one */ + if (ef) + { + /* reference it up and return it */ + ef->references++; + return ef; + } + + /* allocate struct for eet file and have it zero'd out */ + ef = calloc(sizeof(Eet_File), 1); + if (!ef) return NULL; + + /* fill some of the members */ + ef->path = strdup(file); + ef->real_path = strdup(buf); + ef->magic = EET_MAGIC_FILE; + ef->references = 1; + ef->mode = mode; + + /* try open the file based on mode */ + if (ef->mode == EET_FILE_MODE_READ) + ef->fp = fopen(ef->path, "r"); + else if (ef->mode == EET_FILE_MODE_WRITE) + { + /* opening for write - delete old copy of file right away */ + unlink(ef->real_path); + ef->fp = fopen(ef->path, "w"); + } + else + { + eet_close(ef); + return NULL; + } + + /* if we can't open - bail out */ + if (!ef->fp) + { + eet_close(ef); + return NULL; + } + + /* if we opened for read */ + if (mode == EET_FILE_MODE_READ) + { + unsigned char buf[12]; + unsigned char *dyn_buf, *p; + unsigned long int i1, i2; + int num_entries, byte_entries, i; + size_t count; + + /* build header table if read mode */ + /* geat header */ + count = fread(buf, 12, 1, ef->fp); + if (count != 1) + { + eet_close(ef); + return NULL; + } + /* get magic no */ + i1 = *((int *)(buf + 0)); + i2 = ntohl(i1); + if (i2 != EET_MAGIC_FILE) + { + eet_close(ef); + return NULL; + } + /* get entries count and byte count */ + i1 = *((int *)(buf + 4)); + i2 = ntohl(i1); + num_entries = (int)i2; + i1 = *((int *)(buf + 8)); + i2 = ntohl(i1); + byte_entries = (int)i2; + /* we cant have <= 0 values here - invalid */ + if ((num_entries <= 0) || (byte_entries <= 0)) + { + eet_close(ef); + return NULL; + } + /* we can't have more entires than minimum bytes for those! invalid! */ + if ((num_entries * 20) > byte_entries) + { + eet_close(ef); + return NULL; + } + /* allocate dynamic buffer for entire directory block */ + dyn_buf = malloc(byte_entries); + if (!dyn_buf) + { + eet_close(ef); + return NULL; + } + /* allocate header */ + ef->header = calloc(sizeof(Eet_File_Header), 1); + if (!ef->header) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + ef->header->magic = EET_MAGIC_FILE_HEADER; + /* allocate directory block in ram */ + ef->header->directory = calloc(sizeof(Eet_File_Directory), 1); + if (!ef->header->directory) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* 8 bit hash table (256 buckets) */ + ef->header->directory->size = 8; + /* allocate base hash table */ + ef->header->directory->hash = calloc(sizeof(Eet_File_Directory_Hash), (1 << (ef->header->directory->size - 1))); + if (!ef->header->directory->hash) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* actually read the directory block - all of it, into ram */ + count = fread(dyn_buf, byte_entries, 1, ef->fp); + if (count != 1) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* parse directory block */ + p = dyn_buf; + for (i = 0; i < num_entries; i++) + { + int offset; + int flags; + int size; + int data_size; + int name_size; + char *name; + int hash; + Eet_File_Node *node; + int node_size; + + /* out directory block is inconsistent - we have oveerun our */ + /* dynamic block buffer before we finished scanning dir entries */ + if (p >= (dyn_buf + byte_entries)) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* get entrie header */ + i1 = *((int *)(p + 0)); + i2 = ntohl(i1); + offset = (int)i2; + i1 = *((int *)(p + 4)); + i2 = ntohl(i1); + flags = (int)i2; + i1 = *((int *)(p + 8)); + i2 = ntohl(i1); + size = (int)i2; + i1 = *((int *)(p + 12)); + i2 = ntohl(i1); + data_size = (int)i2; + i1 = *((int *)(p + 16)); + i2 = ntohl(i1); + name_size = (int)i2; + /* invalid size */ + if (size <= 0) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* invalid name_size */ + if (name_size <= 0) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* reading name would mean falling off end of dyn_buf - invalid */ + if ((p + 16 + name_size) > (dyn_buf + byte_entries)) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* allocate name string */ + name = malloc(name_size + 1); + if (!name) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* copy name in and terminate it */ + strncpy(name, p + 20, name_size); + name[name_size] = 0; + + /* get hask bucket it should go in */ + hash = eet_hash_gen(name, ef->header->directory->size); + /* resize hask bucket */ + node = realloc(ef->header->directory->hash[hash].node, + (ef->header->directory->hash[hash].size + 1) * + sizeof(Eet_File_Node)); + if (!node) + { + free(dyn_buf); + eet_close(ef); + return NULL; + } + /* current node size */ + node_size = ef->header->directory->hash[hash].size; + /* resized node list set up */ + ef->header->directory->hash[hash].node = node; + /* new node at end */ + ef->header->directory->hash[hash].node[node_size].name = name; + ef->header->directory->hash[hash].node[node_size].offset = offset; + ef->header->directory->hash[hash].node[node_size].compression = flags; + ef->header->directory->hash[hash].node[node_size].size = size; + ef->header->directory->hash[hash].node[node_size].data_size = data_size; + /* currently we have no data loaded */ + ef->header->directory->hash[hash].node[node_size].data = NULL; + /* increment number of nodes */ + ef->header->directory->hash[hash].size++; + /* advance */ + p += 20 + name_size; + } + /* done - free dynamic buffer */ + free(dyn_buf); + } + /* add to cache */ + if (ef->mode == EET_FILE_MODE_READ) + eet_cache_add(ef, &eet_readers, &eet_readers_num); + else if (ef->mode == EET_FILE_MODE_WRITE) + eet_cache_add(ef, &eet_writers, &eet_writers_num); + return ef; +} + +void +eet_close(Eet_File *ef) +{ + /* check to see its' an eet file pointer */ + if ((!ef) || (ef->magic != EET_MAGIC_FILE)) + return; + /* deref */ + ef->references--; + /* if its still referenced - dont go any further */ + if (ef->references > 0) return; + /* remove from cache */ + if (ef->mode == EET_FILE_MODE_READ) + eet_cache_del(ef, &eet_readers, &eet_readers_num); + else if (ef->mode == EET_FILE_MODE_WRITE) + eet_cache_del(ef, &eet_writers, &eet_writers_num); + /* flush any writes */ + eet_flush(ef); + + /* free up members */ + if (ef->fp) fclose(ef->fp); + if (ef->path) free(ef->path); + if (ef->real_path) free(ef->real_path); + + /* free up data */ + if (ef->header) + { + if (ef->header->directory) + { + if (ef->header->directory->hash) + { + int i, num; + + num = (1 << (ef->header->directory->size - 1)); + for (i = 0; i < num; i++) + { + if (ef->header->directory->hash[i].node) + { + int j; + int num2; + + num2 = ef->header->directory->hash[i].size; + for (j = 0; j < num2; j++) + { + if (ef->header->directory->hash[i].node[j].name) + free(ef->header->directory->hash[i].node[j].name); + if (ef->header->directory->hash[i].node[j].data) + free(ef->header->directory->hash[i].node[j].data); + } + free(ef->header->directory->hash[i].node); + } + } + free(ef->header->directory->hash); + } + free(ef->header->directory); + } + free(ef->header); + } + + /* zero out ram for struct - caution tactic against stale memory use */ + memset(ef, 0, sizeof(Eet_File)); + /* free it */ + free(ef); +} + +void * +eet_read(Eet_File *ef, char *name, int *size_ret) +{ + void *data = NULL; + int size = 0, tmp_size; + int hash, i, num; + + /* check to see its' an eet file pointer */ + if ((!ef) || (ef->magic != EET_MAGIC_FILE)) + { + if (size_ret) *size_ret = 0; + return NULL; + } + /* get hash bucket this should be in */ + hash = eet_hash_gen(name, ef->header->directory->size); + /* hunt hash bucket */ + num = ef->header->directory->hash[hash].size; + for (i = 0; i < num; i++) + { + /* if it matches */ + if (eet_string_match(ef->header->directory->hash[hash].node[i].name, name)) + { + /* uncompressed data */ + if (ef->header->directory->hash[hash].node[i].compression == 0) + { + /* get size */ + size = ef->header->directory->hash[hash].node[i].size; + /* allocate data */ + data = malloc(size); + if (data) + { + /* if we alreayd have the data in ram... copy that */ + if (ef->header->directory->hash[hash].node[i].data) + memcpy(data, + ef->header->directory->hash[hash].node[i].data, + ef->header->directory->hash[hash].node[i].size); + /* or get data from disk */ + else + { + /* seek to data location */ + if (fseek(ef->fp, ef->header->directory->hash[hash].node[i].offset, SEEK_SET) < 0) + { + free(data); + data = NULL; + break; + } + /* read it */ + if (fread(data, size, 1, ef->fp) != 1) + { + free(data); + data = NULL; + break; + } + } + } + break; + } + /* compressed data */ + else + { + void *tmp_data; + + /* get size of data in file */ + tmp_size = ef->header->directory->hash[hash].node[i].size; + tmp_data = malloc(tmp_size); + if (!tmp_data) break; + /* get size uncompressed */ + size = ef->header->directory->hash[hash].node[i].data_size; + /* allocate data */ + data = malloc(size); + if (data) + { + uLongf dlen; + + /* if we already have the data in ram... copy that */ + if (ef->header->directory->hash[hash].node[i].data) + memcpy(tmp_data, + ef->header->directory->hash[hash].node[i].data, + tmp_size); + /* or get data from disk */ + else + { + /* seek to data location */ + if (fseek(ef->fp, ef->header->directory->hash[hash].node[i].offset, SEEK_SET) < 0) + { + free(tmp_data); + free(data); + data = NULL; + break; + } + /* read it */ + if (fread(tmp_data, tmp_size, 1, ef->fp) != 1) + { + free(tmp_data); + free(data); + data = NULL; + break; + } + } + /* decompress it */ + dlen = size; + if (uncompress((Bytef *)data, &dlen, + tmp_data, (uLongf)tmp_size)) + { + free(tmp_data); + free(data); + data = NULL; + break; + } + } + free(tmp_data); + break; + } + } + } + /* fill in return values */ + *size_ret = size; + /* update access time */ + return data; +} + +int +eet_write(Eet_File *ef, char *name, void *data, int size, int compress) +{ + int data_size; + int hash, node_size; + Eet_File_Node *node; + char *name2; + void *data2; + + /* check to see its' an eet file pointer */ + if ((!ef) || (ef->magic != EET_MAGIC_FILE) + || (!name) || (!data) || (size <= 0) || + (ef->mode != EET_FILE_MODE_WRITE)) + return 0; + + if (!ef->header) + { + /* allocate header */ + ef->header = calloc(sizeof(Eet_File_Header), 1); + if (!ef->header) return 0; + ef->header->magic = EET_MAGIC_FILE_HEADER; + /* allocate directory block in ram */ + ef->header->directory = calloc(sizeof(Eet_File_Directory), 1); + if (!ef->header->directory) return 0; + /* 8 bit hash table (256 buckets) */ + ef->header->directory->size = 8; + /* allocate base hash table */ + ef->header->directory->hash = calloc(sizeof(Eet_File_Directory_Hash), (1 << (ef->header->directory->size - 1))); + if (!ef->header->directory->hash) return 0; + } + /* figure hash bucket */ + hash = eet_hash_gen(name, ef->header->directory->size); + node_size = ef->header->directory->hash[hash].size; + /* dup name */ + name2 = strdup(name); + if (!name2) return 0; + /* dup data */ + data_size = size; + if (compress == 1) + data_size = 12 + ((size * 101) / 100); + data2 = malloc(data_size); + if (!data2) + { + free(name2); + return 0; + } + /* if we want to compress */ + if (compress == 1) + { + uLongf buflen; + + /* compress the data with max compression */ + if (compress2((Bytef *)data2, &buflen, (Bytef *)data, + (uLong)size, 9) != Z_OK) + { + free(name2); + free(data2); + return 0; + } + /* record compressed chunk size */ + data_size = (int)buflen; + if (data_size >= size) + { + compress = 0; + data_size = size; + } + } + if (!compress) + memcpy(data2, data, size); + /* increase hash bucket size */ + node = realloc(ef->header->directory->hash[hash].node, + (node_size + 1) * sizeof(Eet_File_Node)); + if (!node) + { + free(name2); + free(data2); + return 0; + } + /* resized node list set up */ + ef->header->directory->hash[hash].node = node; + /* new node at end */ + ef->header->directory->hash[hash].node[node_size].name = name2; + ef->header->directory->hash[hash].node[node_size].offset = 0; + ef->header->directory->hash[hash].node[node_size].compression = compress; + ef->header->directory->hash[hash].node[node_size].size = data_size; + ef->header->directory->hash[hash].node[node_size].data_size = size; + ef->header->directory->hash[hash].node[node_size].data = data2; + ef->header->directory->hash[hash].size++; + + /* flags that writes are pending */ + ef->writes_pending = 1; + /* update access time */ + return size; +} + +char ** +eet_list(Eet_File *ef, char *glob, int *count_ret) +{ + char **list_ret = NULL; + int list_count = 0; + int list_count_alloc = 0; + int i, j, num; + + /* check to see its' an eet file pointer */ + if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!glob)) + { + if (count_ret) *count_ret = 0; + return NULL; + } + /* loop through all entries */ + num = (1 << (ef->header->directory->size - 1)); + for (i = 0; i < num; i++) + { + for (j = 0; j < ef->header->directory->hash[i].size; j++) + { + /* if the entry matches the input glob */ + if (!fnmatch(glob, ef->header->directory->hash[i].node[j].name, 0)) + { + char **new_list; + + /* add it to our list */ + list_count++; + /* only realloc in 32 entry chunks */ + if (list_count > list_count_alloc) + { + list_count_alloc += 32; + new_list = realloc(list_ret, list_count_alloc * (sizeof(char *))); + if (!new_list) + { + free(list_ret); + if (count_ret) *count_ret = 0; + return NULL; + } + list_ret = new_list; + } + /* put pointer of name string in */ + list_ret[list_count - 1] = ef->header->directory->hash[i].node[j].name; + } + } + } + /* return count and list */ + if (count_ret) *count_ret = list_count; + return list_ret; +}