parent
4c824dfe92
commit
31660022d0
34
.cvsignore
34
.cvsignore
|
@ -1,34 +0,0 @@
|
|||
config.guess
|
||||
config.h.in
|
||||
config.sub
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
aclocal.m4
|
||||
stamp-h.in
|
||||
Makefile.in
|
||||
configure
|
||||
config.log
|
||||
config.h
|
||||
config.cache
|
||||
libtool
|
||||
config.status
|
||||
stamp-h
|
||||
Makefile
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
imlib2
|
||||
loaderpath.h
|
||||
*.tar.gz
|
||||
.icons
|
||||
imlib2-config
|
||||
dox
|
||||
install-sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
build-stamp
|
||||
configure-stamp
|
||||
stamp-h1
|
||||
autom4te.cache
|
||||
*.pc
|
30
AUTHORS
30
AUTHORS
|
@ -1,30 +0,0 @@
|
|||
The Rasterman (Carsten Haitzler) <raster@rasterman.com> <raster@valinux.com>
|
||||
Ryan Gustafson <ryan_gustafson@yahoo.com>
|
||||
Mandrake (Geoff Harrison) <mandrake@mandrake.net>
|
||||
Willem Monsuwe <willem@stack.nl>
|
||||
KainX (Michael Jennings) <mej@eterm.org>
|
||||
Eric Dorland <dorland@lords.com>
|
||||
Chutt (Isaac Richards) <ijr@po.cwru.edu>
|
||||
giblet (Tom Gilbert) <tom@linuxbrit.co.uk>
|
||||
Takis <takis@lumumba.luc.ac.be>
|
||||
Dan Maas <dmaas@dcine.com>
|
||||
Platon Fomichev <pla@cland.ru>
|
||||
boris (Chris Ross) <chris@darkrock.co.uk>
|
||||
Martin Grimm <grimm.martin@gmx.de>
|
||||
Matt McClanahan <cardinal@dodds.net>
|
||||
Steve Langasek <vorlon@dodds.net>
|
||||
Christophe Tronche <ch.tronche@computer.org>
|
||||
Nathan Ingersoll <ningerso@d.umn.edu>
|
||||
Masa(Masahiko) Mori <masa@engr.sgi.com>
|
||||
Term (Lyle Kempler) <term@twistedpath.org>
|
||||
Adam Kisiel <kisiel@if.pw.edu.pl>
|
||||
Carsten Pfeiffer <carpdjih@sp.zrz.tu-berlin.de>
|
||||
Lightman (Franz Marini) <marini@pcmenelao.mi.infn.it>
|
||||
Mark Bainter <mark-e@cymry.org>
|
||||
Brian Lindholm <brian_lindholm@users.sourceforge.net>
|
||||
Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
||||
Yuri Hudobin <glassy_ape@users.sourceforge.net>
|
||||
Radoslaw Grzanka <radekg2@poczta.onet.pl>
|
||||
Kim Woelders <kim@woelders.dk>
|
||||
Nick Blievers <nickb@sgi.com>
|
||||
Mike Castle <dalgoda@ix.netcom.com>
|
20
COPYING
20
COPYING
|
@ -1,20 +0,0 @@
|
|||
Copyright (C) 1999 Carsten Haitzler and various contributors
|
||||
|
||||
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.
|
139
Doxyfile
139
Doxyfile
|
@ -1,139 +0,0 @@
|
|||
PROJECT_NAME = Imlib2
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY = doc
|
||||
INPUT = imlib2.c
|
||||
IMAGE_PATH = doc/img
|
||||
OUTPUT_LANGUAGE = English
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = doc/head.html
|
||||
HTML_FOOTER = doc/foot.html
|
||||
HTML_STYLESHEET = doc/imlib2.css
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
ENUM_VALUES_PER_LINE = 1
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
HIDE_FRIEND_COMPOUNDS = YES
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
INTERNAL_DOCS = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
VERBATIM_HEADERS = NO
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 2
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SHOW_USED_FILES = NO
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
FILE_PATTERNS =
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 2
|
||||
IGNORE_PREFIX =
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
GENERATE_MAN = YES
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = YES
|
||||
GENERATE_XML = YES
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = NO
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
CLASS_DIAGRAMS = NO
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = NO
|
||||
COLLABORATION_GRAPH = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = NO
|
||||
INCLUDED_BY_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = NO
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 512
|
||||
MAX_DOT_GRAPH_HEIGHT = 512
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
SEARCHENGINE = NO
|
46
Makefile.am
46
Makefile.am
|
@ -1,46 +0,0 @@
|
|||
AUTOMAKE_OPTIONS = 1.4 foreign
|
||||
|
||||
MAINTAINERCLEANFILES = INSTALL Makefile.in aclocal.m4 config.guess \
|
||||
config.h.in config.sub configure install-sh \
|
||||
ltconfig ltmain.sh missing mkinstalldirs \
|
||||
stamp-h.in
|
||||
|
||||
SUBDIRS = src filters doc loaders test demo
|
||||
|
||||
bin_SCRIPTS = imlib2-config
|
||||
|
||||
EXTRA_DIST = \
|
||||
imlib2.spec \
|
||||
imlib2.pc.in \
|
||||
demo/Makefile.am \
|
||||
demo/Makefile.in \
|
||||
demo/view.c \
|
||||
demo/imconvert.c \
|
||||
test/Makefile.am \
|
||||
test/Makefile.in \
|
||||
test/main.c \
|
||||
test/test_images/cal.png \
|
||||
test/test_images/lock.png \
|
||||
test/test_images/paper.png \
|
||||
test/test_images/stop.png \
|
||||
test/test_images/audio.png \
|
||||
test/test_images/calc.png \
|
||||
test/test_images/mail.png \
|
||||
test/test_images/sh1.png \
|
||||
test/test_images/tnt.png \
|
||||
test/test_images/bg.png \
|
||||
test/test_images/folder.png \
|
||||
test/test_images/menu.png \
|
||||
test/test_images/sh2.png \
|
||||
test/test_images/bulb.png \
|
||||
test/test_images/globe.png \
|
||||
test/test_images/mush.png \
|
||||
test/test_images/sh3.png \
|
||||
test/ttfonts/cinema.ttf \
|
||||
test/ttfonts/grunge.ttf \
|
||||
test/ttfonts/morpheus.ttf \
|
||||
test/ttfonts/notepad.ttf
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = imlib2.pc
|
||||
|
41
README
41
README
|
@ -1,41 +0,0 @@
|
|||
###############################################################################
|
||||
# #
|
||||
# I M L I B 2 #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
This is the Imlib 2 library - a library that does image file loading and
|
||||
saving as well as rendering, manipulation, arbitrary polygon support, etc.
|
||||
|
||||
It does ALL of these operations FAST. Imlib2 also tries to be highly
|
||||
intelligent about doing them, so writing naive programs can be done
|
||||
easily, without sacrificing speed.
|
||||
|
||||
This is a complete rewrite over the Imlib 1.x series. The architecture is
|
||||
more modular, simple, and flexible. See index.html in the doc/ directory
|
||||
for more information.
|
||||
|
||||
Imlib2 requires several libraries to be already installed. These are:
|
||||
|
||||
libjpeg http://www.ijg.org/
|
||||
libpng http://www.libpng.org/pub/png/libpng.html
|
||||
freetype 2.1.x http://www.freetype.org/
|
||||
|
||||
|
||||
For examples of this library in use, seek:
|
||||
|
||||
Eterm http://www.eterm.org/ (CVS version only, currently)
|
||||
feh http://www.linuxbrit.co.uk/feh.html
|
||||
geist http://www.linuxbrit.co.uk/geist.html
|
||||
|
||||
|
||||
A blurb about each of the directories:
|
||||
|
||||
debian/ Debian build files
|
||||
demo/ Demo view program
|
||||
doc/ Documentation for imlib2, primarily in html
|
||||
filters/ Filter shared objects
|
||||
libltdl/ Libtool LGPL-licensed loadable module support library source
|
||||
loaders/ Imlib2's image loader-savers (jpg, png, etc)
|
||||
src/ Imlib2 main source
|
||||
test/ Test program(s)
|
6
TODO
6
TODO
|
@ -1,6 +0,0 @@
|
|||
* line code doesnt draw nice liens when clipping - fix
|
||||
* filled polygons can break fill bounds on corner cases - fix
|
||||
* go thru TODOs and FIXMEs
|
||||
|
||||
evas2 has fixed code for these 2 in it that work just fine. just need to
|
||||
port over (should be fairly easy).
|
13
autogen.sh
13
autogen.sh
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
rm -rf autom4te.cache
|
||||
rm -f aclocal.m4
|
||||
|
||||
echo "Running aclocal..."; aclocal $ACLOCAL_FLAGS -I m4 \
|
||||
&& echo "Running autoheader..."; autoheader \
|
||||
&& echo "Running autoconf..."; autoconf \
|
||||
&& echo "Running libtoolize..."; (libtoolize --automake || glibtoolize --automake) \
|
||||
&& echo "Running automake..."; automake --add-missing --copy --gnu
|
||||
|
||||
### If you want this, uncomment it.
|
||||
./configure "$@"
|
435
configure.in
435
configure.in
|
@ -1,435 +0,0 @@
|
|||
# get rid of that stupid cache mechanism
|
||||
rm -f config.cache
|
||||
|
||||
AC_INIT(configure.in)
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
AC_ISC_POSIX
|
||||
AM_INIT_AUTOMAKE(imlib2, 1.1.2)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
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", [Installation directory for user executables])
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${prefix}/bin", [Installation directory for user executables])
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${bindir}", [Installation directory for user executables])
|
||||
fi
|
||||
|
||||
if test "x${libdir}" = 'xNONE'; then
|
||||
if test "x${prefix}" = "xNONE"; then
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${ac_default_prefix}/lib", [Installation directory for libraries] )
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${prefix}/lib", [Installation directory for libraries])
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${libdir}", [Installation directory for libraries])
|
||||
fi
|
||||
|
||||
dnl Set PACKAGE_SOURCE_DIR in config.h.
|
||||
packagesrcdir=`cd $srcdir && pwd`
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}", [Source code directory])
|
||||
|
||||
|
||||
dnl here was freetype stuff (1)
|
||||
|
||||
# check for freetype
|
||||
|
||||
AC_ARG_WITH(freetype-config,
|
||||
[ --with-freetype-config=FREETYPE_CONFIG use freetype-config specified ],
|
||||
[
|
||||
PROG_CONFIG=$withval;
|
||||
echo "using "$PROG_CONFIG" for freetype-config";
|
||||
],[
|
||||
PROG="freetype-config";
|
||||
AC_PATH_PROG(PROG_CONFIG, $PROG, "", $PATH)
|
||||
])
|
||||
if [ test -z $PROG_CONFIG ]; then
|
||||
echo $PROG " is not in your \$PATH. Please ensure it is.";
|
||||
echo "You may need to install the library and/or development packages";
|
||||
echo "that contain this configure-script.";
|
||||
echo "FATAL ERROR. ABORT.";
|
||||
exit -1;
|
||||
fi
|
||||
freetype_cflags=`$PROG_CONFIG --cflags`
|
||||
freetype_libs=`$PROG_CONFIG --libs`
|
||||
|
||||
dnl /here was freetype stuff (1)
|
||||
|
||||
mmx=no
|
||||
AC_ARG_ENABLE(mmx,[ --enable-mmx attempt compiling using mmx assembly [default=yes]],
|
||||
[
|
||||
if test x$enableval = xyes; then
|
||||
mmx=yes
|
||||
fi
|
||||
],
|
||||
[
|
||||
if test x$target_os = xlinux-gnu; then
|
||||
mmx=`cat /proc/cpuinfo | grep mmx`
|
||||
if test -n "$mmx"; then
|
||||
mmx=yes
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "You are not running Linux - This script cannot auto-detect mmx assembly."
|
||||
echo "You will have to enable the mmx assembly (which gives anywhere from 10%"
|
||||
echo "to 300% speedups) by adding --enable-mmx on the configure command-line."
|
||||
echo ""
|
||||
fi
|
||||
]
|
||||
)
|
||||
if test x$mmx = xyes; then
|
||||
AC_DEFINE(DO_MMX_ASM, 1, [enabling MMX Assembly])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_MMX, test x$mmx = xyes)
|
||||
|
||||
pkglibdir='${libdir}'/imlib2_loaders
|
||||
AC_SUBST(pkglibdir)
|
||||
|
||||
#if test X"$enable_shared" = Xyes; then
|
||||
# DLLDFLAGS=-export-dynamic
|
||||
# AC_SUBST(DLLDFLAGS)
|
||||
#fi
|
||||
|
||||
dnl AM_PROG_AS
|
||||
ASFLAGS="$ASFLAGS -I../"
|
||||
AS=$CC
|
||||
AC_SUBST(ASFLAGS)
|
||||
AC_SUBST(AS)
|
||||
|
||||
CCASFLAGS="$ASFLAGS"
|
||||
CCAS="$AS"
|
||||
AC_SUBST(CCASFLAGS)
|
||||
AC_SUBST(CCAS)
|
||||
|
||||
|
||||
AC_MSG_CHECKING(whether fopen accepts "b" mode)
|
||||
AC_CACHE_VAL([ag_cv_func_fopen_binary],
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
FILE *fp = fopen("/bin/sh", "rb");
|
||||
return (fclose(fp) >= 0);
|
||||
}],[ag_cv_func_fopen_binary=yes],
|
||||
[ag_cv_func_fopen_binary=yes],[ag_cv_func_fopen_binary=yes])
|
||||
rm -f core *.exe.core])
|
||||
AC_MSG_RESULT([$ag_cv_func_fopen_binary])
|
||||
if test x$ag_cv_func_fopen_binary = xyes; then
|
||||
AC_DEFINE(USE_FOPEN_BINARY, 1,
|
||||
[Define this if we can use the "b" mode for fopen safely.])
|
||||
fi
|
||||
|
||||
AC_PATH_X
|
||||
AC_PATH_XTRA
|
||||
|
||||
if test "x$have_x" = "xdisabled"; then
|
||||
AC_MSG_WARN([Xlib support is disabled.])
|
||||
AM_CONDITIONAL(HAVE_X, false)
|
||||
XMISS="-DX_DISPLAY_MISSING"
|
||||
else
|
||||
AM_CONDITIONAL(HAVE_X, true)
|
||||
XMISS=""
|
||||
|
||||
if test "x$x_includes" = "x"; then
|
||||
x_includes="/usr/include"
|
||||
fi
|
||||
|
||||
x_cflags="$X_CFLAGS"
|
||||
x_ldflags="$X_LDFLAGS"
|
||||
x_libs="$X_LIBS $X_EXTRA_LIBS"
|
||||
X_OBJS="color.lo context.lo draw.lo grab.lo rend.lo rgba.lo ximage.lo"
|
||||
|
||||
AC_CHECK_LIB(X11, XOpenDisplay, x_libs="-lX11 $x_libs",
|
||||
AC_MSG_ERROR([ERROR: libX11 not found.]); exit,
|
||||
$X_LDFLAGS $X_EXTRA_LIBS $X_LIBS)
|
||||
AC_CHECK_LIB(Xext, XShmAttach, x_libs="-lXext $x_libs",
|
||||
AC_CHECK_LIB(XextSam, XShmAttach,
|
||||
x_libs="-lXextSam -lXext $x_libs",
|
||||
AC_MSG_ERROR([ERROR: XShm not found.]); exit,
|
||||
$x_libs),
|
||||
$x_libs)
|
||||
AC_CHECK_LIB(Xext, XShapeCombineMask, x_libs="-lXext $x_libs",
|
||||
AC_MSG_ERROR([ERROR: XShape not found.]); exit,
|
||||
$x_libs)
|
||||
fi
|
||||
AC_SUBST(XMISS)
|
||||
AC_SUBST(XDIR)
|
||||
AC_SUBST(X_OBJS)
|
||||
|
||||
# This is necessary so that .o files in LIBOBJS are also built via
|
||||
# the ANSI2KNR-filtering rules.
|
||||
dnl# Doesn't work with autoconf-2.13!
|
||||
dnl# LIB@&t@OBJS=`echo "$LIB@&t@OBJS" |
|
||||
dnl# sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'`
|
||||
LTLIBOBJS=`echo "$LIB@&t@OBJS" |
|
||||
sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
|
||||
AC_SUBST(LTLIBOBJS)
|
||||
|
||||
dnl here was freetype headers checking
|
||||
|
||||
|
||||
|
||||
dnl /here was freetype headers checking
|
||||
|
||||
AC_CHECK_LIB(dl, dlopen, dlopen_libs=-ldl)
|
||||
AC_CHECK_LIB(ltdl, lt_dlopen, ltdlopen_libs=-lltdl)
|
||||
|
||||
EXTRA_LIBS="-L/usr/local/lib -L/usr/X11R6/lib"
|
||||
|
||||
# Test for libjpeg
|
||||
AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
|
||||
jpeg_ok=yes,
|
||||
jpeg_ok=no
|
||||
AC_MSG_WARN(*** Native JPEG support will not be built (JPEG library not found) ***), $EXTRA_LIBS)
|
||||
if test "$jpeg_ok" = yes; then
|
||||
AC_MSG_CHECKING([for jpeglib.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <jpeglib.h>],
|
||||
jpeg_ok=yes,
|
||||
jpeg_ok=no)
|
||||
AC_MSG_RESULT($jpeg_ok)
|
||||
if test "$jpeg_ok" = yes; then
|
||||
JPEGLIBS="-ljpeg"
|
||||
else
|
||||
AC_MSG_WARN(*** Native JPEG support will not be built (JPEG header file not found) ***)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test for libpng
|
||||
AC_CHECK_LIB(png, png_read_info,
|
||||
png_ok=yes,
|
||||
png_ok=no
|
||||
AC_MSG_WARN(*** Native PNG support will not be built (PNG library not found) ***), $EXTRA_LIBS -lz -lm)
|
||||
if test "$png_ok" = yes; then
|
||||
AC_MSG_CHECKING([for png.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <png.h>],
|
||||
png_ok=yes,
|
||||
png_ok=no)
|
||||
AC_MSG_RESULT($png_ok)
|
||||
if test "$png_ok" = yes; then
|
||||
PNGLIBS="-lpng -lz -lm"
|
||||
REQUIREMENTS=libpng12
|
||||
else
|
||||
AC_MSG_WARN(*** Native PNG support will not be built (PNG header file not found) ***)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test for libtiff
|
||||
AC_CHECK_LIB(tiff, TIFFReadScanline,
|
||||
tiff_libs="-ltiff"
|
||||
tiff_ok=yes,
|
||||
AC_CHECK_LIB(tiff, TIFFWriteScanline,
|
||||
tiff_libs="-ltiff -ljpeg -lz -lm"
|
||||
tiff_ok=yes,
|
||||
AC_CHECK_LIB(tiff34, TIFFFlushData,
|
||||
tiff_libs="-ltiff -ljpeg -lz -lm"
|
||||
tiff_ok=yes,
|
||||
tiff_ok=no
|
||||
AC_MSG_WARN(*** Native TIFF support will not be built (TIFF library not found) ***),
|
||||
$EXTRA_LIBS -ljpeg -lz -lm),
|
||||
$EXTRA_LIBS -ljpeg -lz -lm),
|
||||
$EXTRA_LIBS)
|
||||
if test "$tiff_ok" = yes; then
|
||||
AC_MSG_CHECKING([for tiffio.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <tiffio.h>],
|
||||
tiff_ok=yes,
|
||||
tiff_ok=no)
|
||||
AC_MSG_RESULT($tiff_ok)
|
||||
if test "$tiff_ok" = yes; then
|
||||
TIFFLIBS=$tiff_libs
|
||||
else
|
||||
AC_MSG_WARN(*** Native TIFF support will not be built (TIFF header file not found) ***)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test for libungif
|
||||
AC_CHECK_LIB(ungif, DGifOpenFileName,
|
||||
gif_libs="-lungif"
|
||||
gif_ok=yes,
|
||||
gif_ok=no,
|
||||
$EXTRA_LIBS -lX11)
|
||||
if test "$gif_ok" = yes; then
|
||||
AC_MSG_CHECKING([for gif_lib.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <gif_lib.h>],
|
||||
gif_ok=yes,
|
||||
gif_ok=no)
|
||||
AC_MSG_RESULT($gif_ok)
|
||||
if test "$gif_ok" = yes; then
|
||||
GIFLIBS=$gif_libs
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test for libgif
|
||||
if test "$gif_ok" = no; then
|
||||
AC_CHECK_LIB(gif, DGifOpenFileName,
|
||||
gif_libs="-lgif"
|
||||
gif_ok=yes,
|
||||
gif_ok=no
|
||||
AC_MSG_WARN(*** Native GIF support will not be built (GIF library not found) ***),
|
||||
$EXTRA_LIBS)
|
||||
if test "$gif_ok" = yes; then
|
||||
AC_MSG_CHECKING([for gif_lib.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <gif_lib.h>],
|
||||
gif_ok=yes,
|
||||
gif_ok=no)
|
||||
AC_MSG_RESULT($gif_ok)
|
||||
if test "$gif_ok" = yes; then
|
||||
GIFLIBS=$gif_libs
|
||||
else
|
||||
AC_MSG_WARN(*** Native GIF support will not be built (GIF header file not found) ***)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test for zlib
|
||||
AC_CHECK_LIB(z, uncompress,
|
||||
zlib_ok=yes,
|
||||
zlib_ok=no
|
||||
AC_MSG_WARN(*** Native zlib support will not be built (zlib not found) ***), $EXTRA_LIBS -lz)
|
||||
if test "$zlib_ok" = yes; then
|
||||
AC_MSG_CHECKING([for zlib.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <zlib.h>],
|
||||
zlib_ok=yes,
|
||||
zlib_ok=no)
|
||||
AC_MSG_RESULT($zlib_ok)
|
||||
if test "$zlib_ok" = yes; then
|
||||
ZLIBLIBS="-lz"
|
||||
else
|
||||
AC_MSG_WARN(*** Native zlib support will not be built (zlib header file not found) ***)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test for libbzip2
|
||||
AC_CHECK_LIB(bz2, BZ2_bzRead,
|
||||
bz2_ok=yes,
|
||||
bz2_ok=no
|
||||
AC_MSG_WARN(*** Native bz2 support will not be built (bzip2 library not found) ***), $EXTRA_LIBS -lbz2)
|
||||
if test "$bz2_ok" = yes; then
|
||||
AC_MSG_CHECKING([for bzlib.h])
|
||||
AC_TRY_CPP(
|
||||
[#include <stdio.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include <bzlib.h>],
|
||||
bz2_ok=yes,
|
||||
bz2_ok=no)
|
||||
AC_MSG_RESULT($bz2_ok)
|
||||
if test "$bz2_ok" = yes; then
|
||||
BZ2LIBS="-lbz2"
|
||||
else
|
||||
AC_MSG_WARN(*** Native bz2 support will not be built (bzip2 header file not found) ***)
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(JPEG_LOADER, test "$jpeg_ok" = yes)
|
||||
AM_CONDITIONAL(PNG_LOADER, test "$png_ok" = yes)
|
||||
AM_CONDITIONAL(TIFF_LOADER, test "$tiff_ok" = yes)
|
||||
AM_CONDITIONAL(GIF_LOADER, test "$gif_ok" = yes)
|
||||
AM_CONDITIONAL(ZLIB_LOADER, test "$zlib_ok" = yes)
|
||||
AM_CONDITIONAL(BZ2_LOADER, test "$bz2_ok" = yes)
|
||||
|
||||
AC_SUBST(JPEGLIBS)
|
||||
AC_SUBST(PNGLIBS)
|
||||
AC_SUBST(TIFFLIBS)
|
||||
AC_SUBST(GIFLIBS)
|
||||
AC_SUBST(ZLIBLIBS)
|
||||
AC_SUBST(BZ2LIBS)
|
||||
AC_SUBST(REQUIREMENTS)
|
||||
|
||||
AC_SUBST(x_cflags)
|
||||
AC_SUBST(x_includes)
|
||||
AC_SUBST(x_ldflags)
|
||||
AC_SUBST(x_libs)
|
||||
AC_SUBST(dlopen_libs)
|
||||
AC_SUBST(ltdlopen_libs)
|
||||
AC_SUBST(freetype_cflags)
|
||||
AC_SUBST(freetype_libs)
|
||||
|
||||
dnl AC_SUBST(freetype_libs)
|
||||
dnl AC_SUBST(freetype_includes)
|
||||
|
||||
dnl# This stuff is not compatible with autoconf-2.13
|
||||
dnl# AC_CONFIG_FILES([imlib2-config imlib2.pc Makefile loaders/Makefile src/Makefile test/Makefile \
|
||||
dnl# filters/Makefile demo/Makefile doc/Makefile libltdl/Makefile \
|
||||
dnl# ])
|
||||
dnl# AC_CONFIG_COMMANDS([default],[[
|
||||
dnl# chmod +x imlib2-config
|
||||
dnl# ]],[[]])
|
||||
dnl# AC_OUTPUT
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
loaders/Makefile
|
||||
src/Makefile
|
||||
test/Makefile
|
||||
filters/Makefile
|
||||
demo/Makefile
|
||||
doc/Makefile
|
||||
imlib2-config
|
||||
imlib2.pc
|
||||
],[
|
||||
chmod +x imlib2-config
|
||||
])
|
|
@ -1,11 +0,0 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
files
|
||||
libimlib2
|
||||
libimlib2-dev
|
||||
libimlib2-dev.postinst.debhelper
|
||||
libimlib2-dev.prerm.debhelper
|
||||
libimlib2.postinst.debhelper
|
||||
libimlib2.postrm.debhelper
|
||||
libimlib2.substvars
|
||||
tmp
|
|
@ -1,9 +0,0 @@
|
|||
EXTRA_DIST = \
|
||||
changelog \
|
||||
control \
|
||||
copyright \
|
||||
imlib2-config.1 \
|
||||
libimlib2-dev.doc-base \
|
||||
libimlib2.files \
|
||||
libimlib2-dev.files \
|
||||
rules
|
|
@ -1,5 +0,0 @@
|
|||
imlib2 (1.1.2-0cvs20040918) unstable; urgency=low
|
||||
|
||||
* a CVS release
|
||||
|
||||
-- Sytse Wielinga <s.b.wielinga@student.utwente.nl> Sat, 18 Sep 2004 12:48:44 +0200
|
|
@ -1,44 +0,0 @@
|
|||
Source: imlib2
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Maintainer: Laurence J. Lane <ljlane@debian.org>
|
||||
Build-Depends: libjpeg62-dev, libttf-dev, libpng3-dev | libpng2-dev | libpng-dev, libtiff4-dev | libtiff-dev, zlib1g-dev, libungif4-dev | libungif3g-dev | giflib3g-dev, xlibs-dev, libfreetype6-dev | freetype2-dev, libbz2-dev, libltdl3-dev, automake1.7 | automaken, libtool, debhelper (>= 4.0)
|
||||
Standards-Version: 3.5.7.0
|
||||
|
||||
Package: imlib2-demo
|
||||
Architecture: any
|
||||
Section: graphics
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: Imlib2 demo's
|
||||
This package contains two small Imlib2-based programs: a simple
|
||||
image viewer and a simple image conversion program.
|
||||
|
||||
Package: imlib2-test
|
||||
Architecture: any
|
||||
Section: graphics
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: Imlib2 test programs
|
||||
This package contains some, not generally usable, test programs
|
||||
for Imlib2.
|
||||
|
||||
Package: libimlib2
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}
|
||||
Suggests: imlib2-loaders, imlib2-demo (= ${Source-Version})
|
||||
Description: Powerful image loading and rendering library
|
||||
Imlib2 is an advanced replacement library for libraries like
|
||||
libXpm that provides many more features with much greater
|
||||
flexibility and speed than standard libraries, including font
|
||||
rasterization, rotation, RGBA space rendering and blending,
|
||||
dynamic binary filters, scripting, and more.
|
||||
.
|
||||
Imlib2 is not a drop-in replacement for Imlib 1.x.
|
||||
|
||||
Package: libimlib2-dev
|
||||
Architecture: any
|
||||
Section: devel
|
||||
Architecture: any
|
||||
Depends: libimlib2 (= ${Source-Version}), libc6-dev | libc-dev, libjpeg62-dev, libpng3-dev | libpng2-dev | libpng-dev, libtiff4-dev | libtiff-dev, zlib1g-dev, libttf-dev, libungif4-dev | libungif3g-dev | giflib3g-dev, xlibs-dev, libfreetype6-dev | freetype2-dev, libbz2-dev
|
||||
Description: Imlib2 headers, static libraries and documentation
|
||||
Headers, static libraries and documentation for Imlib2.
|
|
@ -1,32 +0,0 @@
|
|||
This package was debianized by Laurence J. Lane <ljlane@debian.org> on
|
||||
Sat, 28 Oct 2000 17:56:46 -0400.
|
||||
|
||||
The source code is from the e17/libs/imlib2 module of the enlightenment CVS
|
||||
tree. For more information, see:
|
||||
|
||||
http://www.enlightenment.org/cvs.html
|
||||
|
||||
Upstream Author: Carsten Haitzler <raster@rasterman.com>
|
||||
|
||||
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.
|
|
@ -1,17 +0,0 @@
|
|||
.TH imlib2-config 1 "29 Oct 2000" imlib2-config
|
||||
.SH NAME
|
||||
.HP
|
||||
imlib2-config - imlib2 build information script
|
||||
.SH SYNOPSIS
|
||||
.HP
|
||||
imlib2-config [options]
|
||||
.P
|
||||
.SH DESCRIPTION
|
||||
.HP
|
||||
.I imlib2-config
|
||||
is a script that's used by make and other build enviroments to
|
||||
gather imlib2 information.
|
||||
.HP
|
||||
Run
|
||||
.I imlib2-config
|
||||
for additional information.
|
|
@ -1,2 +0,0 @@
|
|||
usr/bin/imconvert
|
||||
usr/bin/imlib2_view
|
|
@ -1,5 +0,0 @@
|
|||
usr/bin/imlib2
|
||||
usr/bin/imlib2_test
|
||||
usr/bin/bumpmaptest
|
||||
usr/bin/color_spaces
|
||||
usr/bin/polytest
|
|
@ -1,10 +0,0 @@
|
|||
Document: imlib2
|
||||
Title: Imlib2 Guide
|
||||
Author: Carsten Haitzler
|
||||
Abstract: This document describes Imlib2 API
|
||||
and provides sample C code.
|
||||
Section: Apps/Programming
|
||||
|
||||
Format: HTML
|
||||
Index: /usr/share/doc/libimlib2-dev/html/index.html
|
||||
Files: /usr/share/doc/libimlib2-dev/html/index.html
|
|
@ -1,10 +0,0 @@
|
|||
usr/bin/imlib2-config
|
||||
usr/lib/pkgconfig/*
|
||||
usr/include
|
||||
usr/lib/*.so
|
||||
usr/lib/*.a
|
||||
usr/lib/*.la
|
||||
usr/lib/imlib2_loaders/filter/*.a
|
||||
usr/lib/imlib2_loaders/filter/*.la
|
||||
usr/lib/imlib2_loaders/image/*.a
|
||||
usr/lib/imlib2_loaders/image/*.la
|
|
@ -1,3 +0,0 @@
|
|||
usr/lib/*.so.*
|
||||
usr/lib/imlib2_loaders/filter/*.so
|
||||
usr/lib/imlib2_loaders/image/*.so
|
|
@ -1,88 +0,0 @@
|
|||
#!/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 compatability version to use.
|
||||
export DH_COMPAT=4
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
CFLAGS ?= -Wall -g
|
||||
|
||||
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -O0
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
||||
INSTALL_PROGRAM += -s
|
||||
endif
|
||||
ifneq (,$(findstring mmx,$(DEB_BUILD_OPTIONS)))
|
||||
ENABLE_MMX = yes
|
||||
else
|
||||
ENABLE_MMX = no
|
||||
endif
|
||||
|
||||
INSTALL=/usr/bin/install -p
|
||||
CONFIGUREOPTS = --prefix=/usr --enable-mmx=$(ENABLE_MMX) --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
|
||||
package=libimlib2
|
||||
|
||||
configure: configure-stamp
|
||||
configure-stamp:
|
||||
test -x autogen.sh && ./autogen.sh $(CONFIGUREOPTS) || ./configure $(CONFIGUREOPTS)
|
||||
touch configure-stamp
|
||||
|
||||
build: build-stamp
|
||||
build-stamp: configure-stamp
|
||||
dh_testdir
|
||||
$(MAKE)
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
rm -f build-stamp configure-stamp
|
||||
|
||||
-$(MAKE) distclean
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp/
|
||||
|
||||
$(INSTALL) -d debian/$(package)-dev/usr/share/doc/$(package)-dev/html
|
||||
$(INSTALL) -m 644 doc/*.html doc/*.gif \
|
||||
debian/$(package)-dev/usr/share/doc/$(package)-dev/html
|
||||
|
||||
binary-indep: build install
|
||||
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_install --sourcedir=debian/tmp --list-missing
|
||||
|
||||
dh_installdocs AUTHORS README
|
||||
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 configure
|
|
@ -1,26 +0,0 @@
|
|||
config.guess
|
||||
imconvert
|
||||
config.h.in
|
||||
config.sub
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
aclocal.m4
|
||||
stamp-h.in
|
||||
Makefile.in
|
||||
configure
|
||||
config.log
|
||||
config.h
|
||||
config.cache
|
||||
libtool
|
||||
config.status
|
||||
stamp-h
|
||||
Makefile
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
imlib2
|
||||
loaderpath.h
|
||||
imlib2_blend
|
||||
imlib2_view
|
||||
.icons
|
|
@ -1,28 +0,0 @@
|
|||
## 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 =
|
||||
INCLUDES = -I. -I$(top_srcdir) -I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/loaders -I$(top_srcdir)/libltdl \
|
||||
-I/usr/X11R6/include $(X_CFLAGS) \
|
||||
-I$(prefix)/include -I$(includedir)
|
||||
|
||||
if HAVE_X
|
||||
|
||||
LDADD = $(top_builddir)/src/libImlib2.la
|
||||
|
||||
bin_PROGRAMS = imlib2_view imconvert
|
||||
|
||||
imconvert_SOURCES = imconvert.c
|
||||
imconvert_LDFLAGS = $(LDFLAGS) -L/usr/X11R6/lib
|
||||
|
||||
imlib2_view_SOURCES = view.c
|
||||
imlib2_view_LDFLAGS = $(LDFLAGS) -L/usr/X11R6/lib
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST = imconvert.c view.c
|
|
@ -1,91 +0,0 @@
|
|||
/* Convert images between formats, using Imlib2's API. Smart enough to know
|
||||
* about edb files; defaults to jpg's.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <Imlib2.h>
|
||||
|
||||
#define PROG_NAME "imconvert"
|
||||
|
||||
static void usage(int exit_status);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *dot, *colon, *n, *oldn;
|
||||
Imlib_Image im;
|
||||
|
||||
/* I'm just plain being lazy here.. get our basename. */
|
||||
for (oldn = n = argv[0]; n; oldn = n)
|
||||
n = strchr(++oldn, '/');
|
||||
if (argc < 3 || !strcmp(argv[1], "-h"))
|
||||
usage(-1);
|
||||
if ((im = imlib_load_image(argv[1])) == NULL)
|
||||
{
|
||||
fprintf(stderr, PROG_NAME ": Error loading image: %s\n", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* we only care what format the export format is. */
|
||||
imlib_context_set_image(im);
|
||||
/* hopefully the last one will be the one we want.. */
|
||||
dot = strrchr(argv[2], '.');
|
||||
/* if there's a format, snarf it and set the format. */
|
||||
if (dot && *(dot + 1))
|
||||
{
|
||||
colon = strrchr(++dot, ':');
|
||||
/* if a db file with a key, export it to a db. */
|
||||
if (colon && *(colon + 1))
|
||||
{
|
||||
*colon = 0;
|
||||
/* beats having to look for strcasecmp() */
|
||||
if (!strncmp(dot, "db", 2) || !strncmp(dot, "dB", 2) ||
|
||||
!strncmp(dot, "DB", 2) || !strncmp(dot, "Db", 2))
|
||||
{
|
||||
imlib_image_set_format("db");
|
||||
}
|
||||
*colon = ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p, *q;
|
||||
|
||||
/* max length of 8 for format name. seems reasonable. */
|
||||
q = p = malloc(8);
|
||||
memset(p, 0, 8);
|
||||
strncpy(p, dot, (strlen(dot) < 9) ? strlen(dot) : 8);
|
||||
/* Imlib2 only recognizes lowercase formats. convert it. */
|
||||
for (q[8] = 0; *q; q++)
|
||||
*q = tolower(*q);
|
||||
imlib_image_set_format(p);
|
||||
free(p);
|
||||
}
|
||||
dot--;
|
||||
}
|
||||
else
|
||||
imlib_image_set_format("jpg");
|
||||
|
||||
imlib_save_image(argv[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(int exit_status)
|
||||
{
|
||||
fprintf(exit_status ? stderr : stdout,
|
||||
PROG_NAME ": Convert images between formats (part of the "
|
||||
"Imlib2 package)\n\n"
|
||||
"Usage: " PROG_NAME " [ -h | <image1> <image2[.fmt]> ]\n"
|
||||
" <fmt> defaults to jpg if not provided; images in "
|
||||
"edb files are supported via\n"
|
||||
" the file.db:/key/name convention.\n"
|
||||
" -h shows this help.\n\n");
|
||||
|
||||
exit(exit_status);
|
||||
}
|
345
demo/view.c
345
demo/view.c
|
@ -1,345 +0,0 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "Imlib2.h"
|
||||
|
||||
Display *disp;
|
||||
Window win;
|
||||
Pixmap pm = 0;
|
||||
Visual *vis;
|
||||
Colormap cm;
|
||||
int depth;
|
||||
int image_width = 0, image_height = 0;
|
||||
Imlib_Image bg_im = NULL;
|
||||
|
||||
static int
|
||||
progress(Imlib_Image im, char percent, int update_x, int update_y,
|
||||
int update_w, int update_h);
|
||||
|
||||
static int
|
||||
progress(Imlib_Image im, char percent, int update_x, int update_y,
|
||||
int update_w, int update_h)
|
||||
{
|
||||
/* first time it's called */
|
||||
imlib_context_set_drawable(pm);
|
||||
imlib_context_set_anti_alias(0);
|
||||
imlib_context_set_dither(0);
|
||||
imlib_context_set_blend(0);
|
||||
if (image_width == 0)
|
||||
{
|
||||
int x, y, onoff;
|
||||
|
||||
imlib_context_set_image(im);
|
||||
image_width = imlib_image_get_width();
|
||||
image_height = imlib_image_get_height();
|
||||
if (pm)
|
||||
XFreePixmap(disp, pm);
|
||||
pm = XCreatePixmap(disp, win, image_width, image_height, depth);
|
||||
imlib_context_set_drawable(pm);
|
||||
if (bg_im)
|
||||
{
|
||||
imlib_context_set_image(bg_im);
|
||||
imlib_free_image_and_decache();
|
||||
}
|
||||
bg_im = imlib_create_image(image_width, image_height);
|
||||
imlib_context_set_image(bg_im);
|
||||
for (y = 0; y < image_height; y += 8)
|
||||
{
|
||||
onoff = (y / 8) & 0x1;
|
||||
for (x = 0; x < image_width; x += 8)
|
||||
{
|
||||
if (onoff)
|
||||
imlib_context_set_color(144, 144, 144, 255);
|
||||
else
|
||||
imlib_context_set_color(100, 100, 100, 255);
|
||||
imlib_image_fill_rectangle(x, y, 8, 8);
|
||||
onoff++;
|
||||
if (onoff == 2)
|
||||
onoff = 0;
|
||||
}
|
||||
}
|
||||
imlib_render_image_part_on_drawable_at_size(0, 0, image_width,
|
||||
image_height, 0, 0,
|
||||
image_width, image_height);
|
||||
XSetWindowBackgroundPixmap(disp, win, pm);
|
||||
XResizeWindow(disp, win, image_width, image_height);
|
||||
XMapWindow(disp, win);
|
||||
XSync(disp, False);
|
||||
}
|
||||
imlib_context_set_anti_alias(0);
|
||||
imlib_context_set_dither(0);
|
||||
imlib_context_set_blend(1);
|
||||
imlib_blend_image_onto_image(im, 0,
|
||||
update_x, update_y,
|
||||
update_w, update_h,
|
||||
update_x, update_y, update_w, update_h);
|
||||
imlib_context_set_blend(0);
|
||||
imlib_render_image_part_on_drawable_at_size(update_x, update_y,
|
||||
update_w, update_h,
|
||||
update_x, update_y,
|
||||
update_w, update_h);
|
||||
XSetWindowBackgroundPixmap(disp, win, pm);
|
||||
XClearArea(disp, win, update_x, update_y, update_w, update_h, False);
|
||||
XFlush(disp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Imlib_Image *im = NULL;
|
||||
char *file = NULL;
|
||||
int no = 1;
|
||||
|
||||
if (argc < 2)
|
||||
return 1;
|
||||
|
||||
file = argv[no];
|
||||
disp = XOpenDisplay(NULL);
|
||||
vis = DefaultVisual(disp, DefaultScreen(disp));
|
||||
depth = DefaultDepth(disp, DefaultScreen(disp));
|
||||
cm = DefaultColormap(disp, DefaultScreen(disp));
|
||||
win = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 0, 0, 10, 10,
|
||||
0, 0, 0);
|
||||
XSelectInput(disp, win, ButtonPressMask | ButtonReleaseMask |
|
||||
ButtonMotionMask | PointerMotionMask);
|
||||
imlib_context_set_display(disp);
|
||||
imlib_context_set_visual(vis);
|
||||
imlib_context_set_colormap(cm);
|
||||
imlib_context_set_progress_function(progress);
|
||||
imlib_context_set_progress_granularity(10);
|
||||
imlib_context_set_drawable(win);
|
||||
im = imlib_load_image(file);
|
||||
while (!im)
|
||||
{
|
||||
no++;
|
||||
if (no == argc)
|
||||
exit(0);
|
||||
file = argv[no];
|
||||
image_width = 0;
|
||||
im = imlib_load_image(file);
|
||||
imlib_context_set_image(im);
|
||||
}
|
||||
if (!im)
|
||||
{
|
||||
fprintf(stderr, "Image format not available\n");
|
||||
exit(0);
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
int x, y, b, count, fdsize, xfd, timeout = 0;
|
||||
XEvent ev;
|
||||
static int zoom_mode = 0, zx, zy;
|
||||
static double zoom = 1.0;
|
||||
struct timeval tval;
|
||||
fd_set fdset;
|
||||
double t1;
|
||||
|
||||
XFlush(disp);
|
||||
while (XPending(disp))
|
||||
{
|
||||
XNextEvent(disp, &ev);
|
||||
switch (ev.type)
|
||||
{
|
||||
case ButtonPress:
|
||||
b = ev.xbutton.button;
|
||||
x = ev.xbutton.x;
|
||||
y = ev.xbutton.y;
|
||||
if (b == 3)
|
||||
{
|
||||
zoom_mode = 1;
|
||||
zx = x;
|
||||
zy = y;
|
||||
imlib_context_set_drawable(pm);
|
||||
imlib_context_set_image(bg_im);
|
||||
imlib_context_set_anti_alias(0);
|
||||
imlib_context_set_dither(0);
|
||||
imlib_context_set_blend(0);
|
||||
imlib_render_image_part_on_drawable_at_size
|
||||
(0, 0, image_width, image_height,
|
||||
0, 0, image_width, image_height);
|
||||
XSetWindowBackgroundPixmap(disp, win, pm);
|
||||
XClearWindow(disp, win);
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
b = ev.xbutton.button;
|
||||
x = ev.xbutton.x;
|
||||
y = ev.xbutton.y;
|
||||
if (b == 3)
|
||||
zoom_mode = 0;
|
||||
if (b == 1)
|
||||
{
|
||||
no++;
|
||||
if (no == argc)
|
||||
no = argc - 1;
|
||||
file = argv[no];
|
||||
image_width = 0;
|
||||
zoom = 1.0;
|
||||
zoom_mode = 0;
|
||||
imlib_context_set_image(im);
|
||||
imlib_free_image_and_decache();
|
||||
im = imlib_load_image(file);
|
||||
while (!im)
|
||||
{
|
||||
no++;
|
||||
if (no == argc)
|
||||
exit(0);
|
||||
file = argv[no];
|
||||
image_width = 0;
|
||||
im = imlib_load_image(file);
|
||||
}
|
||||
imlib_context_set_image(im);
|
||||
}
|
||||
if (b == 2)
|
||||
{
|
||||
no--;
|
||||
if (no == 0)
|
||||
no = 1;
|
||||
file = argv[no];
|
||||
image_width = 0;
|
||||
zoom = 1.0;
|
||||
zoom_mode = 0;
|
||||
imlib_context_set_image(im);
|
||||
imlib_free_image_and_decache();
|
||||
im = imlib_load_image(file);
|
||||
while (!im)
|
||||
{
|
||||
no--;
|
||||
if (no == 0)
|
||||
no = 1;
|
||||
file = argv[no];
|
||||
image_width = 0;
|
||||
im = imlib_load_image(file);
|
||||
}
|
||||
imlib_context_set_image(im);
|
||||
}
|
||||
break;
|
||||
case MotionNotify:
|
||||
while (XCheckTypedWindowEvent
|
||||
(disp, win, MotionNotify, &ev));
|
||||
x = ev.xmotion.x;
|
||||
y = ev.xmotion.y;
|
||||
if (zoom_mode)
|
||||
{
|
||||
int sx, sy, sw, sh, dx, dy, dw, dh;
|
||||
|
||||
zoom = ((double)x - (double)zx) / 32.0;
|
||||
if (zoom < 0)
|
||||
zoom = 1.0 + ((zoom * 32.0) / ((double)(zx + 1)));
|
||||
else
|
||||
zoom += 1.0;
|
||||
if (zoom <= 0.0001)
|
||||
zoom = 0.0001;
|
||||
if (zoom > 1.0)
|
||||
{
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
dw = image_width;
|
||||
dh = image_height;
|
||||
|
||||
sx = zx - (zx / zoom);
|
||||
sy = zy - (zy / zoom);
|
||||
sw = image_width / zoom;
|
||||
sh = image_height / zoom;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = zx - (zx * zoom);
|
||||
dy = zy - (zy * zoom);
|
||||
dw = image_width * zoom;
|
||||
dh = image_height * zoom;
|
||||
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sw = image_width;
|
||||
sh = image_height;
|
||||
}
|
||||
imlib_context_set_anti_alias(0);
|
||||
imlib_context_set_dither(0);
|
||||
imlib_context_set_blend(0);
|
||||
imlib_context_set_image(bg_im);
|
||||
imlib_render_image_part_on_drawable_at_size
|
||||
(sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
XSetWindowBackgroundPixmap(disp, win, pm);
|
||||
XClearWindow(disp, win);
|
||||
XFlush(disp);
|
||||
timeout = 1;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
t1 = 0.2;
|
||||
tval.tv_sec = (long)t1;
|
||||
tval.tv_usec = (long)((t1 - ((double)tval.tv_sec)) * 1000000);
|
||||
xfd = ConnectionNumber(disp);
|
||||
fdsize = xfd + 1;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(xfd, &fdset);
|
||||
if (timeout)
|
||||
count = select(fdsize, &fdset, NULL, NULL, &tval);
|
||||
else
|
||||
count = select(fdsize, &fdset, NULL, NULL, NULL);
|
||||
if (count < 0)
|
||||
{
|
||||
if ((errno == ENOMEM) || (errno == EINVAL)
|
||||
|| (errno == EBADF))
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((count == 0) && (timeout))
|
||||
{
|
||||
int sx, sy, sw, sh, dx, dy, dw, dh;
|
||||
|
||||
if (zoom > 1.0)
|
||||
{
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
dw = image_width;
|
||||
dh = image_height;
|
||||
|
||||
sx = zx - (zx / zoom);
|
||||
sy = zy - (zy / zoom);
|
||||
sw = image_width / zoom;
|
||||
sh = image_height / zoom;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = zx - (zx * zoom);
|
||||
dy = zy - (zy * zoom);
|
||||
dw = image_width * zoom;
|
||||
dh = image_height * zoom;
|
||||
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sw = image_width;
|
||||
sh = image_height;
|
||||
}
|
||||
imlib_context_set_anti_alias(1);
|
||||
imlib_context_set_dither(1);
|
||||
imlib_context_set_blend(0);
|
||||
imlib_context_set_image(bg_im);
|
||||
imlib_render_image_part_on_drawable_at_size
|
||||
(sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
XSetWindowBackgroundPixmap(disp, win, pm);
|
||||
XClearWindow(disp, win);
|
||||
XFlush(disp);
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
Makefile
|
||||
Makefile.in
|
|
@ -1,3 +0,0 @@
|
|||
EXTRA_DIST = imlib2.gif \
|
||||
blank.gif \
|
||||
index.html
|
BIN
doc/blank.gif
BIN
doc/blank.gif
Binary file not shown.
Before Width: | Height: | Size: 266 B |
|
@ -1,2 +0,0 @@
|
|||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<title>$title</title>
|
||||
<link href=imlib2.css rel=stylesheet type=text/css>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class=nav>
|
||||
<table border=0 align=center><tr>
|
||||
<td width=16><img src=imlib2_mini.png width=16 height=16 alt=E></td>
|
||||
<td width=100% align=center>
|
||||
I : M : L : I : B : 2
|
||||
</td>
|
||||
<td width=16><img src=imlib2_mini.png width=16 height=16 alt=E></td>
|
||||
</tr></table>
|
||||
</div>
|
Binary file not shown.
Before Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 753 B |
178
doc/imlib2.css
178
doc/imlib2.css
|
@ -1,178 +0,0 @@
|
|||
td.md {
|
||||
background-color: #ffffff;
|
||||
font-family: monospace;
|
||||
text-align: left;
|
||||
vertical-align: center;
|
||||
font-size: 10;
|
||||
padding-right : 1px;
|
||||
padding-top : 1px;
|
||||
padding-left : 1px;
|
||||
padding-bottom : 1px;
|
||||
margin-left : 1px;
|
||||
margin-right : 1px;
|
||||
margin-top : 1px;
|
||||
margin-bottom : 1px
|
||||
}
|
||||
td.mdname {
|
||||
font-family: monospace;
|
||||
text-align: left;
|
||||
vertical-align: center;
|
||||
font-size: 10;
|
||||
padding-right : 1px;
|
||||
padding-top : 1px;
|
||||
padding-left : 1px;
|
||||
padding-bottom : 1px;
|
||||
margin-left : 1px;
|
||||
margin-right : 1px;
|
||||
margin-top : 1px;
|
||||
margin-bottom : 1px
|
||||
}
|
||||
h1
|
||||
{
|
||||
text-align: center;
|
||||
color: #333333
|
||||
}
|
||||
h2
|
||||
{
|
||||
text-align: left;
|
||||
color: #333333
|
||||
}
|
||||
h3
|
||||
{
|
||||
text-align: left;
|
||||
color: #333333
|
||||
}
|
||||
a:link
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #444444;
|
||||
font-weight: bold;
|
||||
}
|
||||
a:visited
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #666666;
|
||||
font-weight: bold;
|
||||
}
|
||||
a:hover
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
}
|
||||
a.nav:link
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #444444;
|
||||
font-weight: normal;
|
||||
}
|
||||
a.nav:visited
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #666666;
|
||||
font-weight: normal;
|
||||
}
|
||||
a.nav:hover
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
}
|
||||
a.qindex:link
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #444444;
|
||||
font-weight: normal;
|
||||
}
|
||||
a.qindex:visited
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #666666;
|
||||
font-weight: normal;
|
||||
}
|
||||
a.qindex:hover
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
}
|
||||
p
|
||||
{
|
||||
color: #000000;
|
||||
font-family: sans-serif;
|
||||
font-size: 10;
|
||||
}
|
||||
body {
|
||||
background-image: url("hilite.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
background-color: #dddddd;
|
||||
color: #000000;
|
||||
font-family: sans-serif;
|
||||
padding: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
div.fragment
|
||||
{
|
||||
background-image: url("hilite.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
border: thin solid #888888;
|
||||
background-color: #eeeeee;
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
vertical-align: center;
|
||||
font-size: 12;
|
||||
}
|
||||
hr
|
||||
{
|
||||
border: 0;
|
||||
background-color: #000000;
|
||||
width: 80%;
|
||||
height: 1;
|
||||
}
|
||||
dl
|
||||
{
|
||||
background-image: url("hilite.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
border: thin solid #aaaaaa;
|
||||
background-color: #eeeeee;
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
vertical-align: center;
|
||||
font-size: 12;
|
||||
}
|
||||
em
|
||||
{
|
||||
color: #334466;
|
||||
font-family: courier;
|
||||
font-size: 10;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.nav
|
||||
{
|
||||
border: thin solid #000000;
|
||||
background-color: #ffffff;
|
||||
padding: 1px;
|
||||
text-align: center;
|
||||
vertical-align: center;
|
||||
font-size: 12;
|
||||
}
|
||||
div.body
|
||||
{
|
||||
border: thin solid #000000;
|
||||
background-color: #ffffff;
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
font-size: 10;
|
||||
}
|
||||
div.diag
|
||||
{
|
||||
border: thin solid #888888;
|
||||
background-color: #eeeeee;
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
font-size: 8;
|
||||
}
|
BIN
doc/imlib2.gif
BIN
doc/imlib2.gif
Binary file not shown.
Before Width: | Height: | Size: 6.6 KiB |
2268
doc/index.html
2268
doc/index.html
File diff suppressed because it is too large
Load Diff
|
@ -1,21 +0,0 @@
|
|||
config.guess
|
||||
config.h.in
|
||||
config.sub
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
aclocal.m4
|
||||
stamp-h.in
|
||||
Makefile.in
|
||||
configure
|
||||
config.log
|
||||
config.h
|
||||
config.cache
|
||||
libtool
|
||||
config.status
|
||||
stamp-h
|
||||
Makefile
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
.icons
|
|
@ -1,27 +0,0 @@
|
|||
## 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$(top_builddir)/src -L$(top_builddir)/src/.libs -L/usr/X11R6/lib
|
||||
INCLUDES = -I. -I$(top_srcdir) -I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/loaders \
|
||||
-I/usr/X11R6/include $(X_CFLAGS) \
|
||||
-I$(prefix)/include -I$(includedir)
|
||||
|
||||
pkgdir = $(libdir)/imlib2_loaders/filter
|
||||
pkg_LTLIBRARIES = testfilter.la bump_map.la colormod.la
|
||||
|
||||
testfilter_la_SOURCES = filter_test.c
|
||||
testfilter_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
testfilter_la_LIBADD = -lImlib2
|
||||
|
||||
bump_map_la_SOURCES = filter_bumpmap.c
|
||||
bump_map_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
bump_map_la_LIBADD = -lImlib2
|
||||
|
||||
colormod_la_SOURCES = filter_colormod.c
|
||||
colormod_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
colormod_la_LIBADD = -lImlib2
|
|
@ -1,292 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include "image.h"
|
||||
#include "script.h"
|
||||
#include "dynamic_filters.h"
|
||||
#include "colormod.h"
|
||||
#include "blend.h"
|
||||
|
||||
#define PI (4 * atan(1))
|
||||
|
||||
static Imlib_Image
|
||||
bump_map(Imlib_Image im, pIFunctionParam par)
|
||||
{
|
||||
Imlib_Image map = im;
|
||||
pIFunctionParam ptr;
|
||||
double an = 0, el = 30, d = 0x200;
|
||||
double red = 0x200, green = 0x200, blue = 0x200;
|
||||
double ambient = 0;
|
||||
|
||||
int free_map = 0;
|
||||
DATA32 *src;
|
||||
DATA32 *mp, *mpy, *mpp;
|
||||
double z, z_2, x2, y2;
|
||||
int w, h, i, j, w2, h2, wh2, mx, my;
|
||||
|
||||
for (ptr = par; ptr; ptr = ptr->next)
|
||||
{
|
||||
ASSIGN_IMAGE("map", map);
|
||||
ASSIGN_INT("angle", an);
|
||||
ASSIGN_INT("elevation", el);
|
||||
ASSIGN_INT("depth", d);
|
||||
ASSIGN_INT("red", red);
|
||||
ASSIGN_INT("green", green);
|
||||
ASSIGN_INT("blue", blue);
|
||||
ASSIGN_INT("ambient", ambient);
|
||||
}
|
||||
if (!map)
|
||||
return im;
|
||||
|
||||
red /= 0x100;
|
||||
green /= 0x100;
|
||||
blue /= 0x100;
|
||||
ambient /= 0x100;
|
||||
d /= 0x100;
|
||||
|
||||
imlib_context_set_image(im);
|
||||
src = imlib_image_get_data();
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
|
||||
imlib_context_set_image(map);
|
||||
mpp = imlib_image_get_data_for_reading_only();
|
||||
w2 = imlib_image_get_width();
|
||||
h2 = imlib_image_get_height();
|
||||
wh2 = w2 * h2;
|
||||
|
||||
an *= (PI / 180);
|
||||
el *= (PI / 180);
|
||||
|
||||
x2 = sin(an) * cos(el);
|
||||
y2 = cos(an) * cos(el);
|
||||
z = sin(el);
|
||||
|
||||
d /= (255 * (255 + 255 + 255));
|
||||
z_2 = z * z;
|
||||
|
||||
my = h2;
|
||||
for (j = h; --j >= 0;)
|
||||
{
|
||||
mp = mpp;
|
||||
mpp += w2;
|
||||
if (--my <= 0)
|
||||
{
|
||||
mpp -= wh2;
|
||||
my = h2;
|
||||
}
|
||||
mpy = mpp;
|
||||
mx = w2;
|
||||
for (i = w; --i >= 0;)
|
||||
{
|
||||
double x1, y1, v;
|
||||
int r, g, b, gr;
|
||||
|
||||
gr = A_VAL(mp) * (R_VAL(mp) + G_VAL(mp) + B_VAL(mp));
|
||||
y1 = d * (double)(A_VAL(mpy) * (R_VAL(mpy) +
|
||||
G_VAL(mpy) + B_VAL(mpy)) - gr);
|
||||
mp++;
|
||||
mpy++;
|
||||
if (--mx <= 0)
|
||||
{
|
||||
mp -= w2;
|
||||
mpy -= w2;
|
||||
mx = w2;
|
||||
}
|
||||
x1 = d * (double)(A_VAL(mp) * (R_VAL(mp) +
|
||||
G_VAL(mp) + B_VAL(mp)) - gr);
|
||||
v = x1 * x2 + y1 * y2 + z;
|
||||
v /= sqrt((x1 * x1) + (y1 * y1) + 1.0);
|
||||
v += ambient;
|
||||
r = v * R_VAL(src) * red;
|
||||
g = v * G_VAL(src) * green;
|
||||
b = v * B_VAL(src) * blue;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
R_VAL(src) = r;
|
||||
G_VAL(src) = g;
|
||||
B_VAL(src) = b;
|
||||
|
||||
src++;
|
||||
}
|
||||
}
|
||||
if (free_map)
|
||||
{
|
||||
imlib_context_set_image(map);
|
||||
imlib_free_image();
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
static Imlib_Image
|
||||
bump_map_point(Imlib_Image im, pIFunctionParam par)
|
||||
{
|
||||
Imlib_Image map = im;
|
||||
pIFunctionParam ptr;
|
||||
double x = 0, y = 0, z = 30, d = 0x200;
|
||||
double red = 0x200, green = 0x200, blue = 0x200;
|
||||
double ambient = 0;
|
||||
|
||||
int free_map = 0;
|
||||
DATA32 *src;
|
||||
DATA32 *mp, *mpy, *mpp;
|
||||
double z_2, x2, y2;
|
||||
int w, h, i, j, w2, h2, wh2, mx, my;
|
||||
|
||||
for (ptr = par; ptr; ptr = ptr->next)
|
||||
{
|
||||
ASSIGN_IMAGE("map", map);
|
||||
ASSIGN_INT("x", x);
|
||||
ASSIGN_INT("y", y);
|
||||
ASSIGN_INT("z", z);
|
||||
ASSIGN_INT("depth", d);
|
||||
ASSIGN_INT("red", red);
|
||||
ASSIGN_INT("green", green);
|
||||
ASSIGN_INT("blue", blue);
|
||||
ASSIGN_INT("ambient", ambient);
|
||||
}
|
||||
if (!map)
|
||||
return im;
|
||||
|
||||
red /= 0x100;
|
||||
green /= 0x100;
|
||||
blue /= 0x100;
|
||||
ambient /= 0x100;
|
||||
d /= 0x100;
|
||||
|
||||
imlib_context_set_image(im);
|
||||
src = imlib_image_get_data();
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
|
||||
imlib_context_set_image(map);
|
||||
mpp = imlib_image_get_data_for_reading_only();
|
||||
w2 = imlib_image_get_width();
|
||||
h2 = imlib_image_get_height();
|
||||
wh2 = w2 * h2;
|
||||
|
||||
d /= (255 * (255 + 255 + 255));
|
||||
z_2 = z * z;
|
||||
|
||||
my = h2;
|
||||
y2 = -y;
|
||||
for (j = h; --j >= 0;)
|
||||
{
|
||||
mp = mpp;
|
||||
mpp += w2;
|
||||
if (--my <= 0)
|
||||
{
|
||||
mpp -= wh2;
|
||||
my = h2;
|
||||
}
|
||||
mpy = mpp;
|
||||
mx = w2;
|
||||
x2 = -x;
|
||||
for (i = w; --i >= 0;)
|
||||
{
|
||||
double x1, y1, v;
|
||||
int r, g, b, gr;
|
||||
|
||||
gr = A_VAL(mp) * (R_VAL(mp) + G_VAL(mp) + B_VAL(mp));
|
||||
y1 = d * (double)(A_VAL(mpy) * (R_VAL(mpy) +
|
||||
G_VAL(mpy) + B_VAL(mpy)) - gr);
|
||||
mp++;
|
||||
mpy++;
|
||||
if (--mx <= 0)
|
||||
{
|
||||
mp -= w2;
|
||||
mpy -= w2;
|
||||
mx = w2;
|
||||
}
|
||||
x1 = d * (double)(A_VAL(mp) * (R_VAL(mp) +
|
||||
G_VAL(mp) + B_VAL(mp)) - gr);
|
||||
v = x1 * x2 + y1 * y2 + z;
|
||||
v /= sqrt((x1 * x1) + (y1 * y1) + 1.0);
|
||||
v /= sqrt((x2 * x2) + (y2 * y2) + z_2);
|
||||
v += ambient;
|
||||
r = v * R_VAL(src) * red;
|
||||
g = v * G_VAL(src) * green;
|
||||
b = v * B_VAL(src) * blue;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
R_VAL(src) = r;
|
||||
G_VAL(src) = g;
|
||||
B_VAL(src) = b;
|
||||
|
||||
x2++;
|
||||
src++;
|
||||
}
|
||||
y2++;
|
||||
}
|
||||
if (free_map)
|
||||
{
|
||||
imlib_context_set_image(map);
|
||||
imlib_free_image();
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
init(struct imlib_filter_info *info)
|
||||
{
|
||||
char *filters[] = { "bump_map_point", "bump_map" };
|
||||
int i = (sizeof(filters) / sizeof(*filters));
|
||||
|
||||
info->name = strdup("Bump Mapping");
|
||||
info->author = strdup("Willem Monsuwe (willem@stack.nl)");
|
||||
info->description =
|
||||
strdup
|
||||
("Provides bumpmapping to a point and bumpmapping from an infinite light source. *very* cool.");
|
||||
info->num_filters = i;
|
||||
info->filters = malloc(sizeof(char *) * i);
|
||||
while (--i >= 0)
|
||||
info->filters[i] = strdup(filters[i]);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
deinit()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void *
|
||||
exec(char *filter, void *im, pIFunctionParam par)
|
||||
{
|
||||
if (!strcmp(filter, "bump_map"))
|
||||
return bump_map((Imlib_Image) im, par);
|
||||
if (!strcmp(filter, "bump_map_point"))
|
||||
return bump_map_point((Imlib_Image) im, par);
|
||||
return im;
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include "image.h"
|
||||
#include "script.h"
|
||||
#include "dynamic_filters.h"
|
||||
|
||||
#define GET_INT(x, ptr) (((ptr)->type == VAR_PTR) ? \
|
||||
(x) = (*(int *)(ptr)->data) : \
|
||||
((ptr)->type == VAR_CHAR) ? \
|
||||
(x) = strtol((ptr)->data, 0, 0) \
|
||||
: 0)
|
||||
|
||||
#define GET_DOUBLE(x, ptr) (((ptr)->type == VAR_PTR) ? \
|
||||
(x) = (*(double *)(ptr)->data) : \
|
||||
((ptr)->type == VAR_CHAR) ? \
|
||||
(x) = strtod((ptr)->data, 0) \
|
||||
: 0)
|
||||
|
||||
static void
|
||||
mod_brightness(double t[256], double v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 256; --i >= 0;)
|
||||
t[i] += v;
|
||||
}
|
||||
|
||||
static void
|
||||
mod_contrast(double t[256], double v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 256; --i >= 0;)
|
||||
t[i] = ((t[i] - 0.5) * v) + 0.5;
|
||||
}
|
||||
|
||||
static void
|
||||
mod_gamma(double t[256], double v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 256; --i >= 0;)
|
||||
t[i] = pow(t[i], 1 / v);
|
||||
}
|
||||
|
||||
static void
|
||||
mod_tint(double t[256], double v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 256; --i >= 0;)
|
||||
t[i] *= v;
|
||||
}
|
||||
|
||||
static Imlib_Image
|
||||
colormod(Imlib_Image im, pIFunctionParam par)
|
||||
{
|
||||
double a_d[256], r_d[256], g_d[256], b_d[256];
|
||||
DATA8 a_b[256], r_b[256], g_b[256], b_b[256];
|
||||
pIFunctionParam ptr;
|
||||
int x = 0, y = 0, h, w, i;
|
||||
double v = 0.0;
|
||||
|
||||
imlib_context_set_image(im);
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
|
||||
for (i = 256; --i >= 0;)
|
||||
a_d[i] = r_d[i] = g_d[i] = b_d[i] = (double)i / 255;
|
||||
|
||||
for (ptr = par; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (!strcmp("x", ptr->key))
|
||||
{
|
||||
GET_INT(x, ptr);
|
||||
}
|
||||
else if (!strcmp("y", ptr->key))
|
||||
{
|
||||
GET_INT(y, ptr);
|
||||
}
|
||||
else if (!strcmp("w", ptr->key))
|
||||
{
|
||||
GET_INT(w, ptr);
|
||||
}
|
||||
else if (!strcmp("h", ptr->key))
|
||||
{
|
||||
GET_INT(h, ptr);
|
||||
}
|
||||
else if (!memcmp("brightness", ptr->key, 10))
|
||||
{
|
||||
GET_DOUBLE(v, ptr);
|
||||
if (!ptr->key[10])
|
||||
{
|
||||
mod_brightness(r_d, v);
|
||||
mod_brightness(g_d, v);
|
||||
mod_brightness(b_d, v);
|
||||
mod_brightness(a_d, v);
|
||||
}
|
||||
else if (!strcmp("_r", ptr->key + 10))
|
||||
{
|
||||
mod_brightness(r_d, v);
|
||||
}
|
||||
else if (!strcmp("_g", ptr->key + 10))
|
||||
{
|
||||
mod_brightness(g_d, v);
|
||||
}
|
||||
else if (!strcmp("_b", ptr->key + 10))
|
||||
{
|
||||
mod_brightness(b_d, v);
|
||||
}
|
||||
else if (!strcmp("_a", ptr->key + 10))
|
||||
{
|
||||
mod_brightness(a_d, v);
|
||||
}
|
||||
}
|
||||
else if (!memcmp("contrast", ptr->key, 8))
|
||||
{
|
||||
GET_DOUBLE(v, ptr);
|
||||
if (!ptr->key[8])
|
||||
{
|
||||
mod_contrast(r_d, v);
|
||||
mod_contrast(g_d, v);
|
||||
mod_contrast(b_d, v);
|
||||
mod_contrast(a_d, v);
|
||||
}
|
||||
else if (!strcmp("_r", ptr->key + 8))
|
||||
{
|
||||
mod_contrast(r_d, v);
|
||||
}
|
||||
else if (!strcmp("_g", ptr->key + 8))
|
||||
{
|
||||
mod_contrast(g_d, v);
|
||||
}
|
||||
else if (!strcmp("_b", ptr->key + 8))
|
||||
{
|
||||
mod_contrast(b_d, v);
|
||||
}
|
||||
else if (!strcmp("_a", ptr->key + 8))
|
||||
{
|
||||
mod_contrast(a_d, v);
|
||||
}
|
||||
}
|
||||
else if (!memcmp("gamma", ptr->key, 5))
|
||||
{
|
||||
GET_DOUBLE(v, ptr);
|
||||
if (!ptr->key[5])
|
||||
{
|
||||
mod_gamma(r_d, v);
|
||||
mod_gamma(g_d, v);
|
||||
mod_gamma(b_d, v);
|
||||
mod_gamma(a_d, v);
|
||||
}
|
||||
else if (!strcmp("_r", ptr->key + 5))
|
||||
{
|
||||
mod_gamma(r_d, v);
|
||||
}
|
||||
else if (!strcmp("_g", ptr->key + 5))
|
||||
{
|
||||
mod_gamma(g_d, v);
|
||||
}
|
||||
else if (!strcmp("_b", ptr->key + 5))
|
||||
{
|
||||
mod_gamma(b_d, v);
|
||||
}
|
||||
else if (!strcmp("_a", ptr->key + 5))
|
||||
{
|
||||
mod_gamma(a_d, v);
|
||||
}
|
||||
}
|
||||
else if (!memcmp("tint", ptr->key, 4))
|
||||
{
|
||||
GET_DOUBLE(v, ptr);
|
||||
if (!ptr->key[4])
|
||||
{
|
||||
mod_tint(r_d, v);
|
||||
mod_tint(g_d, v);
|
||||
mod_tint(b_d, v);
|
||||
mod_tint(a_d, v);
|
||||
}
|
||||
else if (!strcmp("_r", ptr->key + 4))
|
||||
{
|
||||
mod_tint(r_d, v);
|
||||
}
|
||||
else if (!strcmp("_g", ptr->key + 4))
|
||||
{
|
||||
mod_tint(g_d, v);
|
||||
}
|
||||
else if (!strcmp("_b", ptr->key + 4))
|
||||
{
|
||||
mod_tint(b_d, v);
|
||||
}
|
||||
else if (!strcmp("_a", ptr->key + 4))
|
||||
{
|
||||
mod_tint(a_d, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 256; --i >= 0;)
|
||||
{
|
||||
if (a_d[i] < 0)
|
||||
a_d[i] = 0;
|
||||
if (a_d[i] > 1)
|
||||
a_d[i] = 1;
|
||||
a_b[i] = a_d[i] * 255;
|
||||
if (r_d[i] < 0)
|
||||
r_d[i] = 0;
|
||||
if (r_d[i] > 1)
|
||||
r_d[i] = 1;
|
||||
r_b[i] = r_d[i] * 255;
|
||||
if (g_d[i] < 0)
|
||||
g_d[i] = 0;
|
||||
if (g_d[i] > 1)
|
||||
g_d[i] = 1;
|
||||
g_b[i] = g_d[i] * 255;
|
||||
if (b_d[i] < 0)
|
||||
b_d[i] = 0;
|
||||
if (b_d[i] > 1)
|
||||
b_d[i] = 1;
|
||||
b_b[i] = b_d[i] * 255;
|
||||
}
|
||||
imlib_context_set_color_modifier(imlib_create_color_modifier());
|
||||
imlib_set_color_modifier_tables(r_b, g_b, b_b, a_b);
|
||||
imlib_apply_color_modifier_to_rectangle(x, y, w, h);
|
||||
imlib_free_color_modifier();
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
init(struct imlib_filter_info *info)
|
||||
{
|
||||
char *filters[] = { "colormod" };
|
||||
int i = (sizeof(filters) / sizeof(*filters));
|
||||
|
||||
info->name = strdup("Tinting");
|
||||
info->author = strdup("Willem Monsuwe (willem@stack.nl)");
|
||||
info->description =
|
||||
strdup("Provides most common color modification filters.");
|
||||
info->num_filters = i;
|
||||
info->filters = malloc(sizeof(char *) * i);
|
||||
while (--i >= 0)
|
||||
info->filters[i] = strdup(filters[i]);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
deinit()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void *
|
||||
exec(char *filter, void *im, pIFunctionParam par)
|
||||
{
|
||||
if (!strcmp(filter, "colormod"))
|
||||
return colormod((Imlib_Image) im, par);
|
||||
return im;
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
#include "image.h"
|
||||
#include "script.h"
|
||||
#include "dynamic_filters.h"
|
||||
|
||||
void init(struct imlib_filter_info *info);
|
||||
void deinit(void);
|
||||
void *exec(char *filter, void *im, pIFunctionParam params);
|
||||
|
||||
void
|
||||
init(struct imlib_filter_info *info)
|
||||
{
|
||||
char *filters[] = { "tint", "cool_text", "gradient" };
|
||||
int i = 0;
|
||||
|
||||
info->name = strdup("Test Filter");
|
||||
info->author = strdup("Chris Ross - Boris - chris@darkrock.co.uk");
|
||||
info->description =
|
||||
strdup
|
||||
("This filter is used to show that the imlib2 filter system works!");
|
||||
info->num_filters = 3;
|
||||
info->filters = malloc(sizeof(char *) * 3);
|
||||
for (i = 0; i < info->num_filters; i++)
|
||||
info->filters[i] = strdup(filters[i]);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
deinit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void *
|
||||
exec(char *filter, void *im, pIFunctionParam params)
|
||||
{
|
||||
Imlib_Image imge = im;
|
||||
Imlib_Image anoim;
|
||||
IFunctionParam *ptr;
|
||||
|
||||
if (strcmp(filter, "tint") == 0)
|
||||
{
|
||||
Imlib_Color_Modifier cm;
|
||||
DATA8 atab[256];
|
||||
int x = 0, y = 0, w = 0, h = 0;
|
||||
DATA8 r = 255, b = 255, g = 255, a = 255;
|
||||
|
||||
/*
|
||||
printf( "filter_test.c: tint called\n" );
|
||||
*/
|
||||
/* Set friendly defaults */
|
||||
imlib_context_set_image(imge);
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
|
||||
for (ptr = params; ptr != NULL; ptr = ptr->next)
|
||||
{
|
||||
ASSIGN_DATA8("red", r);
|
||||
ASSIGN_DATA8("blue", b);
|
||||
ASSIGN_DATA8("green", g);
|
||||
ASSIGN_INT("x", x);
|
||||
ASSIGN_INT("y", y);
|
||||
ASSIGN_INT("w", w);
|
||||
ASSIGN_INT("h", h);
|
||||
ASSIGN_DATA8("alpha", a);
|
||||
}
|
||||
/*
|
||||
printf( "Using values red=%d,blue=%d,green=%d,x=%d,y=%d,height=%d,width=%d,alpha=%d\n", r,b,g,x,y,w,h,a );
|
||||
*/
|
||||
anoim = imlib_create_image(w, h);
|
||||
cm = imlib_create_color_modifier();
|
||||
imlib_context_set_color_modifier(cm);
|
||||
imlib_context_set_image(anoim);
|
||||
|
||||
imlib_context_set_color(r, g, b, 255);
|
||||
imlib_image_fill_rectangle(0, 0, w, h);
|
||||
imlib_context_set_blend(1);
|
||||
imlib_image_set_has_alpha(1);
|
||||
|
||||
memset(atab, a, sizeof(atab));
|
||||
imlib_set_color_modifier_tables(NULL, NULL, NULL, atab);
|
||||
imlib_apply_color_modifier_to_rectangle(0, 0, w, h);
|
||||
|
||||
imlib_context_set_image(imge);
|
||||
imlib_blend_image_onto_image(anoim, 0, 0, 0, w, h, x, y, w, h);
|
||||
|
||||
imlib_free_color_modifier();
|
||||
imlib_context_set_image(anoim);
|
||||
imlib_free_image_and_decache();
|
||||
imlib_context_set_image(imge);
|
||||
|
||||
return imge;
|
||||
}
|
||||
|
||||
if (strcmp(filter, "cool_text") == 0)
|
||||
{
|
||||
return imge;
|
||||
}
|
||||
if (strcmp(filter, "gradient") == 0)
|
||||
{
|
||||
int angle = 0;
|
||||
|
||||
for (ptr = params; ptr != NULL; ptr = ptr->next)
|
||||
{
|
||||
ASSIGN_INT("angle", angle);
|
||||
}
|
||||
return imge;
|
||||
}
|
||||
return imge;
|
||||
}
|
17
gendoc
17
gendoc
|
@ -1,17 +0,0 @@
|
|||
#!/bin/sh
|
||||
cp ./imlib2.c.in ./imlib2.c
|
||||
|
||||
for I in `find ./src -name "api.c" -print`; do
|
||||
cat $I >> ./imlib2.c
|
||||
done
|
||||
|
||||
#for I in `find ./src/lib -name "*.c" -print`; do
|
||||
# cat $I >> ./imlib2.c
|
||||
#done
|
||||
rm -rf ./doc/html ./doc/latex ./doc/man
|
||||
doxygen
|
||||
cp doc/img/*.png doc/html/
|
||||
rm -f imlib2_docs.tar imlib2_docs.tar.gz
|
||||
tar -cvf imlib2_docs.tar doc/html doc/man doc/latex
|
||||
gzip -9 imlib2_docs.tar
|
||||
exit 0
|
|
@ -1,59 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
exec_prefix_set=no
|
||||
|
||||
usage="\
|
||||
Usage: imlib2-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 @x_cflags@
|
||||
;;
|
||||
--libs)
|
||||
libdirs=-L@libdir@
|
||||
echo $libdirs -lImlib2 @freetype_libs@ -lm @dlopen_libs@ @x_ldflags@ @x_libs@
|
||||
;;
|
||||
*)
|
||||
echo "${usage}" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
exit 0
|
547
imlib2.c.in
547
imlib2.c.in
|
@ -1,547 +0,0 @@
|
|||
/**
|
||||
@file
|
||||
@brief Imlib2 library
|
||||
|
||||
Brief of imlib2 library
|
||||
*/
|
||||
/**
|
||||
|
||||
@mainpage Imlib2 Library Documentation
|
||||
@image html imlib2.png
|
||||
@version 1.1.1
|
||||
@author Carsten Haitzler <raster@rasterman.com>
|
||||
@date 1999-2004
|
||||
|
||||
@section intro What is Imlib2 ?
|
||||
|
||||
|
||||
Imlib 2 is the successor to Imlib. It is NOT a newer version - it is a completely new library. Imlib 2 can be installed alongside Imlib 1.x without any problems since they are effectively different libraries - BUT they Have very similar functionality.
|
||||
|
||||
Imlib 2 does the following:
|
||||
|
||||
\li Load image files from disk in one of many formats
|
||||
\li Save images to disk in one of many formats
|
||||
\li Render image data onto other images
|
||||
\li Render images to an X-Windows drawable
|
||||
\li Produce pixmaps and pixmap masks of Images
|
||||
\li Apply filters to images
|
||||
\li Rotate images
|
||||
\li Accept RGBA Data for images
|
||||
\li Scale images
|
||||
\li Alpha blend Images on other images or drawables
|
||||
\li Apply color correction and modification tables and factors to images
|
||||
\li Render images onto images with color correction and modification tables
|
||||
\li Render truetype anti-aliased text
|
||||
\li Render truetype anti-aliased text at any angle
|
||||
\li Render anti-aliased lines
|
||||
\li Render rectangles
|
||||
\li Render linear multi-colored gradients
|
||||
\li Cache data intelligently for maximum performance
|
||||
\li Allocate colors automatically
|
||||
\li Allow full control over caching and color allocation
|
||||
\li Provide highly optimized MMX assembly for core routines
|
||||
\li Provide plug-in filter interface
|
||||
\li Provide on-the-fly runtime plug-in image loading and saving interface
|
||||
\li Fastest image compositing, rendering and manipulation library for X
|
||||
|
||||
If what you want isn't in the list above somewhere then likely Imlib 2 does not do it. If it does it it likely does it faster than any other library you can find (this includes gdk-pixbuf, gdkrgb, etc.) primarily because of highly optimized code and a smart subsystem that does the dirty work for you and picks up the pieces for you so you can be lazy and let all the optimizations for FOR you.
|
||||
|
||||
Imlib 2 can run without a display, so it can be easily used for background image processing for web sites or servers - it only requires the X libraries to be installed - that is all - it does not require an XServer to run unless you wish to display images.
|
||||
|
||||
The interface is simple - once you get used to it, the functions do exactly what they say they do.
|
||||
|
||||
@section first_ex A Simple Example
|
||||
|
||||
The best way to start is to show a simple example of an Imlib2
|
||||
program. This one will load an image of any format you have a loader
|
||||
installed for (all loaders are dynamic code objects that Imlib2 will
|
||||
use and update automatically runtime - anyone is free to write a
|
||||
loader. All that has to be done is for the object to be dropped into
|
||||
the loaders directory with the others and all Imlib2 programs will
|
||||
automatically be able to use it - without a restart).
|
||||
|
||||
@code
|
||||
/* main program */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* an image handle */
|
||||
Imlib_Image image;
|
||||
|
||||
/* if we provided < 2 arguments after the command - exit */
|
||||
if (argc != 3) exit(1);
|
||||
/* load the image */
|
||||
image = imlib_load_image(argv[1]);
|
||||
/* if the load was successful */
|
||||
if (image)
|
||||
{
|
||||
char *tmp;
|
||||
/* set the image we loaded as the current context image to work on */
|
||||
imlib_context_set_image(image);
|
||||
/* set the image format to be the format of the extension of our last */
|
||||
/* argument - i.e. .png = png, .tif = tiff etc. */
|
||||
tmp = strrchr(argv[2], '.');
|
||||
if(tmp)
|
||||
imlib_image_set_format(tmp + 1);
|
||||
/* save the image */
|
||||
imlib_save_image(argv[2]);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
Now to compile this
|
||||
|
||||
@verbatim
|
||||
cc imlib2_convert.c -o imlib2_convert `imlib2-config --cflags` `imlib2-config --libs`
|
||||
@endverbatim
|
||||
|
||||
You now have a program that if used as follows:
|
||||
|
||||
@verbatim
|
||||
cc imlib2_con
|
||||
./imlib2_convert image1.jpg image2.png
|
||||
@endverbatim
|
||||
|
||||
will convert image1.jpg into a png called image2.png. It is that simple.
|
||||
|
||||
@section loading How Image Loading Works
|
||||
|
||||
It is probably a good idea to discuss how Imlib2 actually loads an Image so the programmer knows what is going on, how to take advantage of the optimizations already there and to explain why things work as they do.
|
||||
|
||||
@subsection load_func Loading using imlib_load_image();
|
||||
|
||||
This is likely to be by far the most common way to load an image - when you don't really care about the details of the loading process or why it failed - all you care about is if you got a valid image handle.
|
||||
|
||||
When you call this function Imlib2 attempts to find the file specified as the parameter. This will involve Imlib2 first checking to see if that file path already has been loaded and is in Imlib2's cache (a cache of already decoded images in memory to save having to load and decode from disk all the time). If there already is a copy in the cache (either already active or speculatively cached from a previous load & free) this copy will have its handle returned instead of Imlib2 checking on disk (in some circumstances this is not true - see later in this section to find out). This means if your program blindly loads an Image, renders it, then frees it - then soon afterwards loads the same image again, it will not be loaded from disk at all, instead it will simply be re-referenced from the cache - meaning the load will be almost instant. A great way to take full advantage of this is to set the cache to some size you are happy with for the image data being used by your application and then all rendering o an image follows the pseudo code:
|
||||
|
||||
@verbatim
|
||||
set cache to some amount (e.g. 4 Mb)
|
||||
...
|
||||
rendering loop ...
|
||||
load image
|
||||
render image
|
||||
free image
|
||||
... continue loop
|
||||
@endverbatim
|
||||
|
||||
This may normally sound silly - load image, render then free - EVERY time we want to use it, BUT - it is actually the smartest way to use Imlib2 - since the caching will find the image for you in the cache - you do not need to manage your own cache, or worry about filling up memory with image data - only as much memory as you have set for the cache size will actually ever be used to store image data - if you have lots of image data to work with then increase the cache size for better performance, but this is the only thing you need to worry about. you won't have problems of accidentally forgetting to free images later since you free them immediately after use.
|
||||
|
||||
Now what happens if the file changes on disk while it's in cache? By default nothing. The file is ignored. This is an optimization (to avoid hitting the disk to check if the file changed for every load if it's cached). You can inform Imlib2 that you care about this by using the imlib_image_set_changes_on_disk(); call. Do this whenever you load an Image that you expect will change on disk, and the fact that it changes really matters. Remember this will marginally reduce the caching performance.
|
||||
|
||||
Now what actually happens when we try and load an image using a
|
||||
filename? First the filename is broken down into 2 parts. the filename
|
||||
before a colon (:) and the key after the colon. This means when we
|
||||
have a filename like:
|
||||
|
||||
@verbatim
|
||||
/path/to/file.jpg
|
||||
@endverbatim
|
||||
|
||||
the filename is:
|
||||
|
||||
@verbatim
|
||||
/path/to/file.jpg
|
||||
@endverbatim
|
||||
|
||||
and the key is blank. If we have:
|
||||
|
||||
@verbatim
|
||||
/path/to/file.db:key.value/blah
|
||||
@endverbatim
|
||||
|
||||
the filename is:
|
||||
|
||||
@verbatim
|
||||
/path/to/file.db
|
||||
@endverbatim
|
||||
|
||||
and the key is:
|
||||
|
||||
@verbatim
|
||||
key.value/blah
|
||||
@endverbatim
|
||||
|
||||
You may ask what is this thing with keys and filenames? Well Imlib2 has loaders that are able to load data that is WITHIN a file (the loader capable of this right now is the database loader that is able to load image data stored with a key in a Berkeley-db database file). The colon is used to delimit where the filename ends and the key begins. Fro the majority of files you load you won't have to worry, but there is a limit in this case that filenames cannot contain a color character.
|
||||
|
||||
First Imlib2 checks to see if the file exists and that you have permission to read it. If this fails it will abort the load. Now that it has checked that this is the case it evaluates that it's list of dynamically loaded loader modules it up to date then it runs through the loader modules until one of them claims it can load this file. If this is the case that loader is now used to decode the image and return an Image handle to the calling program. If the loader is written correctly and the file format sanely supports this, the loader will NOT decode any image data at this point. It will ONLY read the header of the image to figure out its size, if it has an alpha channel, format and any other header information. The loader is remembered and it will be re-used to load the image data itself later if and ONLY if the actual image data itself is needed. This means you can scan vast directories of files figuring their format and size and other such information just by loading and freeing - and it will be fast because no image data is decoded. You can take advantage of this by loading the image and checking its size to calculate the size of an output area before you ever load the data. This means geometry calculations can be done fast ahead of time.
|
||||
|
||||
If you desire more detailed information about why a load failed you can use imlib_load_image_with_error_return(); and it will return a detailed error return code.
|
||||
|
||||
If you do not wish to have the image data loaded later using the optimized "deferred" method of loading, you can force the data to be decoded immediately with imlib_load_image_immediately();
|
||||
|
||||
If you wish to bypass the cache when loading images you can using imlib_load_image_without_cache(); and imlib_load_image_immediately_without_cache();.
|
||||
|
||||
Sometimes loading images can take a while. Often it is a good idea to provide feedback to the user whilst this is happening. This is when you set the progress function callback. Setting this to NULL will mean no progress function is called during load - this is the default. When it is set you set it to a function that will get called every so often (depending on the progress granularity) during load. Use imlib_context_set_progress_function(); and imlib_context_set_progress_granularity(); to set this up.
|
||||
|
||||
@section second_ex A more advanced Example
|
||||
|
||||
This is a more comprehensive example that should show off a fair number of features of imlib2. The code this was based off can be found in Imlib2's test directory. This covers a lot of the core of Imlib2's API so you should have a pretty good idea on how it works if you understand this code snippet.
|
||||
|
||||
@code
|
||||
/* include X11 stuff */
|
||||
#include <X11/Xlib.h>
|
||||
/* include Imlib2 stuff */
|
||||
#include <Imlib2.h>
|
||||
/* sprintf include */
|
||||
#include <stdio.h>
|
||||
|
||||
/* some globals for our window & X display */
|
||||
Display *disp;
|
||||
Window win;
|
||||
Visual *vis;
|
||||
Colormap cm;
|
||||
int depth;
|
||||
|
||||
/* the program... */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* events we get from X */
|
||||
XEvent ev;
|
||||
/* areas to update */
|
||||
Imlib_Updates updates, current_update;
|
||||
/* our virtual framebuffer image we draw into */
|
||||
Imlib_Image buffer;
|
||||
/* a font */
|
||||
Imlib_Font font;
|
||||
/* our color range */
|
||||
Imlib_Color_Range range;
|
||||
/* our mouse x, y coordinates */
|
||||
int mouse_x = 0, mouse_y = 0;
|
||||
|
||||
/* connect to X */
|
||||
disp = XOpenDisplay(NULL);
|
||||
/* get default visual , colormap etc. you could ask imlib2 for what it */
|
||||
/* thinks is the best, but this example is intended to be simple */
|
||||
vis = DefaultVisual(disp, DefaultScreen(disp));
|
||||
depth = DefaultDepth(disp, DefaultScreen(disp));
|
||||
cm = DefaultColormap(disp, DefaultScreen(disp));
|
||||
/* create a window 640x480 */
|
||||
win = XCreateSimpleWindow(disp, DefaultRootWindow(disp),
|
||||
0, 0, 640, 480, 0, 0, 0);
|
||||
/* tell X what events we are interested in */
|
||||
XSelectInput(disp, win, ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask | ExposureMask);
|
||||
/* show the window */
|
||||
XMapWindow(disp, win);
|
||||
/* set our cache to 2 Mb so it doesn't have to go hit the disk as long as */
|
||||
/* the images we use use less than 2Mb of RAM (that is uncompressed) */
|
||||
imlib_set_cache_size(2048 * 1024);
|
||||
/* set the font cache to 512Kb - again to avoid re-loading */
|
||||
imlib_set_font_cache_size(512 * 1024);
|
||||
/* add the ./ttfonts dir to our font path - you'll want a notepad.ttf */
|
||||
/* in that dir for the text to display */
|
||||
imlib_add_path_to_font_path("./ttfonts");
|
||||
/* set the maximum number of colors to allocate for 8bpp and less to 128 */
|
||||
imlib_set_color_usage(128);
|
||||
/* dither for depths < 24bpp */
|
||||
imlib_context_set_dither(1);
|
||||
/* set the display , visual, colormap and drawable we are using */
|
||||
imlib_context_set_display(disp);
|
||||
imlib_context_set_visual(vis);
|
||||
imlib_context_set_colormap(cm);
|
||||
imlib_context_set_drawable(win);
|
||||
/* infinite event loop */
|
||||
for (;;)
|
||||
{
|
||||
/* image variable */
|
||||
Imlib_Image image;
|
||||
/* width and height values */
|
||||
int w, h, text_w, text_h;
|
||||
|
||||
/* init our updates to empty */
|
||||
updates = imlib_updates_init();
|
||||
/* while there are events form X - handle them */
|
||||
do
|
||||
{
|
||||
XNextEvent(disp, &ev);
|
||||
switch (ev.type)
|
||||
{
|
||||
case Expose:
|
||||
/* window rectangle was exposed - add it to the list of */
|
||||
/* rectangles we need to re-render */
|
||||
updates = imlib_update_append_rect(updates,
|
||||
ev.xexpose.x, ev.xexpose.y,
|
||||
ev.xexpose.width, ev.xexpose.height);
|
||||
break;
|
||||
case ButtonPress:
|
||||
/* if we click anywhere in the window, exit */
|
||||
exit(0);
|
||||
break;
|
||||
case MotionNotify:
|
||||
/* if the mouse moves - note it */
|
||||
/* add a rectangle update for the new mouse position */
|
||||
image = imlib_load_image("./test_images/mush.png");
|
||||
imlib_context_set_image(image);
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
imlib_context_set_image(image);
|
||||
imlib_free_image();
|
||||
/* the old position - so we wipe over where it used to be */
|
||||
updates = imlib_update_append_rect(updates,
|
||||
mouse_x - (w / 2), mouse_y - (h / 2),
|
||||
w, h);
|
||||
font = imlib_load_font("notepad/30");
|
||||
if (font)
|
||||
{
|
||||
char text[4096];
|
||||
|
||||
imlib_context_set_font(font);
|
||||
sprintf(text, "Mouse is at %i, %i", mouse_x, mouse_y);
|
||||
imlib_get_text_size(text, &text_w, &text_h);
|
||||
imlib_free_font();
|
||||
updates = imlib_update_append_rect(updates,
|
||||
320 - (text_w / 2), 240 - (text_h / 2),
|
||||
text_w, text_h);
|
||||
}
|
||||
|
||||
mouse_x = ev.xmotion.x;
|
||||
mouse_y = ev.xmotion.y;
|
||||
/* the new one */
|
||||
updates = imlib_update_append_rect(updates,
|
||||
mouse_x - (w / 2), mouse_y - (h / 2),
|
||||
w, h);
|
||||
font = imlib_load_font("notepad/30");
|
||||
if (font)
|
||||
{
|
||||
char text[4096];
|
||||
|
||||
imlib_context_set_font(font);
|
||||
sprintf(text, "Mouse is at %i, %i", mouse_x, mouse_y);
|
||||
imlib_get_text_size(text, &text_w, &text_h);
|
||||
imlib_free_font();
|
||||
updates = imlib_update_append_rect(updates,
|
||||
320 - (text_w / 2), 240 - (text_h / 2),
|
||||
text_w, text_h);
|
||||
}
|
||||
default:
|
||||
/* any other events - do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (XPending(disp));
|
||||
|
||||
/* no more events for now ? ok - idle time so lets draw stuff */
|
||||
|
||||
/* take all the little rectangles to redraw and merge them into */
|
||||
/* something sane for rendering */
|
||||
updates = imlib_updates_merge_for_rendering(updates, 640, 480);
|
||||
for (current_update = updates;
|
||||
current_update;
|
||||
current_update = imlib_updates_get_next(current_update))
|
||||
{
|
||||
int up_x, up_y, up_w, up_h;
|
||||
|
||||
/* find out where the first update is */
|
||||
imlib_updates_get_coordinates(current_update,
|
||||
&up_x, &up_y, &up_w, &up_h);
|
||||
|
||||
/* create our buffer image for rendering this update */
|
||||
buffer = imlib_create_image(up_w, up_h);
|
||||
|
||||
/* we can blend stuff now */
|
||||
imlib_context_set_blend(1);
|
||||
|
||||
/* fill the window background */
|
||||
/* load the background image - you'll need to have some images */
|
||||
/* in ./test_images lying around for this to actually work */
|
||||
image = imlib_load_image("./test_images/bg.png");
|
||||
/* we're working with this image now */
|
||||
imlib_context_set_image(image);
|
||||
/* get its size */
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
/* now we want to work with the buffer */
|
||||
imlib_context_set_image(buffer);
|
||||
/* if the iimage loaded */
|
||||
if (image)
|
||||
{
|
||||
/* blend image onto the buffer and scale it to 640x480 */
|
||||
imlib_blend_image_onto_image(image, 0,
|
||||
0, 0, w, h,
|
||||
- up_x, - up_y, 640, 480);
|
||||
/* working with the loaded image */
|
||||
imlib_context_set_image(image);
|
||||
/* free it */
|
||||
imlib_free_image();
|
||||
}
|
||||
|
||||
/* draw an icon centered around the mouse position */
|
||||
image = imlib_load_image("./test_images/mush.png");
|
||||
imlib_context_set_image(image);
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
imlib_context_set_image(buffer);
|
||||
if (image)
|
||||
{
|
||||
imlib_blend_image_onto_image(image, 0,
|
||||
0, 0, w, h,
|
||||
mouse_x - (w / 2) - up_x, mouse_y - (h / 2) - up_y, w, h);
|
||||
imlib_context_set_image(image);
|
||||
imlib_free_image();
|
||||
}
|
||||
|
||||
/* draw a gradient on top of things at the top left of the window */
|
||||
/* create a range */
|
||||
range = imlib_create_color_range();
|
||||
imlib_context_set_color_range(range);
|
||||
/* add white opaque as the first color */
|
||||
imlib_context_set_color(255, 255, 255, 255);
|
||||
imlib_add_color_to_color_range(0);
|
||||
/* add an orange color, semi-transparent 10 units from the first */
|
||||
imlib_context_set_color(255, 200, 10, 100);
|
||||
imlib_add_color_to_color_range(10);
|
||||
/* add black, fully transparent at the end 20 units away */
|
||||
imlib_context_set_color(0, 0, 0, 0);
|
||||
imlib_add_color_to_color_range(20);
|
||||
/* draw the range */
|
||||
imlib_context_set_image(buffer);
|
||||
imlib_image_fill_color_range_rectangle(- up_x, - up_y, 128, 128, -45.0);
|
||||
/* free it */
|
||||
imlib_free_color_range();
|
||||
|
||||
/* draw text - centered with the current mouse x, y */
|
||||
font = imlib_load_font("notepad/30");
|
||||
if (font)
|
||||
{
|
||||
char text[4096];
|
||||
|
||||
/* set the current font */
|
||||
imlib_context_set_font(font);
|
||||
/* set the image */
|
||||
imlib_context_set_image(buffer);
|
||||
/* set the color (black) */
|
||||
imlib_context_set_color(0, 0, 0, 255);
|
||||
/* print text to display in the buffer */
|
||||
sprintf(text, "Mouse is at %i, %i", mouse_x, mouse_y);
|
||||
/* query the size it will be */
|
||||
imlib_get_text_size(text, &text_w, &text_h);
|
||||
/* draw it */
|
||||
imlib_text_draw(320 - (text_w / 2) - up_x, 240 - (text_h / 2) - up_y, text);
|
||||
/* free the font */
|
||||
imlib_free_font();
|
||||
}
|
||||
|
||||
/* don't blend the image onto the drawable - slower */
|
||||
imlib_context_set_blend(0);
|
||||
/* set the buffer image as our current image */
|
||||
imlib_context_set_image(buffer);
|
||||
/* render the image at 0, 0 */
|
||||
imlib_render_image_on_drawable(up_x, up_y);
|
||||
/* don't need that temporary buffer image anymore */
|
||||
imlib_free_image();
|
||||
}
|
||||
/* if we had updates - free them */
|
||||
if (updates)
|
||||
imlib_updates_free(updates);
|
||||
/* loop again waiting for events */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section filters Imlib2 filters
|
||||
|
||||
@subsection dyn_filter Imlib 2 Dynamic Filters
|
||||
|
||||
Imlib2 has built in features allowing filters and effects to be applied at run time through a very small scripting language, this is similar to that of script-fu found in the GIMP (http://www.gimp.org). There are two parts to the system, the client library call ``imlib_apply_filter'' and the library side filters. The library side filters are synonymous with image loaders.
|
||||
|
||||
To run a script on an image you need to set the context image then call:
|
||||
|
||||
@verbatim
|
||||
imlib_apply_filter( script_string, ... );
|
||||
@endverbatim
|
||||
|
||||
The script_string variable is made up of the script language, which is very simple and made up of only function calls. Functions calls look like this:
|
||||
|
||||
@verbatim
|
||||
filter name( key=value [, ...] );
|
||||
@endverbatim
|
||||
|
||||
Where,
|
||||
|
||||
\li <b>filter name</b> is the name of the filter you wish to apply
|
||||
\li \b key is an expected value
|
||||
\li \b value is a ``string'', a number, or an actual variable in
|
||||
|
||||
the program, or the result of another filter.
|
||||
|
||||
eg.
|
||||
|
||||
@verbatim
|
||||
bump_map( map=tint(red=50,tint=200), blue=10 );
|
||||
@endverbatim
|
||||
|
||||
This example would bump map using a a map generated from the tint filter.
|
||||
|
||||
It is also possible to pass application information to the filters via the usage of the [] operator. When the script is being compiled the script engine looks on the parameters passed to it and picks up a pointer for every [] found.
|
||||
|
||||
eg2.
|
||||
|
||||
@verbatim
|
||||
imlib_apply_filter( "tint( x=[], y=[], red=255, alpha=55 );", &myxint, &myyint );
|
||||
@endverbatim
|
||||
|
||||
This will cause a tint to the current image at (myxint,myyint) to be done. This is very useful for when you want the filters to dynamically change according to program variables. The system is very quick as the code is pseudo-compiled and then run. The advantage of having the scripting system allows customization of the image manipulations, this is particularly useful in applications that allow modifications to be done (eg. image viewers).
|
||||
|
||||
|
||||
@subsection lib_filter Filter Library
|
||||
There are three functions that must be in every filter library
|
||||
|
||||
@code
|
||||
void init( struct imlib_filter_info *info ); - Called once on loading of the filter
|
||||
@endcode
|
||||
|
||||
info - a structure passed to the filter to be filled in with information about the filter info->name - Name of the filter library
|
||||
info->author - Name of the library author
|
||||
info->description - Description of the filter library
|
||||
info->num_filters - Number of filters the library exports
|
||||
info->filters - An array of ``char *'' with each filter name in it.
|
||||
|
||||
@code
|
||||
void deinit(); - Called when the filter is closed
|
||||
|
||||
/* Called every time a filter the library exports is called */
|
||||
void *exec( char *filter, void *im, pIFunctionParam params );
|
||||
@endcode
|
||||
|
||||
filter - The name of the filter being asked for im - The image that the filter should be applied against params - A linked list of parameters.
|
||||
|
||||
The best way to get all the values is such:
|
||||
|
||||
Declare all parameters and initialize them to there default values.
|
||||
|
||||
@code
|
||||
for( ptr = params; ptr != NULL; ptr = ptr->next )
|
||||
{
|
||||
..MACRO TO GET VALUE..
|
||||
}
|
||||
@endcode
|
||||
|
||||
Current Macros are:
|
||||
|
||||
@verbatim
|
||||
ASSIGN_INT( keyname, local variable )
|
||||
ASSIGN_DATA8( keyname, local variable )
|
||||
ASSIGN_IMAGE( keyname, local variable )
|
||||
@endverbatim
|
||||
|
||||
eg.
|
||||
|
||||
@code
|
||||
int r = 50;
|
||||
IFunctionParam *ptr;
|
||||
|
||||
for( ptr = params; ptr != NULL; ptr = ptr->next )
|
||||
{
|
||||
ASSIGN_INT( "red", r );
|
||||
}
|
||||
@endcode
|
||||
|
||||
If the value "red" is not passed to the filter then it will remain at 50, but it a value is passed, it will be assign to r.
|
||||
|
||||
return type - Imlib_Image, this is the result of filter.
|
||||
|
||||
@todo line code doesnt draw nice liens when clipping - fix
|
||||
@todo filled polygons can break fill bounds on corner cases - fix
|
||||
@todo go thru TODOs and FIXMEs
|
||||
|
||||
*/
|
12
imlib2.pc.in
12
imlib2.pc.in
|
@ -1,12 +0,0 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: imlib2
|
||||
Description: Powerful image loading and rendering library
|
||||
Version: @VERSION@
|
||||
Requires: @REQUIREMENTS@
|
||||
Libs: -L${libdir} -lImlib2 @freetype_libs@ -lm @x_libs@ @x_ldflags@ @dlopen_libs@
|
||||
Cflags: -I${includedir} -I@x_cflags@ @freetype_cflags@
|
||||
|
184
imlib2.spec
184
imlib2.spec
|
@ -1,184 +0,0 @@
|
|||
Summary: Powerful image loading and rendering library
|
||||
Name: imlib2
|
||||
Version: 1.1.2
|
||||
Release: 1.%(date '+%Y%m%d')
|
||||
Copyright: BSD
|
||||
Group: System Environment/Libraries
|
||||
Source: ftp://ftp.enlightenment.org/pub/enlightenment/e17/libs/%{name}-%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-root
|
||||
Packager: Michael Jennings <mej@eterm.org>
|
||||
URL: http://www.rasterman.com/raster/imlib.html
|
||||
#BuildSuggests: freetype-devel xorg-x11-devel
|
||||
Requires: %{name}-loader_jpeg = %{version}
|
||||
Requires: %{name}-loader_png = %{version}
|
||||
Requires: %{name}-loader_argb = %{version}
|
||||
|
||||
%description
|
||||
Imlib2 is an advanced replacement library for libraries like libXpm that
|
||||
provides many more features with much greater flexibility and speed than
|
||||
standard libraries, including font rasterization, rotation, RGBA space
|
||||
rendering and blending, dynamic binary filters, scripting, and more.
|
||||
|
||||
%package devel
|
||||
Summary: Imlib2 headers, static libraries and documentation
|
||||
Group: System Environment/Libraries
|
||||
Requires: %{name} = %{version}
|
||||
%description devel
|
||||
Headers, static libraries and documentation for Imlib2.
|
||||
|
||||
%package filters
|
||||
Summary: Imlib2 basic plugin filters set
|
||||
Group: System Environment/Libraries
|
||||
Requires: %{name} = %{version}
|
||||
%description filters
|
||||
Basic set of plugin filters that come with Imlib2
|
||||
|
||||
%package loader_lbm
|
||||
Summary: Imlib2 LBM loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_lbm
|
||||
LBM image loader/saver for Imlib2
|
||||
|
||||
%package loader_jpeg
|
||||
Summary: Imlib2 JPEG loader
|
||||
Group: System Environment/Libraries
|
||||
BuildRequires: libjpeg-devel
|
||||
%description loader_jpeg
|
||||
JPEG image loader/saver for Imlib2
|
||||
|
||||
%package loader_png
|
||||
Summary: Imlib2 PNG loader
|
||||
Group: System Environment/Libraries
|
||||
BuildRequires: libpng-devel
|
||||
BuildRequires: zlib-devel
|
||||
%description loader_png
|
||||
PNG image loader/saver for Imlib2
|
||||
|
||||
%package loader_argb
|
||||
Summary: Imlib2 ARGB loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_argb
|
||||
ARGB image loader/saver for Imlib2
|
||||
|
||||
%package loader_bmp
|
||||
Summary: Imlib2 BMP loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_bmp
|
||||
BMP image loader/saver for Imlib2
|
||||
|
||||
%package loader_gif
|
||||
Summary: Imlib2 GIF loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_gif
|
||||
GIF image loader for Imlib2
|
||||
|
||||
%package loader_pnm
|
||||
Summary: Imlib2 PNM loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_pnm
|
||||
PNM image loader/saver for Imlib2
|
||||
|
||||
%package loader_tga
|
||||
Summary: Imlib2 TGA loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_tga
|
||||
TGA image loader/saver for Imlib2
|
||||
|
||||
%package loader_tiff
|
||||
Summary: Imlib2 TIFF loader
|
||||
Group: System Environment/Libraries
|
||||
BuildRequires: libtiff-devel
|
||||
%description loader_tiff
|
||||
TIFF image loader/saver for Imlib2
|
||||
|
||||
%package loader_xpm
|
||||
Summary: Imlib2 XPM loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_xpm
|
||||
XPM image loader/saver for Imlib2
|
||||
|
||||
%package loader_bz2
|
||||
Summary: Imlib2 .bz2 loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_bz2
|
||||
Bzip2 compressed image loader/saver for Imlib2
|
||||
|
||||
%package loader_gz
|
||||
Summary: Imlib2 .gz loader
|
||||
Group: System Environment/Libraries
|
||||
%description loader_gz
|
||||
gz compressed image loader/saver for Imlib2
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%{configure} --prefix=%{_prefix}
|
||||
%{__make} %{?_smp_mflags} %{?mflags}
|
||||
|
||||
%install
|
||||
%{__make} %{?mflags_install} DESTDIR=$RPM_BUILD_ROOT install
|
||||
|
||||
%clean
|
||||
test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
/sbin/ldconfig
|
||||
|
||||
%postun
|
||||
/sbin/ldconfig
|
||||
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
%doc AUTHORS COPYING README ChangeLog doc/index.html doc/imlib2.gif doc/blank.gif
|
||||
%{_libdir}/lib*.so.*
|
||||
%{_bindir}/*
|
||||
|
||||
%files devel
|
||||
%defattr(-, root, root, 0755)
|
||||
%{_libdir}/libImlib2.so
|
||||
%{_libdir}/*.a
|
||||
%{_libdir}/*.la
|
||||
%{_libdir}/pkgconfig/imlib2.pc
|
||||
%{_includedir}/*
|
||||
|
||||
%files filters
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/filter/*
|
||||
|
||||
%files loader_lbm
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/lbm.*
|
||||
|
||||
%files loader_jpeg
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/jpeg.*
|
||||
|
||||
%files loader_png
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/png.*
|
||||
|
||||
%files loader_argb
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/argb.*
|
||||
|
||||
%files loader_bmp
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/bmp.*
|
||||
|
||||
%files loader_gif
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/gif.*
|
||||
|
||||
%files loader_pnm
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/pnm.*
|
||||
|
||||
%files loader_tga
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/tga.*
|
||||
|
||||
%files loader_tiff
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/tiff.*
|
||||
|
||||
%files loader_xpm
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/xpm.*
|
||||
|
||||
%files loader_bz2
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/bz2.*
|
||||
|
||||
%files loader_gz
|
||||
%attr(755,root,root) %{_libdir}/imlib2_loaders/image/zlib.*
|
||||
|
||||
%changelog
|
|
@ -1,22 +0,0 @@
|
|||
config.guess
|
||||
config.h.in
|
||||
config.sub
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
aclocal.m4
|
||||
stamp-h.in
|
||||
Makefile.in
|
||||
configure
|
||||
config.log
|
||||
config.h
|
||||
config.cache
|
||||
libtool
|
||||
config.status
|
||||
stamp-h
|
||||
Makefile
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
imlib2
|
||||
loaderpath.h
|
|
@ -1,90 +0,0 @@
|
|||
## 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$(top_builddir)/src -L$(top_builddir)/src/.libs -L/usr/X11R6/lib
|
||||
INCLUDES = -I. -I$(top_srcdir) -I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/loaders -I$(top_srcdir)/libltdl \
|
||||
-I/usr/X11R6/include $(X_CFLAGS) \
|
||||
-I$(prefix)/include -I$(includedir)
|
||||
|
||||
pkgdir = $(libdir)/imlib2_loaders/image
|
||||
|
||||
if JPEG_LOADER
|
||||
JPEG_L = jpeg.la
|
||||
endif
|
||||
if PNG_LOADER
|
||||
PNG_L = png.la
|
||||
endif
|
||||
if TIFF_LOADER
|
||||
TIFF_L = tiff.la
|
||||
endif
|
||||
if GIF_LOADER
|
||||
GIF_L = gif.la
|
||||
endif
|
||||
if ZLIB_LOADER
|
||||
ZLIB_L = zlib.la
|
||||
endif
|
||||
if BZ2_LOADER
|
||||
BZ2_L = bz2.la
|
||||
endif
|
||||
|
||||
pkg_LTLIBRARIES = \
|
||||
$(JPEG_L) \
|
||||
$(PNG_L) \
|
||||
$(TIFF_L) \
|
||||
$(GIF_L) \
|
||||
$(ZLIB_L) \
|
||||
$(BZ2_L) \
|
||||
pnm.la argb.la bmp.la xpm.la tga.la lbm.la
|
||||
|
||||
jpeg_la_SOURCES = loader_jpeg.c
|
||||
jpeg_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
jpeg_la_LIBADD = @JPEGLIBS@ -lImlib2
|
||||
|
||||
png_la_SOURCES = loader_png.c
|
||||
png_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
png_la_LIBADD = @PNGLIBS@ -lImlib2
|
||||
|
||||
tiff_la_SOURCES = loader_tiff.c
|
||||
tiff_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
tiff_la_LIBADD = @TIFFLIBS@ -lImlib2
|
||||
|
||||
gif_la_SOURCES = loader_gif.c
|
||||
gif_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
gif_la_LIBADD = @GIFLIBS@ -lImlib2
|
||||
|
||||
pnm_la_SOURCES = loader_pnm.c
|
||||
pnm_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
pnm_la_LIBADD = -lImlib2
|
||||
|
||||
argb_la_SOURCES = loader_argb.c
|
||||
argb_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
argb_la_LIBADD = -lImlib2
|
||||
|
||||
bmp_la_SOURCES = loader_bmp.c
|
||||
bmp_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
bmp_la_LIBADD = -lImlib2
|
||||
|
||||
xpm_la_SOURCES = loader_xpm.c
|
||||
xpm_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
xpm_la_LIBADD = -lImlib2
|
||||
|
||||
tga_la_SOURCES = loader_tga.c
|
||||
tga_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
tga_la_LIBADD = -lImlib2
|
||||
|
||||
zlib_la_SOURCES = loader_zlib.c
|
||||
zlib_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
zlib_la_LIBADD = @ZLIBLIBS@ -lImlib2
|
||||
|
||||
bz2_la_SOURCES = loader_bz2.c
|
||||
bz2_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
bz2_la_LIBADD = @BZ2LIBS@ -lImlib2
|
||||
|
||||
lbm_la_SOURCES = loader_lbm.c
|
||||
lbm_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src -L$(top_builddir)/src/.libs
|
||||
lbm_la_LIBADD = -lImlib2
|
|
@ -1,201 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
#define SWAP32(x) (x) = \
|
||||
((((x) & 0x000000ff ) << 24) |\
|
||||
(((x) & 0x0000ff00 ) << 8) |\
|
||||
(((x) & 0x00ff0000 ) >> 8) |\
|
||||
(((x) & 0xff000000 ) >> 24))
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
int w, h, alpha;
|
||||
FILE *f;
|
||||
|
||||
if (im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
/* header */
|
||||
{
|
||||
char buf[256], buf2[256];
|
||||
|
||||
if (!fgets(buf, 255, f))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
sscanf(buf, "%s %i %i %i", buf2, &w, &h, &alpha);
|
||||
if (strcmp(buf2, "ARGB"))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
if (!im->format)
|
||||
{
|
||||
if (alpha)
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
else
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
im->format = strdup("argb");
|
||||
}
|
||||
}
|
||||
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
|
||||
{
|
||||
DATA32 *ptr;
|
||||
int y, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
/* must set the im->data member before callign progress function */
|
||||
ptr = im->data = malloc(w * h * sizeof(DATA32));
|
||||
if (!im->data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
{
|
||||
int x;
|
||||
|
||||
fread(ptr, im->w, 4, f);
|
||||
for (x = 0; x < im->w; x++)
|
||||
SWAP32(ptr[x]);
|
||||
}
|
||||
#else
|
||||
fread(ptr, im->w, 4, f);
|
||||
#endif
|
||||
ptr += im->w;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
FILE *f;
|
||||
DATA32 *ptr;
|
||||
int y, pl = 0, alpha = 0;
|
||||
char pper = 0;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
DATA32 *buf = (DATA32 *) malloc(im->w * 4);
|
||||
#endif
|
||||
|
||||
/* no image data? abort */
|
||||
if (!im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
if (im->flags & F_HAS_ALPHA)
|
||||
alpha = 1;
|
||||
fprintf(f, "ARGB %i %i %i\n", im->w, im->h, alpha);
|
||||
ptr = im->data;
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
{
|
||||
int x;
|
||||
|
||||
memcpy(buf, ptr, im->w * 4);
|
||||
for (x = 0; x < im->w; x++)
|
||||
SWAP32(buf[x]);
|
||||
fwrite(buf, im->w, 4, f);
|
||||
}
|
||||
#else
|
||||
fwrite(ptr, im->w, 4, f);
|
||||
#endif
|
||||
ptr += im->w;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) || (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (buf)
|
||||
free(buf);
|
||||
#endif
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* finish off */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (buf)
|
||||
free(buf);
|
||||
#endif
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
char *list_formats[] = { "argb", "arg" };
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,739 +0,0 @@
|
|||
/*
|
||||
* Based off of Peter Alm's BMP loader from xmms, with additions from
|
||||
* imlib's old BMP loader
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
typedef struct tagRGBQUAD {
|
||||
unsigned char rgbBlue;
|
||||
unsigned char rgbGreen;
|
||||
unsigned char rgbRed;
|
||||
unsigned char rgbReserved;
|
||||
} RGBQUAD;
|
||||
|
||||
#define BI_RGB 0
|
||||
#define BI_RLE8 1
|
||||
#define BI_RLE4 2
|
||||
#define BI_BITFIELDS 3
|
||||
|
||||
static int
|
||||
ReadleShort(FILE * file, unsigned short *ret)
|
||||
{
|
||||
unsigned char b[2];
|
||||
|
||||
if (fread(b, sizeof(unsigned char), 2, file) != 2)
|
||||
return 0;
|
||||
|
||||
*ret = (b[1] << 8) | b[0];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ReadleLong(FILE * file, unsigned long *ret)
|
||||
{
|
||||
unsigned char b[4];
|
||||
|
||||
if (fread(b, sizeof(unsigned char), 4, file) != 4)
|
||||
return 0;
|
||||
|
||||
*ret = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
|
||||
return 1;
|
||||
}
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
FILE *f;
|
||||
char pper = 0;
|
||||
int pl = 0;
|
||||
char type[2];
|
||||
unsigned long size, offset, headSize, comp, imgsize, j, k, l;
|
||||
unsigned short tmpShort, planes, bitcount, ncols, skip;
|
||||
unsigned char tempchar, byte = 0, g, b, r;
|
||||
unsigned long i, w, h;
|
||||
unsigned short x, y;
|
||||
DATA32 *ptr, *data_end;
|
||||
unsigned char *buffer_ptr, *buffer, *buffer_end;
|
||||
RGBQUAD rgbQuads[256];
|
||||
unsigned long rmask = 0xff, gmask = 0xff, bmask = 0xff;
|
||||
unsigned long rshift = 0, gshift = 0, bshift = 0;
|
||||
|
||||
if (im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
/* header */
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(im->real_file, &statbuf) == -1)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
size = statbuf.st_size;
|
||||
|
||||
if (fread(type, 1, 2, f) != 2)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(type, "BM", 2))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(f, 8, SEEK_CUR);
|
||||
ReadleLong(f, &offset);
|
||||
ReadleLong(f, &headSize);
|
||||
if (offset >= size)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
if (headSize == 12)
|
||||
{
|
||||
ReadleShort(f, &tmpShort);
|
||||
w = tmpShort;
|
||||
ReadleShort(f, &tmpShort);
|
||||
h = tmpShort;
|
||||
ReadleShort(f, &planes);
|
||||
ReadleShort(f, &bitcount);
|
||||
imgsize = size - offset;
|
||||
comp = BI_RGB;
|
||||
}
|
||||
else if (headSize == 40)
|
||||
{
|
||||
ReadleLong(f, &w);
|
||||
ReadleLong(f, &h);
|
||||
ReadleShort(f, &planes);
|
||||
ReadleShort(f, &bitcount);
|
||||
ReadleLong(f, &comp);
|
||||
ReadleLong(f, &imgsize);
|
||||
imgsize = size - offset;
|
||||
|
||||
fseek(f, 16, SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((w > 8192) || (h > 8192))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bitcount < 16)
|
||||
{
|
||||
ncols = (offset - headSize - 14);
|
||||
if (headSize == 12)
|
||||
{
|
||||
ncols /= 3;
|
||||
if (ncols > 256) ncols = 256;
|
||||
for (i = 0; i < ncols; i++)
|
||||
fread(&rgbQuads[i], 3, 1, f);
|
||||
}
|
||||
else
|
||||
{
|
||||
ncols /= 4;
|
||||
if (ncols > 256) ncols = 256;
|
||||
fread(rgbQuads, 4, ncols, f);
|
||||
}
|
||||
}
|
||||
else if (bitcount == 16 || bitcount == 32)
|
||||
{
|
||||
if (comp == BI_BITFIELDS)
|
||||
{
|
||||
int bit;
|
||||
|
||||
ReadleLong(f, &bmask);
|
||||
ReadleLong(f, &gmask);
|
||||
ReadleLong(f, &rmask);
|
||||
for (bit = bitcount - 1; bit >= 0; bit--)
|
||||
{
|
||||
if (bmask & (1 << bit))
|
||||
bshift = bit;
|
||||
if (gmask & (1 << bit))
|
||||
gshift = bit;
|
||||
if (rmask & (1 << bit))
|
||||
rshift = bit;
|
||||
}
|
||||
}
|
||||
else if (bitcount == 16)
|
||||
{
|
||||
rmask = 0x7C00;
|
||||
gmask = 0x03E0;
|
||||
bmask = 0x001F;
|
||||
rshift = 10;
|
||||
gshift = 5;
|
||||
bshift = 0;
|
||||
}
|
||||
else if (bitcount == 32)
|
||||
{
|
||||
rmask = 0x00FF0000;
|
||||
gmask = 0x0000FF00;
|
||||
bmask = 0x000000FF;
|
||||
rshift = 16;
|
||||
gshift = 8;
|
||||
bshift = 0;
|
||||
}
|
||||
}
|
||||
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
if (!im->format)
|
||||
{
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
im->format = strdup("bmp");
|
||||
}
|
||||
}
|
||||
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
|
||||
{
|
||||
fseek(f, offset, SEEK_SET);
|
||||
buffer = malloc(imgsize);
|
||||
if (!buffer)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
im->data = malloc(w * h * sizeof(DATA32));
|
||||
if (!im->data)
|
||||
{
|
||||
fclose(f);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread(buffer, imgsize, 1, f);
|
||||
fclose(f);
|
||||
buffer_ptr = buffer;
|
||||
buffer_end = buffer + imgsize;
|
||||
|
||||
data_end = im->data + w * h;
|
||||
ptr = im->data + ((h - 1) * w);
|
||||
|
||||
if (bitcount == 1)
|
||||
{
|
||||
if (comp == BI_RGB)
|
||||
{
|
||||
skip = ((((w + 31) / 32) * 32) - w) / 8;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w && buffer_ptr < buffer_end; x++)
|
||||
{
|
||||
if ((x & 7) == 0)
|
||||
byte = *(buffer_ptr++);
|
||||
k = (byte >> 7) & 1;
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[k].rgbRed << 16) |
|
||||
(rgbQuads[k].rgbGreen << 8) |
|
||||
rgbQuads[k].rgbBlue;
|
||||
byte <<= 1;
|
||||
}
|
||||
buffer_ptr += skip;
|
||||
ptr -= w * 2;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bitcount == 4)
|
||||
{
|
||||
if (comp == BI_RLE4)
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
for (i = 0, g = 1;
|
||||
i < imgsize && g && buffer_ptr < buffer_end; i++)
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
if (byte)
|
||||
{
|
||||
unsigned char t1, t2;
|
||||
|
||||
l = byte;
|
||||
byte = *(buffer_ptr++);
|
||||
t1 = byte & 0xF;
|
||||
t2 = (byte >> 4) & 0xF;
|
||||
for (j = 0; j < l; j++)
|
||||
{
|
||||
k = (j & 1) ? t1 : t2;
|
||||
|
||||
if (x >= w)
|
||||
break;
|
||||
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[k].rgbRed << 16) |
|
||||
(rgbQuads[k].rgbGreen << 8) |
|
||||
rgbQuads[k].rgbBlue;
|
||||
x++;
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
switch (byte)
|
||||
{
|
||||
case 0:
|
||||
x = 0;
|
||||
y++;
|
||||
ptr = im->data + ((h - y - 1)
|
||||
* w * sizeof(DATA32));
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
break;
|
||||
case 1:
|
||||
g = 0;
|
||||
break;
|
||||
case 2:
|
||||
x += *(buffer_ptr++);
|
||||
y += *(buffer_ptr++);
|
||||
ptr = im->data + ((h - y - 1) * w *
|
||||
sizeof(DATA32)) + x;
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
break;
|
||||
default:
|
||||
l = byte;
|
||||
for (j = 0; j < l; j++)
|
||||
{
|
||||
char t1 = '\0', t2 =
|
||||
'\0';
|
||||
|
||||
if ((j & 1) == 0)
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
t1 = byte & 0xF;
|
||||
t2 = (byte >> 4) & 0xF;
|
||||
}
|
||||
k = (j & 1) ? t1 : t2;
|
||||
|
||||
if (x >= w)
|
||||
{
|
||||
buffer_ptr += (l - j) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[k].rgbRed << 16) |
|
||||
(rgbQuads[k].rgbGreen << 8) |
|
||||
rgbQuads[k].rgbBlue;
|
||||
x++;
|
||||
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
|
||||
}
|
||||
|
||||
if ((l & 3) == 1)
|
||||
{
|
||||
tempchar = *(buffer_ptr++);
|
||||
tempchar = *(buffer_ptr++);
|
||||
}
|
||||
else if ((l & 3) == 2)
|
||||
buffer_ptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (comp == BI_RGB)
|
||||
{
|
||||
skip = ((((w + 7) / 8) * 8) - w) / 2;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w && buffer_ptr < buffer_end; x++)
|
||||
{
|
||||
if ((x & 1) == 0)
|
||||
byte = *(buffer_ptr++);
|
||||
k = (byte & 0xF0) >> 4;
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[k].rgbRed << 16) |
|
||||
(rgbQuads[k].rgbGreen << 8) |
|
||||
rgbQuads[k].rgbBlue;
|
||||
byte <<= 4;
|
||||
}
|
||||
buffer_ptr += skip;
|
||||
ptr -= w * 2;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bitcount == 8)
|
||||
{
|
||||
if (comp == BI_RLE8)
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
for (i = 0, g = 1;
|
||||
i < imgsize && buffer_ptr < buffer_end && g; i++)
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
if (byte)
|
||||
{
|
||||
l = byte;
|
||||
byte = *(buffer_ptr++);
|
||||
for (j = 0; j < l; j++)
|
||||
{
|
||||
if (x >= w)
|
||||
break;
|
||||
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[byte].rgbRed << 16) |
|
||||
(rgbQuads[byte].rgbGreen << 8) |
|
||||
rgbQuads[byte].rgbBlue;
|
||||
|
||||
x++;
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
switch (byte)
|
||||
{
|
||||
case 0:
|
||||
x = 0;
|
||||
y++;
|
||||
ptr = im->data + ((h - y - 1)
|
||||
* w * sizeof(DATA32));
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
break;
|
||||
case 1:
|
||||
g = 0;
|
||||
break;
|
||||
case 2:
|
||||
x += *(buffer_ptr++);
|
||||
y += *(buffer_ptr++);
|
||||
ptr = im->data + ((h - y - 1)
|
||||
* w *
|
||||
sizeof(DATA32)) +
|
||||
(x * sizeof(DATA32));
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
break;
|
||||
default:
|
||||
l = byte;
|
||||
for (j = 0; j < l; j++)
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
|
||||
if (x >= w)
|
||||
{
|
||||
buffer_ptr += l - j;
|
||||
break;
|
||||
}
|
||||
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[byte].rgbRed << 16) |
|
||||
(rgbQuads[byte].rgbGreen << 8) |
|
||||
rgbQuads[byte].rgbBlue;
|
||||
x++;
|
||||
|
||||
if (ptr > data_end)
|
||||
ptr = data_end;
|
||||
}
|
||||
if (l & 1)
|
||||
buffer_ptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (comp == BI_RGB)
|
||||
{
|
||||
skip = (((w + 3) / 4) * 4) - w;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w && buffer_ptr < buffer_end; x++)
|
||||
{
|
||||
byte = *(buffer_ptr++);
|
||||
*ptr++ = 0xff000000 |
|
||||
(rgbQuads[byte].rgbRed << 16) |
|
||||
(rgbQuads[byte].rgbGreen << 8) |
|
||||
rgbQuads[byte].rgbBlue;
|
||||
}
|
||||
ptr -= w * 2;
|
||||
buffer_ptr += skip;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (bitcount == 16)
|
||||
{
|
||||
skip = (((w * 16 + 31) / 32) * 4) - (w * 2);
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w && buffer_ptr < buffer_end; x++)
|
||||
{
|
||||
r = ((unsigned short)(*buffer_ptr) & rmask) >> rshift;
|
||||
g = ((unsigned short)(*buffer_ptr) & gmask) >> gshift;
|
||||
b = ((unsigned short)(*(buffer_ptr++)) & bmask) >>
|
||||
bshift;
|
||||
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
ptr -= w * 2;
|
||||
buffer_ptr += skip;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bitcount == 24)
|
||||
{
|
||||
skip = (4 - ((w * 3) % 4)) & 3;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w && buffer_ptr < buffer_end; x++)
|
||||
{
|
||||
b = *(buffer_ptr++);
|
||||
g = *(buffer_ptr++);
|
||||
r = *(buffer_ptr++);
|
||||
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
ptr -= w * 2;
|
||||
buffer_ptr += skip;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bitcount == 32)
|
||||
{
|
||||
skip = (((w * 32 + 31) / 32) * 4) - (w * 4);
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w && buffer_ptr < buffer_end; x++)
|
||||
{
|
||||
r = ((unsigned long)(*buffer_ptr) & rmask) >> rshift;
|
||||
g = ((unsigned long)(*buffer_ptr) & gmask) >> gshift;
|
||||
b = ((unsigned long)(*buffer_ptr) & bmask) >> bshift;
|
||||
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
|
||||
r = *(buffer_ptr++);
|
||||
r = *(buffer_ptr++);
|
||||
}
|
||||
ptr -= w * 2;
|
||||
buffer_ptr += skip;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) ||
|
||||
(y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress
|
||||
(im, per, 0, im->h - y - 1, im->w,
|
||||
im->h - y + l))
|
||||
{
|
||||
free(buffer);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
char *list_formats[] = { "bmp" };
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <bzlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "image.h"
|
||||
|
||||
#define OUTBUF_SIZE 16384
|
||||
#define INBUF_SIZE 1024
|
||||
|
||||
static int uncompress_file (FILE *fp, int dest)
|
||||
{
|
||||
BZFILE *bf;
|
||||
DATA8 outbuf[OUTBUF_SIZE];
|
||||
int bytes, error;
|
||||
|
||||
bf = BZ2_bzReadOpen (&error, fp, 0, 0, NULL, 0);
|
||||
|
||||
if (error != BZ_OK) {
|
||||
BZ2_bzReadClose (NULL, bf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = BZ_OK;
|
||||
|
||||
while (error == BZ_OK) {
|
||||
bytes = BZ2_bzRead (&error, bf, &outbuf, OUTBUF_SIZE);
|
||||
|
||||
if (error == BZ_OK)
|
||||
write (dest, outbuf, bytes);
|
||||
}
|
||||
|
||||
BZ2_bzReadClose (&error, bf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char load (ImlibImage *im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
ImlibLoader *loader;
|
||||
FILE *fp;
|
||||
int dest, res;
|
||||
char *file, tmp[] = "/tmp/imlib2_loader_bz2-XXXXXX";
|
||||
|
||||
assert (im);
|
||||
|
||||
/* we'll need a copy of it later */
|
||||
file = im->real_file;
|
||||
|
||||
if ((dest = mkstemp (tmp)) < 0)
|
||||
return 0;
|
||||
|
||||
if (!(fp = fopen (im->real_file, "rb"))) {
|
||||
unlink (tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = uncompress_file (fp, dest);
|
||||
fclose (fp);
|
||||
close (dest);
|
||||
|
||||
if (!res) {
|
||||
unlink (tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(loader = __imlib_FindBestLoaderForFile (tmp, 0))) {
|
||||
unlink (tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free (im->real_file);
|
||||
im->real_file = strdup (tmp);
|
||||
loader->load (im, progress, progress_granularity, immediate_load);
|
||||
|
||||
free (im->real_file);
|
||||
im->real_file = strdup (file);
|
||||
unlink (tmp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void formats (ImlibLoader *l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] = {"bz2"};
|
||||
int i;
|
||||
|
||||
/* don't bother changing any of this - it just reads this in
|
||||
* and sets the struct values and makes copies
|
||||
*/
|
||||
l->num_formats = sizeof (list_formats) / sizeof (char *);
|
||||
l->formats = malloc (sizeof (char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup (list_formats[i]);
|
||||
}
|
|
@ -1,247 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
#include <gif_lib.h>
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
|
||||
char immediate_load)
|
||||
{
|
||||
DATA32 *ptr;
|
||||
GifFileType *gif;
|
||||
GifRowType *rows;
|
||||
GifRecordType rec;
|
||||
ColorMapObject *cmap;
|
||||
int i, j, done, bg, r, g, b, w = 0, h = 0;
|
||||
float per = 0.0, per_inc;
|
||||
int last_per = 0, last_y = 0;
|
||||
int intoffset[] = { 0, 4, 2, 1 };
|
||||
int intjump[] = { 8, 8, 4, 2 };
|
||||
int transp;
|
||||
int fd;
|
||||
|
||||
done = 0;
|
||||
rows = NULL;
|
||||
transp = -1;
|
||||
|
||||
/* if immediate_load is 1, then dont delay image laoding as below, or */
|
||||
/* already data in this image - dont load it again */
|
||||
if (im->data)
|
||||
return 0;
|
||||
#ifndef __EMX__
|
||||
fd = open(im->real_file, O_RDONLY);
|
||||
#else
|
||||
fd = open(im->real_file, O_RDONLY | O_BINARY);
|
||||
#endif
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
gif = DGifOpenFileHandle(fd);
|
||||
if (!gif)
|
||||
{
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
|
||||
{
|
||||
/* PrintGifError(); */
|
||||
rec = TERMINATE_RECORD_TYPE;
|
||||
}
|
||||
if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
|
||||
{
|
||||
if (DGifGetImageDesc(gif) == GIF_ERROR)
|
||||
{
|
||||
/* PrintGifError(); */
|
||||
rec = TERMINATE_RECORD_TYPE;
|
||||
}
|
||||
w = gif->Image.Width;
|
||||
h = gif->Image.Height;
|
||||
rows = malloc(h * sizeof(GifRowType *));
|
||||
if (!rows)
|
||||
{
|
||||
DGifCloseFile(gif);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
rows[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
rows[i] = malloc(w * sizeof(GifPixelType));
|
||||
if (!rows[i])
|
||||
{
|
||||
DGifCloseFile(gif);
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
if (rows[i])
|
||||
{
|
||||
free(rows[i]);
|
||||
}
|
||||
}
|
||||
free(rows);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (gif->Image.Interlace)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j = intoffset[i]; j < h; j += intjump[i])
|
||||
{
|
||||
DGifGetLine(gif, rows[j], w);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
DGifGetLine(gif, rows[i], w);
|
||||
}
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
else if (rec == EXTENSION_RECORD_TYPE)
|
||||
{
|
||||
int ext_code;
|
||||
GifByteType *ext;
|
||||
|
||||
ext = NULL;
|
||||
DGifGetExtension(gif, &ext_code, &ext);
|
||||
while (ext)
|
||||
{
|
||||
if ((ext_code == 0xf9) && (ext[1] & 1) && (transp < 0))
|
||||
{
|
||||
transp = (int)ext[4];
|
||||
}
|
||||
ext = NULL;
|
||||
DGifGetExtensionNext(gif, &ext);
|
||||
}
|
||||
}
|
||||
} while (rec != TERMINATE_RECORD_TYPE);
|
||||
if (transp >= 0)
|
||||
{
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
}
|
||||
/* set the format string member to the lower-case full extension */
|
||||
/* name for the format - so example names would be: */
|
||||
/* "png", "jpeg", "tiff", "ppm", "pgm", "pbm", "gif", "xpm" ... */
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
if (!im->format)
|
||||
im->format = strdup("gif");
|
||||
if (im->loader || immediate_load || progress)
|
||||
{
|
||||
bg = gif->SBackGroundColor;
|
||||
cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
|
||||
im->data = (DATA32 *) malloc(sizeof(DATA32) * w * h);
|
||||
if (!im->data)
|
||||
{
|
||||
DGifCloseFile(gif);
|
||||
free(rows);
|
||||
return 0;
|
||||
}
|
||||
ptr = im->data;
|
||||
per_inc = 100.0 / (((float)w) * h);
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
if (rows[i][j] == transp)
|
||||
{
|
||||
r = cmap->Colors[bg].Red;
|
||||
g = cmap->Colors[bg].Green;
|
||||
b = cmap->Colors[bg].Blue;
|
||||
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = cmap->Colors[rows[i][j]].Red;
|
||||
g = cmap->Colors[rows[i][j]].Green;
|
||||
b = cmap->Colors[rows[i][j]].Blue;
|
||||
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
per += per_inc;
|
||||
if (progress && (((int)per) != last_per)
|
||||
&& (((int)per) % progress_granularity == 0))
|
||||
{
|
||||
last_per = (int)per;
|
||||
if (!(progress(im, (int)per, 0, last_y, w, i)))
|
||||
{
|
||||
DGifCloseFile(gif);
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
free(rows[i]);
|
||||
}
|
||||
free(rows);
|
||||
return 2;
|
||||
}
|
||||
last_y = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
progress(im, 100, 0, last_y, w, h);
|
||||
}
|
||||
DGifCloseFile(gif);
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
free(rows[i]);
|
||||
}
|
||||
free(rows);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fills the ImlibLoader struct with a strign array of format file */
|
||||
/* extensions this loader can load. eg: */
|
||||
/* loader->formats = { "jpeg", "jpg"}; */
|
||||
/* giving permutations is a good idea. case sensitivity is irrelevant */
|
||||
/* your laoder CAN load more than one format if it likes - like: */
|
||||
/* loader->formats = { "gif", "png", "jpeg", "jpg"} */
|
||||
/* if it can load those formats. */
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] = { "gif" };
|
||||
|
||||
/* don't bother changing any of this - it just reads this in and sets */
|
||||
/* the struct values and makes copies */
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,376 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
#include <jpeglib.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
struct ImLib_JPEG_error_mgr {
|
||||
struct jpeg_error_mgr pub;
|
||||
sigjmp_buf setjmp_buffer;
|
||||
};
|
||||
typedef struct ImLib_JPEG_error_mgr *emptr;
|
||||
|
||||
void _JPEGFatalErrorHandler(j_common_ptr cinfo);
|
||||
void _JPEGErrorHandler(j_common_ptr cinfo);
|
||||
void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
void
|
||||
_JPEGFatalErrorHandler(j_common_ptr cinfo)
|
||||
{
|
||||
emptr errmgr;
|
||||
|
||||
errmgr = (emptr) cinfo->err;
|
||||
/* cinfo->err->output_message(cinfo);*/
|
||||
siglongjmp(errmgr->setjmp_buffer, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_JPEGErrorHandler(j_common_ptr cinfo)
|
||||
{
|
||||
emptr errmgr;
|
||||
|
||||
errmgr = (emptr) cinfo->err;
|
||||
/* cinfo->err->output_message(cinfo);*/
|
||||
/* siglongjmp(errmgr->setjmp_buffer, 1);*/
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
|
||||
{
|
||||
emptr errmgr;
|
||||
|
||||
errmgr = (emptr) cinfo->err;
|
||||
/* cinfo->err->output_message(cinfo);*/
|
||||
/* siglongjmp(errmgr->setjmp_buffer, 1);*/
|
||||
return;
|
||||
msg_level = 0;
|
||||
}
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
int w, h;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct ImLib_JPEG_error_mgr jerr;
|
||||
FILE *f;
|
||||
|
||||
if (im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
cinfo.err = jpeg_std_error(&(jerr.pub));
|
||||
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
||||
jerr.pub.emit_message = _JPEGErrorHandler2;
|
||||
jerr.pub.output_message = _JPEGErrorHandler;
|
||||
if (sigsetjmp(jerr.setjmp_buffer, 1))
|
||||
{
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
if ((!im->loader) && (!im->data))
|
||||
{
|
||||
im->w = w = cinfo.output_width;
|
||||
im->h = h = cinfo.output_height;
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
im->format = strdup("jpeg");
|
||||
}
|
||||
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
|
||||
{
|
||||
DATA8 *ptr, *line[16], *data;
|
||||
DATA32 *ptr2;
|
||||
int x, y, l, i, scans, count, prevy;
|
||||
|
||||
im->w = w = cinfo.output_width;
|
||||
im->h = h = cinfo.output_height;
|
||||
|
||||
if (cinfo.rec_outbuf_height > 16)
|
||||
{
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
data = malloc(w * 16 * 3);
|
||||
if (!data)
|
||||
{
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
/* must set the im->data member before callign progress function */
|
||||
ptr2 = im->data = malloc(w * h * sizeof(DATA32));
|
||||
if (!im->data)
|
||||
{
|
||||
free(data);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
count = 0;
|
||||
prevy = 0;
|
||||
if (cinfo.output_components == 3)
|
||||
{
|
||||
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||
line[i] = data + (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 = data;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
int per;
|
||||
|
||||
per = (l * 100) / h;
|
||||
if (((per - count) >= progress_granularity)
|
||||
|| ((h - l) <= cinfo.rec_outbuf_height))
|
||||
{
|
||||
count = per;
|
||||
if (!progress
|
||||
(im, per, 0, prevy, w, scans + l - prevy))
|
||||
{
|
||||
free(data);
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
prevy = l + scans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cinfo.output_components == 1)
|
||||
{
|
||||
for (i = 0; i < cinfo.rec_outbuf_height; i++)
|
||||
line[i] = data + (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 = data;
|
||||
for (y = 0; y < scans; y++)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
(0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) <<
|
||||
8) |
|
||||
(ptr[0]);
|
||||
ptr++;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
int per;
|
||||
|
||||
per = (l * 100) / h;
|
||||
if (((per - count) >= progress_granularity)
|
||||
|| ((h - l) <= cinfo.rec_outbuf_height))
|
||||
{
|
||||
count = per;
|
||||
if (!progress
|
||||
(im, per, 0, prevy, w, l + scans - prevy))
|
||||
{
|
||||
free(data);
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
prevy = l + scans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct ImLib_JPEG_error_mgr jerr;
|
||||
FILE *f;
|
||||
DATA8 *buf;
|
||||
DATA32 *ptr;
|
||||
JSAMPROW *jbuf;
|
||||
int y = 0, quality = 75, compression = 2;
|
||||
ImlibImageTag *tag;
|
||||
int i, j, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
/* no image data? abort */
|
||||
if (!im->data)
|
||||
return 0;
|
||||
/* allocate a small buffer to convert image data */
|
||||
buf = malloc(im->w * 3 * sizeof(DATA8));
|
||||
if (!buf)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "wb");
|
||||
if (!f)
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
/* set up error handling */
|
||||
jerr.pub.error_exit = _JPEGFatalErrorHandler;
|
||||
jerr.pub.emit_message = _JPEGErrorHandler2;
|
||||
jerr.pub.output_message = _JPEGErrorHandler;
|
||||
cinfo.err = jpeg_std_error(&(jerr.pub));
|
||||
if (sigsetjmp(jerr.setjmp_buffer, 1))
|
||||
{
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
/* setup compress params */
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_stdio_dest(&cinfo, f);
|
||||
cinfo.image_width = im->w;
|
||||
cinfo.image_height = im->h;
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
/* look for tags attached to image to get extra parameters liek quality */
|
||||
/* settigns etc. - thsi si the "api" to hint for extra information for */
|
||||
/* saver modules */
|
||||
|
||||
/* compression */
|
||||
tag = __imlib_GetTag(im, "compression");
|
||||
if (tag)
|
||||
{
|
||||
compression = tag->val;
|
||||
if (compression < 0)
|
||||
compression = 0;
|
||||
if (compression > 9)
|
||||
compression = 9;
|
||||
}
|
||||
/* convert to quality */
|
||||
quality = (9 - compression) * 10;
|
||||
quality = quality * 10 / 9;
|
||||
/* quality */
|
||||
tag = __imlib_GetTag(im, "quality");
|
||||
if (tag)
|
||||
quality = tag->val;
|
||||
if (quality < 1)
|
||||
quality = 1;
|
||||
if (quality > 100)
|
||||
quality = 100;
|
||||
|
||||
/* set up jepg compression parameters */
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_quality(&cinfo, quality, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
/* get the start pointer */
|
||||
ptr = im->data;
|
||||
/* go one scanline at a time... and save */
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
{
|
||||
/* convcert scaline from ARGB to RGB packed */
|
||||
for (j = 0, i = 0; i < im->w; i++)
|
||||
{
|
||||
buf[j++] = ((*ptr) >> 16) & 0xff;
|
||||
buf[j++] = ((*ptr) >> 8) & 0xff;
|
||||
buf[j++] = ((*ptr)) & 0xff;
|
||||
ptr++;
|
||||
}
|
||||
/* write scanline */
|
||||
jbuf = (JSAMPROW *) (&buf);
|
||||
jpeg_write_scanlines(&cinfo, jbuf, 1);
|
||||
y++;
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) || (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* finish off */
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 1;
|
||||
progress = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
char *list_formats[] = { "jpg", "jpeg", "jfif", "jfi" };
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,550 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
* Reads regular Amiga IFF ILBM files.
|
||||
*
|
||||
* Supports IMLIB2_LBM_NOMASK environment variable. If this is set to "1", then
|
||||
* a transparency mask in an image will be ignored. On the Amiga a mask is often
|
||||
* applied only when loading a brush rather than a picture, but this loader has
|
||||
* no way to tell when the user wants this behaviour from the picture alone.
|
||||
*
|
||||
* Author: John Bickers <jbickers@ihug.co.nz>
|
||||
* Since: 2004-08-21
|
||||
* Version: 2004-08-28
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "image.h"
|
||||
|
||||
char load(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity, char immediate_load);
|
||||
#if 0
|
||||
char save(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity);
|
||||
#endif
|
||||
void formats(ImlibLoader *l);
|
||||
|
||||
|
||||
#define L2RLONG(a) ((((long)((a)[0]) & 0xff) << 24) + (((long)((a)[1]) & 0xff) << 16) + (((long)((a)[2]) & 0xff) << 8) + ((long)((a)[3]) & 0xff))
|
||||
#define L2RWORD(a) ((((long)((a)[0]) & 0xff) << 8) + ((long)((a)[1]) & 0xff))
|
||||
|
||||
typedef struct CHUNK {
|
||||
long size;
|
||||
unsigned char *data;
|
||||
} CHUNK;
|
||||
|
||||
typedef struct ILBM {
|
||||
CHUNK bmhd;
|
||||
CHUNK camg;
|
||||
CHUNK cmap;
|
||||
CHUNK ctbl;
|
||||
CHUNK sham;
|
||||
CHUNK body;
|
||||
|
||||
int depth;
|
||||
int mask;
|
||||
int ham;
|
||||
int hbrite;
|
||||
|
||||
int row;
|
||||
|
||||
int offset;
|
||||
int count;
|
||||
int rle;
|
||||
} ILBM;
|
||||
|
||||
static void freeilbm(ILBM *);
|
||||
static int loadchunks(char *, ILBM *, int);
|
||||
static void bodyrow(unsigned char *, int, ILBM *);
|
||||
static unsigned char scalegun(unsigned char, int);
|
||||
static void scalecmap(ILBM *);
|
||||
static void deplane(DATA32 *, int, ILBM *, unsigned char **);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Frees memory allocated as part of an ILBM structure.
|
||||
*------------------------------------------------------------------------------*/
|
||||
static void freeilbm(ILBM *ilbm)
|
||||
{
|
||||
if (ilbm->bmhd.data) free(ilbm->bmhd.data);
|
||||
if (ilbm->camg.data) free(ilbm->camg.data);
|
||||
if (ilbm->cmap.data) free(ilbm->cmap.data);
|
||||
if (ilbm->ctbl.data) free(ilbm->ctbl.data);
|
||||
if (ilbm->sham.data) free(ilbm->sham.data);
|
||||
if (ilbm->body.data) free(ilbm->body.data);
|
||||
|
||||
memset(ilbm, 0, sizeof(*ilbm));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Reads the given chunks out of a file, returns 0 if the file had a problem.
|
||||
*
|
||||
* Format FORMsizeILBMtag.size....tag.size....tag.size....
|
||||
*------------------------------------------------------------------------------*/
|
||||
static int loadchunks(char *name, ILBM *ilbm, int full)
|
||||
{
|
||||
CHUNK *c;
|
||||
FILE *f;
|
||||
size_t s;
|
||||
long formsize, pos, z;
|
||||
int ok, seek;
|
||||
char buf[12];
|
||||
|
||||
ok = 0;
|
||||
|
||||
f = fopen(name, "rb");
|
||||
if (f) {
|
||||
s = fread(buf, 1, 12, f);
|
||||
if (s == 12 && !memcmp(buf, "FORM", 4) && !memcmp(buf + 8, "ILBM", 4)) {
|
||||
memset(ilbm, 0, sizeof(*ilbm));
|
||||
formsize = L2RLONG(buf + 4);
|
||||
|
||||
while (1) {
|
||||
pos = ftell(f);
|
||||
if (pos < 0 || pos >= formsize + 8) break; /* Error or FORM data is finished. */
|
||||
seek = 1;
|
||||
|
||||
s = fread(buf, 1, 8, f);
|
||||
if (s != 8) break; /* Error or short file. */
|
||||
|
||||
z = L2RLONG(buf + 4);
|
||||
if (z < 0) break; /* Corrupt file. */
|
||||
|
||||
c = NULL;
|
||||
if (!memcmp(buf, "BMHD", 4)) c = &(ilbm->bmhd);
|
||||
else if (full) {
|
||||
if (!memcmp(buf, "CAMG", 4)) c = &(ilbm->camg);
|
||||
else if (!memcmp(buf, "CMAP", 4)) c = &(ilbm->cmap);
|
||||
else if (!memcmp(buf, "CTBL", 4)) c = &(ilbm->ctbl);
|
||||
else if (!memcmp(buf, "SHAM", 4)) c = &(ilbm->sham);
|
||||
else if (!memcmp(buf, "BODY", 4)) c = &(ilbm->body);
|
||||
}
|
||||
|
||||
if (c && !c->data) {
|
||||
c->size = z;
|
||||
c->data = malloc(c->size);
|
||||
if (!c->data) break; /* Out of memory. */
|
||||
|
||||
s = fread(c->data, 1, c->size, f);
|
||||
if (s != c->size) break; /* Error or short file. */
|
||||
|
||||
seek = 0;
|
||||
if (!full) { /* Only BMHD required. */
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos + 8 + z >= formsize + 8) break; /* This was last chunk. */
|
||||
|
||||
if (seek && fseek(f, z, SEEK_CUR) != 0) break;
|
||||
}
|
||||
|
||||
/* File may end strangely, especially if body size is uneven, but it's
|
||||
* ok if we have the chunks we want. !full check is already done. */
|
||||
if (ilbm->bmhd.data && ilbm->body.data) ok = 1;
|
||||
if (!ok) freeilbm(ilbm);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Unpacks a row of possibly RLE data at a time.
|
||||
*
|
||||
* RLE compression depends on a count byte, followed by data bytes.
|
||||
*
|
||||
* 0x80 means skip.
|
||||
* 0xff to 0x81 means repeat one data byte (256 - count) + 1 times.
|
||||
* 0x00 to 0x7f means copy count + 1 data bytes.
|
||||
*
|
||||
* In theory RLE compression is not supposed to create runs across scanlines.
|
||||
*------------------------------------------------------------------------------*/
|
||||
static void bodyrow(unsigned char *p, int z, ILBM *ilbm)
|
||||
{
|
||||
int i, x, w;
|
||||
unsigned char b;
|
||||
|
||||
if (ilbm->offset >= ilbm->body.size) {
|
||||
memset(p, 0, z);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ilbm->rle) {
|
||||
w = ilbm->body.size - ilbm->offset;
|
||||
if (w > z) w = z;
|
||||
memcpy(p, ilbm->body.data + ilbm->offset, w);
|
||||
if (w < z) memset(p + w, 0, z - w);
|
||||
ilbm->offset += w;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < z; ) {
|
||||
b = ilbm->body.data[ilbm->offset++];
|
||||
while (b == 0x80 && ilbm->offset < ilbm->body.size) b = ilbm->body.data[ilbm->offset++];
|
||||
if (ilbm->offset >= ilbm->body.size) break;
|
||||
|
||||
if (b & 0x80) {
|
||||
w = (0x100 - b) + 1;
|
||||
if (w > z - i) w = z - i;
|
||||
|
||||
b = ilbm->body.data[ilbm->offset++];
|
||||
memset(p + i, b, w);
|
||||
i += w;
|
||||
}
|
||||
else {
|
||||
w = (b & 0x7f) + 1;
|
||||
if (w > ilbm->body.size - ilbm->offset) w = ilbm->body.size - ilbm->offset;
|
||||
x = (w <= z - i)? w: z - i;
|
||||
memcpy(p + i, ilbm->body.data + ilbm->offset, x);
|
||||
i += x;
|
||||
ilbm->offset += w;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < z) memset(p, 0, z - i);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Shifts a value to produce an 8-bit colour gun, and fills in the lower bits
|
||||
* from the high bits of the value so that, for example, 4-bit 0x0f scales to
|
||||
* 0xff, or 1-bit 0x01 scales to 0xff.
|
||||
*------------------------------------------------------------------------------*/
|
||||
static unsigned char scalegun(unsigned char v, int sl)
|
||||
{
|
||||
int sr;
|
||||
|
||||
switch (sl) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
sr = 8 - sl;
|
||||
return (v << sl) | (v >> sr);
|
||||
|
||||
case 4:
|
||||
return (v << 4) | v;
|
||||
|
||||
case 5:
|
||||
return v * 0x24;
|
||||
|
||||
case 6:
|
||||
return v * 0x55;
|
||||
|
||||
case 7:
|
||||
return v * 0xff;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Scales the colours in a CMAP chunk if they all look like 4-bit colour, so
|
||||
* that they use all 8-bits. This is done by copying the high nybble into the
|
||||
* low nybble, so for example 0xf0 becomes 0xff.
|
||||
*------------------------------------------------------------------------------*/
|
||||
static void scalecmap(ILBM *ilbm)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ilbm->cmap.data) return;
|
||||
|
||||
for (i = 0; i < ilbm->cmap.size; i++)
|
||||
if (ilbm->cmap.data[i] & 0x0f) return;
|
||||
|
||||
for (i = 0; i < ilbm->cmap.size; i++)
|
||||
ilbm->cmap.data[i] |= ilbm->cmap.data[i] >> 4;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Deplanes and converts an array of bitplanes to a single scanline of DATA32
|
||||
* (unsigned int) values. DATA32 is ARGB.
|
||||
*------------------------------------------------------------------------------*/
|
||||
static void deplane(DATA32 *row, int w, ILBM *ilbm, unsigned char *plane[])
|
||||
{
|
||||
unsigned long l;
|
||||
int i, o, sl, x;
|
||||
unsigned char bit, r, g, b, a, v, h, *pal;
|
||||
|
||||
pal = NULL;
|
||||
if (ilbm->sham.data && ilbm->sham.size >= 2 + (ilbm->row + 1) * 2 * 16)
|
||||
pal = ilbm->sham.data + 2 + ilbm->row * 2 * 16;
|
||||
if (ilbm->ctbl.data && ilbm->ctbl.size >= (ilbm->row + 1) * 2 * 16)
|
||||
pal = ilbm->ctbl.data + ilbm->row * 2 * 16;
|
||||
|
||||
if (ilbm->ham) r = g = b = 0;
|
||||
|
||||
bit = 0x80;
|
||||
o = 0;
|
||||
for (x = 0; x < w; x++) {
|
||||
l = 0;
|
||||
for (i = ilbm->depth - 1; i >= 0; i--) {
|
||||
l = l << 1;
|
||||
if (plane[i][o] & bit) l = l | 1;
|
||||
}
|
||||
a = (ilbm->mask == 0 || (ilbm->mask == 1 && (plane[ilbm->depth][o] & bit)) || ilbm->mask == 2)? 0xff: 0x00;
|
||||
|
||||
if (ilbm->depth == 32) {
|
||||
a = (l >> 24) & 0xff;
|
||||
b = (l >> 16) & 0xff;
|
||||
g = (l >> 8) & 0xff;
|
||||
r = l & 0xff;
|
||||
}
|
||||
else if (ilbm->depth == 24) {
|
||||
b = (l >> 16) & 0xff;
|
||||
g = (l >> 8) & 0xff;
|
||||
r = l & 0xff;
|
||||
}
|
||||
else if (ilbm->ham) {
|
||||
v = l & ((1 << (ilbm->depth - 2)) - 1);
|
||||
h = (l & ~v) >> (ilbm->depth - 2);
|
||||
|
||||
if (h == 0x00) {
|
||||
if (!pal) {
|
||||
if ((v + 1) * 3 <= ilbm->cmap.size) {
|
||||
r = ilbm->cmap.data[v * 3];
|
||||
g = ilbm->cmap.data[v * 3 + 1];
|
||||
b = ilbm->cmap.data[v * 3 + 2];
|
||||
}
|
||||
else r = g = b = 0;
|
||||
}
|
||||
else {
|
||||
r = scalegun(pal[v * 2] & 0x0f, 4);
|
||||
g = scalegun((pal[v * 2 + 1] & 0xf0) >> 4, 4);
|
||||
b = scalegun((pal[v * 2 + 1] & 0x0f), 4);
|
||||
}
|
||||
}
|
||||
else if (h == 0x01) b = scalegun(v, 8 - (ilbm->depth - 2));
|
||||
else if (h == 0x02) r = scalegun(v, 8 - (ilbm->depth - 2));
|
||||
else g = scalegun(v, 8 - (ilbm->depth - 2));
|
||||
}
|
||||
else if (ilbm->hbrite) {
|
||||
v = l & ((1 << (ilbm->depth - 1)) - 1);
|
||||
h = (l & ~v) >> (ilbm->depth - 1);
|
||||
|
||||
if (!pal) {
|
||||
if ((v + 1) * 3 <= ilbm->cmap.size) {
|
||||
r = ilbm->cmap.data[v * 3];
|
||||
g = ilbm->cmap.data[v * 3 + 1];
|
||||
b = ilbm->cmap.data[v * 3 + 2];
|
||||
}
|
||||
else r = g = b = 0;
|
||||
}
|
||||
else {
|
||||
r = scalegun(pal[v * 2] & 0x0f, 4);
|
||||
g = scalegun((pal[v * 2 + 1] & 0xf0) >> 4, 4);
|
||||
b = scalegun((pal[v * 2 + 1] & 0x0f), 4);
|
||||
}
|
||||
|
||||
if (h) {
|
||||
r = r >> 1;
|
||||
g = g >> 1;
|
||||
b = b >> 1;
|
||||
}
|
||||
|
||||
if (ilbm->mask == 2 && v == L2RWORD(ilbm->bmhd.data + 12)) a = 0x00;
|
||||
}
|
||||
else if (ilbm->cmap.size == 0 && !pal) {
|
||||
v = l & ((1 << ilbm->depth) - 1);
|
||||
r = scalegun(v, ilbm->depth);
|
||||
g = r;
|
||||
b = r;
|
||||
}
|
||||
else {
|
||||
v = l & 0xff;
|
||||
if (!pal) {
|
||||
if ((v + 1) * 3 <= ilbm->cmap.size) {
|
||||
r = ilbm->cmap.data[v * 3];
|
||||
g = ilbm->cmap.data[v * 3 + 1];
|
||||
b = ilbm->cmap.data[v * 3 + 2];
|
||||
}
|
||||
else r = g = b = 0;
|
||||
}
|
||||
else {
|
||||
r = scalegun(pal[v * 2] & 0x0f, 4);
|
||||
g = scalegun((pal[v * 2 + 1] & 0xf0) >> 4, 4);
|
||||
b = scalegun((pal[v * 2 + 1] & 0x0f), 4);
|
||||
}
|
||||
|
||||
if (ilbm->mask == 2 && v == L2RWORD(ilbm->bmhd.data + 12)) a = 0x00;
|
||||
}
|
||||
|
||||
row[x] = ((unsigned long)a << 24) | ((unsigned long)r << 16) | ((unsigned long)g << 8) | (unsigned long)b;
|
||||
|
||||
bit = bit >> 1;
|
||||
if (bit == 0) {
|
||||
o++;
|
||||
bit = 0x80;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Loads an image. If im->loader is non-zero, or immediate_load is non-zero, or
|
||||
* progress is non-zero, then the file is fully loaded, otherwise only the width
|
||||
* and height are read.
|
||||
*
|
||||
* Imlib2 doesn't support reading comment chunks like ANNO.
|
||||
*------------------------------------------------------------------------------*/
|
||||
char load(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity, char immediate_load)
|
||||
{
|
||||
char *env;
|
||||
int cancel, full, i, j, k, n, ok, y, z, gran, nexty, prevy;
|
||||
unsigned char *plane[40];
|
||||
ILBM ilbm;
|
||||
|
||||
/*----------
|
||||
* Do nothing if the data is already loaded.
|
||||
*----------*/
|
||||
if (im->data) return 0;
|
||||
|
||||
/*----------
|
||||
* Load the chunk(s) we're interested in. If full is not true, then we only
|
||||
* want the image size and format.
|
||||
*----------*/
|
||||
full = (im->loader || immediate_load || progress);
|
||||
ok = loadchunks(im->real_file, &ilbm, full);
|
||||
if (!ok) return 0;
|
||||
|
||||
/*----------
|
||||
* Use and check header.
|
||||
*----------*/
|
||||
ok = 0;
|
||||
if (ilbm.bmhd.size >= 20) {
|
||||
ok = 1;
|
||||
|
||||
im->w = L2RWORD(ilbm.bmhd.data);
|
||||
im->h = L2RWORD(ilbm.bmhd.data + 2);
|
||||
if (im->w <= 0 || im->h <= 0) ok = 0;
|
||||
|
||||
ilbm.depth = ilbm.bmhd.data[8];
|
||||
if (ilbm.depth < 1 || (ilbm.depth > 8 && ilbm.depth != 24 && ilbm.depth != 32)) ok = 0; /* Only 1 to 8, 24, or 32 planes. */
|
||||
|
||||
ilbm.rle = ilbm.bmhd.data[10];
|
||||
if (ilbm.rle < 0 || ilbm.rle > 1) ok = 0; /* Only NONE or RLE compression. */
|
||||
|
||||
ilbm.mask = ilbm.bmhd.data[9];
|
||||
|
||||
if (ilbm.mask || ilbm.depth == 32) SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
else UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
|
||||
env = getenv("IMLIB2_LBM_NOMASK");
|
||||
if (env && (!strcmp(env, "true") || !strcmp(env, "1") || !strcmp(env, "yes") || !strcmp(env, "on"))) UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
|
||||
if (!im->format) im->format = strdup("lbm");
|
||||
|
||||
ilbm.ham = 0;
|
||||
ilbm.hbrite = 0;
|
||||
if (ilbm.depth <= 8) {
|
||||
if (ilbm.camg.size == 4) {
|
||||
if (ilbm.camg.data[2] & 0x08) ilbm.ham = 1;
|
||||
if (ilbm.camg.data[3] & 0x80) ilbm.hbrite = 1;
|
||||
}
|
||||
else { /* Only guess at ham and hbrite if CMAP is present. */
|
||||
if (ilbm.depth == 6 && full && ilbm.cmap.size >= 3 * 16) ilbm.ham = 1;
|
||||
if (full && !ilbm.ham && ilbm.depth > 1 && ilbm.cmap.size == 3 * (1 << (ilbm.depth - 1))) ilbm.hbrite = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!full || !ok) {
|
||||
freeilbm(&ilbm);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*----------
|
||||
* The source data is planar. Each plane is an even number of bytes wide. If
|
||||
* masking type is 1, there is an extra plane that defines the mask. Scanlines
|
||||
* from each plane are interleaved, from top to bottom. The first plane is the
|
||||
* 0 bit.
|
||||
*----------*/
|
||||
ok = 0;
|
||||
cancel = 0;
|
||||
plane[0] = NULL;
|
||||
|
||||
im->data = malloc(im->w * im->h * sizeof(DATA32));
|
||||
if (im->data) {
|
||||
n = ilbm.depth;
|
||||
if (ilbm.mask == 1) n++;
|
||||
|
||||
plane[0] = malloc(((im->w + 15) / 16) * 2 * n);
|
||||
for (i = 1; i < n; i++) plane[i] = plane[i - 1] + ((im->w + 15) / 16) * 2;
|
||||
|
||||
z = ((im->w + 15) / 16) * 2 * n;
|
||||
|
||||
if (progress) {
|
||||
prevy = 0;
|
||||
if (progress_granularity <= 0) progress_granularity = 1;
|
||||
gran = progress_granularity;
|
||||
nexty = ((im->h * gran) / 100);
|
||||
}
|
||||
|
||||
scalecmap(&ilbm);
|
||||
|
||||
for (y = 0; y < im->h; y++) {
|
||||
bodyrow(plane[0], z, &ilbm);
|
||||
|
||||
deplane(im->data + im->w * y, im->w, &ilbm, plane);
|
||||
ilbm.row++;
|
||||
|
||||
if (progress && (y >= nexty || y == im->h - 1)) {
|
||||
if (!progress(im, (char)((100 * (y + 1)) / im->h), 0, prevy, im->w, y + 1)) {
|
||||
cancel = 1;
|
||||
break;
|
||||
}
|
||||
prevy = y;
|
||||
gran += progress_granularity;
|
||||
nexty = ((im->h * gran) / 100);
|
||||
}
|
||||
}
|
||||
|
||||
ok = !cancel;
|
||||
}
|
||||
|
||||
/*----------
|
||||
* We either had a successful decode, the user cancelled, or we couldn't get
|
||||
* the memory for im->data.
|
||||
*----------*/
|
||||
if (!ok) {
|
||||
if (im->data) free(im->data);
|
||||
im->data = NULL;
|
||||
}
|
||||
|
||||
if (plane[0]) free(plane[0]);
|
||||
|
||||
freeilbm(&ilbm);
|
||||
|
||||
return (cancel)? 2: ok;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Perhaps save only in 32-bit format? The IFF ILBM format has pretty much gone
|
||||
* the way of the Amiga, who saves in this format any more?
|
||||
*------------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
char save(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Identifies the file extensions this loader handles. Standard code from other
|
||||
* loaders.
|
||||
*------------------------------------------------------------------------------*/
|
||||
void formats(ImlibLoader *l)
|
||||
{
|
||||
char *list_formats[] = { "iff", "ilbm", "lbm" };
|
||||
int i;
|
||||
|
||||
l->num_formats = sizeof(list_formats) / sizeof(list_formats[0]);
|
||||
l->formats = malloc(l->num_formats * sizeof(list_formats[0]));
|
||||
for (i = 0; i < l->num_formats; i++) l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
|
@ -1,440 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
#include <png.h>
|
||||
|
||||
/* this is a quick sample png loader module... nice and small isnt it? */
|
||||
|
||||
/* PNG stuff */
|
||||
#define PNG_BYTES_TO_CHECK 4
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
static void comment_free(ImlibImage * im, void *data);
|
||||
static void
|
||||
comment_free(ImlibImage * im, void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
png_uint_32 w32, h32;
|
||||
int w, h;
|
||||
char hasa = 0, hasg = 0;
|
||||
FILE *f;
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
|
||||
/* if immediate_load is 1, then dont delay image laoding as below, or */
|
||||
/* already data in this image - dont load it again */
|
||||
if (im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
/* read header */
|
||||
if (!im->data)
|
||||
{
|
||||
unsigned char buf[PNG_BYTES_TO_CHECK];
|
||||
|
||||
/* if we havent read the header before, set the header data */
|
||||
fread(buf, 1, PNG_BYTES_TO_CHECK, f);
|
||||
if (!png_check_sig(buf, PNG_BYTES_TO_CHECK))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
rewind(f);
|
||||
png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
png_init_io(png_ptr, f);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
|
||||
(png_uint_32 *) (&h32), &bit_depth, &color_type,
|
||||
&interlace_type, NULL, NULL);
|
||||
im->w = (int)w32;
|
||||
im->h = (int)h32;
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
hasa = 1;
|
||||
}
|
||||
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
hasa = 1;
|
||||
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
hasa = 1;
|
||||
hasg = 1;
|
||||
}
|
||||
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
hasg = 1;
|
||||
if (hasa)
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
else
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
/* set the format string member to the lower-case full extension */
|
||||
/* name for the format - so example names would be: */
|
||||
/* "png", "jpeg", "tiff", "ppm", "pgm", "pbm", "gif", "xpm" ... */
|
||||
if (!im->loader)
|
||||
im->format = strdup("png");
|
||||
}
|
||||
/* if its the second phase load OR its immediate load or a progress */
|
||||
/* callback is set then load the data */
|
||||
if ((im->loader) || (immediate_load) || (progress))
|
||||
{
|
||||
unsigned char **lines;
|
||||
int i;
|
||||
|
||||
w = im->w;
|
||||
h = im->h;
|
||||
if (hasa)
|
||||
png_set_expand(png_ptr);
|
||||
/* we want ARGB */
|
||||
/* note form raster: */
|
||||
/* thanks to mustapha for helping debug this on PPC Linux remotely by */
|
||||
/* sending across screenshots all the tiem and me figuring out form them */
|
||||
/* what the hell was up with the colors */
|
||||
/* now png loading shoudl work on big endian machines nicely */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
png_set_swap_alpha(png_ptr);
|
||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
||||
#else
|
||||
png_set_bgr(png_ptr);
|
||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||
#endif
|
||||
/* 16bit color -> 8bit color */
|
||||
png_set_strip_16(png_ptr);
|
||||
/* pack all pixels to byte boundaires */
|
||||
png_set_packing(png_ptr);
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_expand(png_ptr);
|
||||
if (im->data)
|
||||
free(im->data);
|
||||
im->data = malloc(w * h * sizeof(DATA32));
|
||||
if (!im->data)
|
||||
{
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
lines = (unsigned char **)malloc(h * sizeof(unsigned char *));
|
||||
|
||||
if (!lines)
|
||||
{
|
||||
free(im->data);
|
||||
im->data = NULL;
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
if (hasg)
|
||||
{
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
if (png_get_bit_depth(png_ptr, info_ptr) < 8)
|
||||
png_set_gray_1_2_4_to_8(png_ptr);
|
||||
}
|
||||
for (i = 0; i < h; i++)
|
||||
lines[i] = ((unsigned char *)(im->data)) + (i * w * sizeof(DATA32));
|
||||
if (progress)
|
||||
{
|
||||
int y, count, prevy, pass, number_passes, per,
|
||||
nrows = 1;
|
||||
|
||||
count = 0;
|
||||
number_passes = png_set_interlace_handling(png_ptr);
|
||||
for (pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
prevy = 0;
|
||||
per = 0;
|
||||
for (y = 0; y < h; y += nrows)
|
||||
{
|
||||
png_read_rows(png_ptr, &lines[y], NULL, nrows);
|
||||
|
||||
per = (((pass * h) + y) * 100) / (h * number_passes);
|
||||
if ((per - count) >= progress_granularity)
|
||||
{
|
||||
count = per;
|
||||
if (!progress(im, per, 0, prevy, w, y - prevy + 1))
|
||||
{
|
||||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr,
|
||||
(png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
prevy = y + 1;
|
||||
}
|
||||
}
|
||||
if (!progress(im, per, 0, prevy, w, y - prevy + 1))
|
||||
{
|
||||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr,
|
||||
(png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
png_read_image(png_ptr, lines);
|
||||
free(lines);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
}
|
||||
#ifdef PNG_TEXT_SUPPORTED
|
||||
{
|
||||
png_textp text;
|
||||
int num;
|
||||
int i;
|
||||
|
||||
num = 0;
|
||||
png_get_text(png_ptr, info_ptr, &text, &num);
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (!strcmp(text[i].key, "Imlib2-Comment"))
|
||||
__imlib_AttachTag(im, "comment", 0, strdup(text[i].text),
|
||||
comment_free);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
FILE *f;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
DATA32 *ptr;
|
||||
int x, y, j;
|
||||
png_bytep row_ptr, data = NULL;
|
||||
png_color_8 sig_bit;
|
||||
int pl = 0;
|
||||
char pper = 0;
|
||||
ImlibImageTag *tag;
|
||||
int quality = 75, compression = 3, num_passes = 1, pass;
|
||||
|
||||
if (!im->data)
|
||||
return 0;
|
||||
|
||||
f = fopen(im->real_file, "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL)
|
||||
{
|
||||
fclose(f);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||||
return 0;
|
||||
}
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
{
|
||||
fclose(f);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
|
||||
png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check whether we should use interlacing */
|
||||
if ((tag = __imlib_GetTag(im, "interlacing")) && tag->val)
|
||||
{
|
||||
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
png_ptr->interlaced = PNG_INTERLACE_ADAM7;
|
||||
num_passes = png_set_interlace_handling(png_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, f);
|
||||
if (im->flags & F_HAS_ALPHA)
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr, im->w, im->h, 8,
|
||||
PNG_COLOR_TYPE_RGB_ALPHA, png_ptr->interlaced,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
png_set_swap_alpha(png_ptr);
|
||||
#else
|
||||
png_set_bgr(png_ptr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
png_set_IHDR(png_ptr, info_ptr, im->w, im->h, 8, PNG_COLOR_TYPE_RGB,
|
||||
png_ptr->interlaced, PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE);
|
||||
data = malloc(im->w * 3 * sizeof(char));
|
||||
}
|
||||
sig_bit.red = 8;
|
||||
sig_bit.green = 8;
|
||||
sig_bit.blue = 8;
|
||||
sig_bit.alpha = 8;
|
||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||||
/* quality */
|
||||
tag = __imlib_GetTag(im, "quality");
|
||||
if (tag)
|
||||
{
|
||||
quality = tag->val;
|
||||
if (quality < 1)
|
||||
quality = 1;
|
||||
if (quality > 99)
|
||||
quality = 99;
|
||||
}
|
||||
/* convert to compression */
|
||||
quality = quality / 10;
|
||||
compression = 9 - quality;
|
||||
/* compression */
|
||||
tag = __imlib_GetTag(im, "compression");
|
||||
if (tag)
|
||||
compression = tag->val;
|
||||
if (compression < 0)
|
||||
compression = 0;
|
||||
if (compression > 9)
|
||||
compression = 9;
|
||||
tag = __imlib_GetTag(im, "comment");
|
||||
if (tag)
|
||||
{
|
||||
#ifdef PNG_TEXT_SUPPORTED
|
||||
png_text text;
|
||||
|
||||
text.key = "Imlib2-Comment";
|
||||
text.text = tag->data;
|
||||
text.compression = PNG_TEXT_COMPRESSION_zTXt;
|
||||
png_set_text(png_ptr, info_ptr, &(text), 1);
|
||||
#endif
|
||||
}
|
||||
png_set_compression_level(png_ptr, compression);
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
png_set_shift(png_ptr, &sig_bit);
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
for (pass = 0; pass < num_passes; pass++)
|
||||
{
|
||||
ptr = im->data;
|
||||
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
if (im->flags & F_HAS_ALPHA)
|
||||
row_ptr = (png_bytep) ptr;
|
||||
else
|
||||
{
|
||||
for (j = 0, x = 0; x < im->w; x++)
|
||||
{
|
||||
data[j++] = (ptr[x] >> 16) & 0xff;
|
||||
data[j++] = (ptr[x] >> 8) & 0xff;
|
||||
data[j++] = (ptr[x]) & 0xff;
|
||||
}
|
||||
row_ptr = (png_bytep) data;
|
||||
}
|
||||
png_write_rows(png_ptr, &row_ptr, 1);
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = 100 * (pass + y / (float) im->h) / num_passes;
|
||||
if ((per - pper) >= progress_granularity)
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr,
|
||||
(png_infopp) & info_ptr);
|
||||
png_destroy_info_struct(png_ptr,
|
||||
(png_infopp) & info_ptr);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
ptr += im->w;
|
||||
}
|
||||
}
|
||||
if (data)
|
||||
free(data);
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
|
||||
png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
|
||||
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fills the ImlibLoader struct with a strign array of format file */
|
||||
/* extensions this loader can load. eg: */
|
||||
/* loader->formats = { "jpeg", "jpg"}; */
|
||||
/* giving permutations is a good idea. case sensitivity is irrelevant */
|
||||
/* your loader CAN load more than one format if it likes - like: */
|
||||
/* loader->formats = { "gif", "png", "jpeg", "jpg"} */
|
||||
/* if it can load those formats. */
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] = { "png" };
|
||||
|
||||
/* don't bother changing any of this - it just reads this in and sets */
|
||||
/* the struct values and makes copies */
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,832 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include "image.h"
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
char p = ' ', numbers = 3, count = 0;
|
||||
int w = 0, h = 0, v = 255, c = 0;
|
||||
char buf[256];
|
||||
FILE *f = NULL;
|
||||
|
||||
if (im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
/* can't use fgets(), because there might be
|
||||
* binary data after the header and there
|
||||
* needn't be a newline before the data, so
|
||||
* no chance to distinguish between end of buffer
|
||||
* and a binary 0.
|
||||
*/
|
||||
|
||||
/* read the header info */
|
||||
|
||||
c = fgetc(f);
|
||||
if (c != 'P')
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = fgetc(f);
|
||||
if (p == '1' || p == '4')
|
||||
numbers = 2; /* bitimages don't have max value */
|
||||
|
||||
if ((p < '1') || (p > '8'))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
count = 0;
|
||||
while (count < numbers)
|
||||
{
|
||||
c = fgetc(f);
|
||||
|
||||
if (c == EOF)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* eat whitespace */
|
||||
while (isspace(c))
|
||||
c = fgetc(f);
|
||||
/* if comment, eat that */
|
||||
if (c == '#')
|
||||
{
|
||||
do
|
||||
c = fgetc(f);
|
||||
while (c != '\n' && c != EOF);
|
||||
}
|
||||
/* no comment -> proceed */
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* read numbers */
|
||||
while (c != EOF && !isspace(c))
|
||||
{
|
||||
buf[i++] = c;
|
||||
c = fgetc(f);
|
||||
}
|
||||
if (i)
|
||||
{
|
||||
buf[i] = 0;
|
||||
count++;
|
||||
switch (count)
|
||||
{
|
||||
/* width */
|
||||
case 1:
|
||||
w = atoi(buf);
|
||||
break;
|
||||
/* height */
|
||||
case 2:
|
||||
h = atoi(buf);
|
||||
break;
|
||||
/* max value, only for color and greyscale */
|
||||
case 3:
|
||||
v = atoi(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((w <= 0) || (w > 8192) || (h <= 0) || (h > 8192) || (v < 0) || (v > 255))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
if (!im->format)
|
||||
{
|
||||
if (p == '8')
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
else
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
im->format = strdup("pnm");
|
||||
}
|
||||
|
||||
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
|
||||
{
|
||||
DATA8 *data = NULL; /* for the binary versions */
|
||||
DATA8 *ptr = NULL;
|
||||
int *idata = NULL; /* for the ASCII versions */
|
||||
int *iptr;
|
||||
char buf2[256];
|
||||
DATA32 *ptr2;
|
||||
int i, j, x, y, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
/* must set the im->data member before callign progress function */
|
||||
ptr2 = im->data = malloc(w * h * sizeof(DATA32));
|
||||
if (!im->data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
/* start reading the data */
|
||||
switch (p)
|
||||
{
|
||||
case '1': /* ASCII monochrome */
|
||||
buf[0] = 0;
|
||||
i = 0;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
x = 0;
|
||||
while (x < w)
|
||||
{
|
||||
if (!buf[i]) /* fill buffer */
|
||||
{
|
||||
if (!fgets(buf, 255, f))
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
while (buf[i] && isspace(buf[i]))
|
||||
i++;
|
||||
if (buf[i])
|
||||
{
|
||||
if (buf[i] == '1')
|
||||
*ptr2 = 0xff000000;
|
||||
else if (buf[i] == '0')
|
||||
*ptr2 = 0xffffffff;
|
||||
else
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr2++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '2': /* ASCII greyscale */
|
||||
idata = malloc(sizeof(int) * w);
|
||||
|
||||
if (!idata)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
buf[0] = 0;
|
||||
i = 0;
|
||||
j = 0;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
iptr = idata;
|
||||
x = 0;
|
||||
while (x < w)
|
||||
{
|
||||
if (!buf[i]) /* fill buffer */
|
||||
{
|
||||
if (!fgets(buf, 255, f))
|
||||
{
|
||||
free(idata);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
while (buf[i] && isspace(buf[i]))
|
||||
i++;
|
||||
while (buf[i] && !isspace(buf[i]))
|
||||
buf2[j++] = buf[i++];
|
||||
if (j)
|
||||
{
|
||||
buf2[j] = 0;
|
||||
*(iptr++) = atoi(buf2);
|
||||
j = 0;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
iptr = idata;
|
||||
if (v == 255)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (iptr[0] << 16) | (iptr[0] << 8)
|
||||
| iptr[0];
|
||||
ptr2++;
|
||||
iptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (((iptr[0] * 255) / v) << 16) |
|
||||
(((iptr[0] * 255) / v) << 8) | ((iptr[0] *
|
||||
255) / v);
|
||||
ptr2++;
|
||||
iptr++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
|
||||
l = y - pl;
|
||||
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
if (idata)
|
||||
free(idata);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '3': /* ASCII RGB */
|
||||
idata = malloc(3 * sizeof(int) * w);
|
||||
|
||||
if (!idata)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
buf[0] = 0;
|
||||
i = 0;
|
||||
j = 0;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
int w3 = 3 * w;
|
||||
|
||||
iptr = idata;
|
||||
x = 0;
|
||||
while (x < w3)
|
||||
{
|
||||
if (!buf[i]) /* fill buffer */
|
||||
{
|
||||
if (!fgets(buf, 255, f))
|
||||
{
|
||||
free(idata);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
while (buf[i] && isspace(buf[i]))
|
||||
i++;
|
||||
while (buf[i] && !isspace(buf[i]))
|
||||
buf2[j++] = buf[i++];
|
||||
if (j)
|
||||
{
|
||||
buf2[j] = 0;
|
||||
*(iptr++) = atoi(buf2);
|
||||
j = 0;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
iptr = idata;
|
||||
if (v == 255)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (iptr[0] << 16) | (iptr[1] << 8)
|
||||
| iptr[2];
|
||||
ptr2++;
|
||||
iptr += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (((ptr[0] * 255) / v) << 16) |
|
||||
(((iptr[1] * 255) / v) << 8) | ((iptr[2] *
|
||||
255) / v);
|
||||
ptr2++;
|
||||
iptr += 3;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
if (idata)
|
||||
free(idata);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '4': /* binary 1bit monochrome */
|
||||
data = malloc(1 * sizeof(DATA8));
|
||||
if (!data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr2 = im->data;
|
||||
j = 0;
|
||||
while ((fread(data, 1, 1, f)) && (j < (w * h)))
|
||||
{
|
||||
for (i = 7; i >= 0; i--)
|
||||
{
|
||||
if (j < (w * h))
|
||||
{
|
||||
if (data[0] & (1 << i))
|
||||
*ptr2 = 0xff000000;
|
||||
else
|
||||
*ptr2 = 0xffffffff;
|
||||
ptr2++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '5': /* binary 8bit grayscale GGGGGGGG */
|
||||
data = malloc(1 * sizeof(DATA8) * w);
|
||||
if (!data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr2 = im->data;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
if (!fread(data, w * 1, 1, f))
|
||||
{
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
ptr = data;
|
||||
if (v == 255)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (ptr[0] << 16) | (ptr[0] << 8) |
|
||||
ptr[0];
|
||||
ptr2++;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (((ptr[0] * 255) / v) << 16) |
|
||||
(((ptr[0] * 255) / v) << 8) | ((ptr[0] *
|
||||
255) / v);
|
||||
ptr2++;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '6': /* 24bit binary RGBRGBRGB */
|
||||
data = malloc(3 * sizeof(DATA8) * w);
|
||||
if (!data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr2 = im->data;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
if (!fread(data, w * 3, 1, f))
|
||||
{
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
ptr = data;
|
||||
if (v == 255)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (ptr[0] << 16) | (ptr[1] << 8) |
|
||||
ptr[2];
|
||||
ptr2++;
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
0xff000000 | (((ptr[0] * 255) / v) << 16) |
|
||||
(((ptr[1] * 255) / v) << 8) | ((ptr[2] *
|
||||
255) / v);
|
||||
ptr2++;
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '7': /* XV's 8bit 332 format */
|
||||
data = malloc(1 * sizeof(DATA8) * w);
|
||||
if (!data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr2 = im->data;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
if (!fread(data, w * 1, 1, f))
|
||||
{
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
ptr = data;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = (*ptr >> 5) & 0x7;
|
||||
g = (*ptr >> 2) & 0x7;
|
||||
b = (*ptr) & 0x3;
|
||||
*ptr2 =
|
||||
0xff000000 | (((r << 21) | (r << 18) | (r << 15)) &
|
||||
0xff0000) | (((g << 13) | (g << 10) |
|
||||
(g << 7)) & 0xff00) |
|
||||
((b << 6) | (b << 4) | (b << 2) | (b << 0));
|
||||
ptr2++;
|
||||
ptr++;
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l = 0;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '8': /* 24bit binary RGBARGBARGBA */
|
||||
data = malloc(4 * sizeof(DATA8) * w);
|
||||
if (!data)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr2 = im->data;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
if (!fread(data, w * 4, 1, f))
|
||||
{
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
ptr = data;
|
||||
if (v == 255)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
(ptr[3] << 24) | (ptr[0] << 16) | (ptr[1] <<
|
||||
8) |
|
||||
ptr[2];
|
||||
ptr2++;
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr2 =
|
||||
(((ptr[3] * 255) /
|
||||
v) << 24) | (((ptr[0] * 255) /
|
||||
v) << 16) | (((ptr[1] * 255) /
|
||||
v) << 8) |
|
||||
((ptr[2] * 255) / v);
|
||||
ptr2++;
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l = 0;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
/* fix off by one in case of the last line */
|
||||
if (y == (im->h - 1))
|
||||
l++;
|
||||
|
||||
if (!progress(im, per, 0, pl, im->w, l))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fclose(f);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (idata)
|
||||
free(idata);
|
||||
if (data)
|
||||
free(data);
|
||||
}
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
FILE *f;
|
||||
DATA8 *buf, *bptr;
|
||||
DATA32 *ptr;
|
||||
int x, y, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
/* no image data? abort */
|
||||
if (!im->data)
|
||||
return 0;
|
||||
f = fopen(im->real_file, "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
/* if the image has a useful alpha channel */
|
||||
if (im->flags & F_HAS_ALPHA)
|
||||
{
|
||||
/* allocate a small buffer to convert image data */
|
||||
buf = malloc(im->w * 4 * sizeof(DATA8));
|
||||
if (!buf)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr = im->data;
|
||||
fprintf(f, "P8\n" "# PNM File written by Imlib2\n" "%i %i\n" "255\n",
|
||||
im->w, im->h);
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
bptr = buf;
|
||||
for (x = 0; x < im->w; x++)
|
||||
{
|
||||
bptr[0] = ((*ptr) >> 16) & 0xff;
|
||||
bptr[1] = ((*ptr) >> 8) & 0xff;
|
||||
bptr[2] = ((*ptr)) & 0xff;
|
||||
bptr[3] = ((*ptr) >> 24) & 0xff;
|
||||
bptr += 4;
|
||||
ptr++;
|
||||
}
|
||||
fwrite(buf, im->w * 4, 1, f);
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allocate a small buffer to convert image data */
|
||||
buf = malloc(im->w * 3 * sizeof(DATA8));
|
||||
if (!buf)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
ptr = im->data;
|
||||
fprintf(f, "P6\n" "# PNM File written by Imlib2\n" "%i %i\n" "255\n",
|
||||
im->w, im->h);
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
bptr = buf;
|
||||
for (x = 0; x < im->w; x++)
|
||||
{
|
||||
bptr[0] = ((*ptr) >> 16) & 0xff;
|
||||
bptr[1] = ((*ptr) >> 8) & 0xff;
|
||||
bptr[2] = ((*ptr)) & 0xff;
|
||||
bptr += 3;
|
||||
ptr++;
|
||||
}
|
||||
fwrite(buf, im->w * 3, 1, f);
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity)
|
||||
|| (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* finish off */
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 1;
|
||||
progress = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
char *list_formats[] = { "pnm", "ppm", "pgm", "pbm", "pam" };
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,584 +0,0 @@
|
|||
/*
|
||||
* loader_tga.c - Loader for Truevision Targa images
|
||||
* for Imlib2
|
||||
*
|
||||
* by Dan Maas <dmaas@dcine.com> May 15, 2000
|
||||
*
|
||||
* based on TGA specifications available at:
|
||||
* http://www.wotsit.org/cgi-bin/search.cgi?TGA
|
||||
*
|
||||
* header/footer structures courtesy of the GIMP Targa plugin
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
#include "colormod.h"
|
||||
#include "blend.h"
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
/* flip an inverted image - see RLE reading below */
|
||||
static void tgaflip(DATA32 * in, int w, int h);
|
||||
|
||||
/* TGA pixel formats */
|
||||
#define TGA_TYPE_MAPPED 1
|
||||
#define TGA_TYPE_COLOR 2
|
||||
#define TGA_TYPE_GRAY 3
|
||||
#define TGA_TYPE_MAPPED_RLE 9
|
||||
#define TGA_TYPE_COLOR_RLE 10
|
||||
#define TGA_TYPE_GRAY_RLE 11
|
||||
|
||||
/* TGA header flags */
|
||||
#define TGA_DESC_ABITS 0x0f
|
||||
#define TGA_DESC_HORIZONTAL 0x10
|
||||
#define TGA_DESC_VERTICAL 0x20
|
||||
|
||||
#define TGA_SIGNATURE "TRUEVISION-XFILE"
|
||||
|
||||
typedef struct {
|
||||
unsigned char idLength;
|
||||
unsigned char colorMapType;
|
||||
unsigned char imageType;
|
||||
unsigned char colorMapIndexLo, colorMapIndexHi;
|
||||
unsigned char colorMapLengthLo, colorMapLengthHi;
|
||||
unsigned char colorMapSize;
|
||||
unsigned char xOriginLo, xOriginHi;
|
||||
unsigned char yOriginLo, yOriginHi;
|
||||
unsigned char widthLo, widthHi;
|
||||
unsigned char heightLo, heightHi;
|
||||
unsigned char bpp;
|
||||
unsigned char descriptor;
|
||||
} tga_header;
|
||||
|
||||
typedef struct {
|
||||
unsigned int extensionAreaOffset;
|
||||
unsigned int developerDirectoryOffset;
|
||||
char signature[16];
|
||||
char dot;
|
||||
char null;
|
||||
} tga_footer;
|
||||
|
||||
/*
|
||||
* Write an uncompressed RGBA 24- or 32-bit targa to disk
|
||||
* (If anyone wants to write a RLE saver, feel free =)
|
||||
*/
|
||||
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
FILE *f;
|
||||
DATA32 *dataptr;
|
||||
unsigned char *buf, *bufptr;
|
||||
int y, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
tga_header header;
|
||||
|
||||
if (!im->data)
|
||||
return 0;
|
||||
|
||||
f = fopen(im->real_file, "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
/* assemble the TGA header information */
|
||||
|
||||
/* most entries are zero... */
|
||||
memset(&header, 0x0, sizeof(header));
|
||||
|
||||
/* uncompressed RGB Targa identifier */
|
||||
header.imageType = TGA_TYPE_COLOR;
|
||||
|
||||
/* image width, low byte */
|
||||
header.widthLo = im->w & 0xFF;
|
||||
/* image width, high byte */
|
||||
header.widthHi = im->w >> 8;
|
||||
|
||||
/* image height, low byte */
|
||||
header.heightLo = im->h & 0xFF;
|
||||
/* image height, high byte */
|
||||
header.heightHi = im->h >> 8;
|
||||
|
||||
/* total number of bits per pixel */
|
||||
header.bpp = (im->flags & F_HAS_ALPHA) ? 32 : 24;
|
||||
/* number of extra (alpha) bits per pixel */
|
||||
header.descriptor = (im->flags & F_HAS_ALPHA) ? 8 : 0;
|
||||
|
||||
/* top-to-bottom storage */
|
||||
header.descriptor |= TGA_DESC_VERTICAL;
|
||||
|
||||
/* allocate a buffer to receive the BGRA-swapped pixel values */
|
||||
buf = malloc(im->w * im->h * ((im->flags & F_HAS_ALPHA) ? 4 : 3));
|
||||
if (!buf)
|
||||
{
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now we have to read from im->data into buf, swapping RGBA to BGRA */
|
||||
dataptr = im->data;
|
||||
bufptr = buf;
|
||||
|
||||
/* for each row */
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
int x;
|
||||
unsigned char r, g, b, a;
|
||||
|
||||
/* for each pixel in the row */
|
||||
for (x = 0; x < im->w; x++)
|
||||
{
|
||||
if (im->flags & F_HAS_ALPHA)
|
||||
{
|
||||
READ_RGBA(dataptr, r, g, b, a);
|
||||
*bufptr++ = b;
|
||||
*bufptr++ = g;
|
||||
*bufptr++ = r;
|
||||
*bufptr++ = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
READ_RGB(dataptr, r, g, b);
|
||||
*bufptr++ = b;
|
||||
*bufptr++ = g;
|
||||
*bufptr++ = r;
|
||||
}
|
||||
dataptr++;
|
||||
} /* end for (each pixel in row) */
|
||||
|
||||
/* report progress every row */
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if (((per - pper) >= progress_granularity) || (y == (im->h - 1)))
|
||||
{
|
||||
l = y - pl;
|
||||
if (!progress(im, per, 0, (y - l), im->w, l))
|
||||
{
|
||||
if (buf)
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write the header */
|
||||
fwrite(&header, sizeof(header), 1, f);
|
||||
|
||||
/* write the image data */
|
||||
fwrite(buf, 1, im->w * im->h * ((im->flags & F_HAS_ALPHA) ? 4 : 3), f);
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load up a TGA file
|
||||
*
|
||||
* As written this function only recognizes the following types of Targas:
|
||||
* Type 02 - Uncompressed RGB, 24 or 32 bits
|
||||
* Type 03 - Uncompressed grayscale, 8 bits
|
||||
* Type 10 - RLE-compressed RGB, 24 or 32 bits
|
||||
* Type 11 - RLE-compressed grayscale, 8 bits
|
||||
* There are several other (uncommon) Targa formats which this function can't currently handle
|
||||
*/
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
int fd;
|
||||
void *seg, *filedata;
|
||||
struct stat ss;
|
||||
int bpp, vinverted = 0;
|
||||
int rle = 0, footer_present = 0;
|
||||
|
||||
tga_header *header;
|
||||
tga_footer *footer;
|
||||
|
||||
if (im->data)
|
||||
return 0;
|
||||
|
||||
fd = open(im->real_file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
if (fstat(fd, &ss) < 0)
|
||||
{
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ss.st_size < sizeof(tga_header) + sizeof(tga_footer))
|
||||
{
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
seg = mmap(0, ss.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (seg == MAP_FAILED)
|
||||
{
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
filedata = seg;
|
||||
header = (tga_header *) filedata;
|
||||
footer = (tga_footer *) ((char *)filedata + ss.st_size - sizeof(tga_footer));
|
||||
|
||||
/* check the footer to see if we have a v2.0 TGA file */
|
||||
if (memcmp(footer->signature, TGA_SIGNATURE, sizeof(footer->signature)) == 0)
|
||||
footer_present = 1;
|
||||
|
||||
if (!footer_present)
|
||||
{
|
||||
}
|
||||
|
||||
/* skip over header */
|
||||
filedata = (char *)filedata + sizeof(tga_header);
|
||||
|
||||
/* skip over alphanumeric ID field */
|
||||
if (header->idLength)
|
||||
filedata = (char *)filedata + header->idLength;
|
||||
|
||||
/* now parse the header */
|
||||
|
||||
/* this flag indicated bottom-up pixel storage */
|
||||
vinverted = !(header->descriptor & TGA_DESC_VERTICAL);
|
||||
|
||||
switch (header->imageType)
|
||||
{
|
||||
case TGA_TYPE_COLOR_RLE:
|
||||
case TGA_TYPE_GRAY_RLE:
|
||||
rle = 1;
|
||||
break;
|
||||
|
||||
case TGA_TYPE_COLOR:
|
||||
case TGA_TYPE_GRAY:
|
||||
rle = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
munmap(seg, ss.st_size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* bits per pixel */
|
||||
bpp = header->bpp;
|
||||
|
||||
if (!((bpp == 32) || (bpp == 24) || (bpp == 8)))
|
||||
{
|
||||
munmap(seg, ss.st_size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* endian-safe loading of 16-bit sizes */
|
||||
im->w = (header->widthHi << 8) | header->widthLo;
|
||||
im->h = (header->heightHi << 8) | header->heightLo;
|
||||
|
||||
if ((im->w > 32767) || (im->w < 1) || (im->h > 32767) || (im->h < 1))
|
||||
{
|
||||
im->w = 0;
|
||||
munmap(seg, ss.st_size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!im->format)
|
||||
{
|
||||
if (bpp == 32)
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
else
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
im->format = strdup("tga");
|
||||
}
|
||||
|
||||
/* if we need to actually read the pixel data... */
|
||||
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
|
||||
{
|
||||
unsigned long datasize;
|
||||
unsigned char *bufptr;
|
||||
DATA32 *dataptr;
|
||||
|
||||
int y, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
/* allocate the destination buffer */
|
||||
im->data = malloc(im->w * im->h * sizeof(DATA32));
|
||||
if (!im->data)
|
||||
{
|
||||
im->w = 0;
|
||||
munmap(seg, ss.st_size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* first we read the file data into a buffer for parsing */
|
||||
/* then we decode from RAM */
|
||||
|
||||
/* find out how much data must be read from the file */
|
||||
/* (this is NOT simply width*height*4, due to compression) */
|
||||
|
||||
datasize = ss.st_size - sizeof(tga_header) - header->idLength -
|
||||
(footer_present ? sizeof(tga_footer) : 0);
|
||||
|
||||
/* buffer is ready for parsing */
|
||||
|
||||
/* bufptr is the next byte to be read from the buffer */
|
||||
bufptr = filedata;
|
||||
|
||||
/* dataptr is the next 32-bit pixel to be filled in */
|
||||
dataptr = im->data;
|
||||
|
||||
/* decode uncompressed BGRA data */
|
||||
if (!rle)
|
||||
{
|
||||
for (y = 0; y < im->h; y++) /* for each row */
|
||||
{
|
||||
int x;
|
||||
|
||||
/* point dataptr at the beginning of the row */
|
||||
if (vinverted)
|
||||
/* some TGA's are stored upside-down! */
|
||||
dataptr = im->data + ((im->h - y - 1) * im->w);
|
||||
else
|
||||
dataptr = im->data + (y * im->w);
|
||||
|
||||
for (x = 0; x < im->w; x++) /* for each pixel in the row */
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
|
||||
/* 32-bit BGRA pixels */
|
||||
case 32:
|
||||
WRITE_RGBA(dataptr,
|
||||
*(bufptr + 2), /* R */
|
||||
*(bufptr + 1), /* G */
|
||||
*(bufptr + 0), /* B */
|
||||
*(bufptr + 3) /* A */
|
||||
);
|
||||
dataptr++;
|
||||
bufptr += 4;
|
||||
break;
|
||||
|
||||
/* 24-bit BGR pixels */
|
||||
case 24:
|
||||
WRITE_RGBA(dataptr,
|
||||
*(bufptr + 2), /* R */
|
||||
*(bufptr + 1), /* G */
|
||||
*(bufptr + 0), /* B */
|
||||
(char)0xff /* A */
|
||||
);
|
||||
dataptr++;
|
||||
bufptr += 3;
|
||||
break;
|
||||
|
||||
/* 8-bit grayscale */
|
||||
case 8:
|
||||
WRITE_RGBA(dataptr, /* grayscale */
|
||||
*bufptr,
|
||||
*bufptr,
|
||||
*bufptr, (char)0xff);
|
||||
dataptr++;
|
||||
bufptr += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
} /* end for (each pixel) */
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
progress(im, 100, 0, 0, im->w, im->h);
|
||||
} /* end for (each row) */
|
||||
}
|
||||
/* end if (!RLE) */
|
||||
/* decode RLE compressed data */
|
||||
else
|
||||
{
|
||||
unsigned char curbyte, red, green, blue, alpha;
|
||||
DATA32 *final_pixel = dataptr + im->w * im->h;
|
||||
|
||||
/* loop until we've got all the pixels */
|
||||
while (dataptr < final_pixel)
|
||||
{
|
||||
int count;
|
||||
|
||||
curbyte = *bufptr++;
|
||||
count = (curbyte & 0x7F) + 1;
|
||||
|
||||
if (curbyte & 0x80) /* RLE packet */
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 32:
|
||||
blue = *bufptr++;
|
||||
green = *bufptr++;
|
||||
red = *bufptr++;
|
||||
alpha = *bufptr++;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
WRITE_RGBA(dataptr, red, green, blue, alpha);
|
||||
dataptr++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
blue = *bufptr++;
|
||||
green = *bufptr++;
|
||||
red = *bufptr++;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
WRITE_RGBA(dataptr, red, green, blue,
|
||||
(char)0xff);
|
||||
dataptr++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
alpha = *bufptr++;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
WRITE_RGBA(dataptr, alpha, alpha, alpha,
|
||||
(char)0xff);
|
||||
dataptr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} /* end if (RLE packet) */
|
||||
|
||||
else /* raw packet */
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
|
||||
/* 32-bit BGRA pixels */
|
||||
case 32:
|
||||
WRITE_RGBA(dataptr, *(bufptr + 2), /* R */
|
||||
*(bufptr + 1), /* G */
|
||||
*(bufptr + 0), /* B */
|
||||
*(bufptr + 3) /* A */
|
||||
);
|
||||
dataptr++;
|
||||
bufptr += 4;
|
||||
break;
|
||||
|
||||
/* 24-bit BGR pixels */
|
||||
case 24:
|
||||
WRITE_RGBA(dataptr, *(bufptr + 2), /* R */
|
||||
*(bufptr + 1), /* G */
|
||||
*(bufptr + 0), /* B */
|
||||
(char)0xff /* A */
|
||||
);
|
||||
dataptr++;
|
||||
bufptr += 3;
|
||||
break;
|
||||
|
||||
/* 8-bit grayscale */
|
||||
case 8:
|
||||
WRITE_RGBA(dataptr, *bufptr, /* pseudo-grayscale */
|
||||
*bufptr, *bufptr, (char)0xff);
|
||||
dataptr++;
|
||||
bufptr += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end if (raw packet) */
|
||||
} /* end for (each packet) */
|
||||
/* must now flip a bottom-up image */
|
||||
if (vinverted) tgaflip(im->data, im->w, im->h);
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
progress(im, 100, 0, 0, im->w, im->h);
|
||||
} /* end for (each row) */
|
||||
}
|
||||
/* end if (image is RLE) */
|
||||
}
|
||||
/* end if (loading pixel data) */
|
||||
|
||||
munmap(seg, ss.st_size);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
char *list_formats[] = { "tga" };
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************/
|
||||
|
||||
/* flip a DATA32 image block vertically in place */
|
||||
|
||||
static void
|
||||
tgaflip (DATA32 * in, int w, int h)
|
||||
{
|
||||
DATA32 *adv, *adv2;
|
||||
int x, y;
|
||||
|
||||
adv = in;
|
||||
adv2 = in + (w * (h - 1));
|
||||
|
||||
for (y = 0; y < (h / 2); y++)
|
||||
{
|
||||
DATA32 tmp;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
tmp = adv[x];
|
||||
adv[x] = adv2[x];
|
||||
adv2[x] = tmp;
|
||||
}
|
||||
adv2 -= w;
|
||||
adv += w;
|
||||
}
|
||||
}
|
|
@ -1,494 +0,0 @@
|
|||
/* To do: */
|
||||
/* o Need code to handle tiff with different orientations */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "image.h"
|
||||
#include <tiffio.h>
|
||||
|
||||
/* This is a wrapper data structure for TIFFRGBAImage, so that data can be */
|
||||
/* passed into the callbacks. More elegent, I think, than a bunch of globals */
|
||||
|
||||
struct TIFFRGBAImage_Extra {
|
||||
TIFFRGBAImage rgba;
|
||||
tileContigRoutine put_contig;
|
||||
tileSeparateRoutine put_separate;
|
||||
ImlibImage *image;
|
||||
ImlibProgressFunction progress;
|
||||
char pper;
|
||||
char progress_granularity;
|
||||
uint32 num_pixels;
|
||||
uint32 py;
|
||||
};
|
||||
|
||||
typedef struct TIFFRGBAImage_Extra TIFFRGBAImage_Extra;
|
||||
|
||||
static void put_contig_and_raster(TIFFRGBAImage *, uint32 *,
|
||||
uint32, uint32, uint32, uint32, int32,
|
||||
int32, unsigned char *);
|
||||
static void put_separate_and_raster(TIFFRGBAImage *, uint32 *, uint32,
|
||||
uint32, uint32, uint32, int32,
|
||||
int32, unsigned char *,
|
||||
unsigned char *, unsigned char *,
|
||||
unsigned char *);
|
||||
static void raster(TIFFRGBAImage_Extra * img, uint32 * raster, uint32 x,
|
||||
uint32 y, uint32 w, uint32 h);
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
static void
|
||||
put_contig_and_raster(TIFFRGBAImage * img, uint32 * rast,
|
||||
uint32 x, uint32 y, uint32 w, uint32 h,
|
||||
int32 fromskew, int32 toskew, unsigned char *cp)
|
||||
{
|
||||
(*(((TIFFRGBAImage_Extra *) img)->put_contig)) (img, rast, x, y, w, h,
|
||||
fromskew, toskew, cp);
|
||||
raster((TIFFRGBAImage_Extra *) img, rast, x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
put_separate_and_raster(TIFFRGBAImage * img, uint32 * rast,
|
||||
uint32 x, uint32 y, uint32 w, uint32 h,
|
||||
int32 fromskew, int32 toskew,
|
||||
unsigned char *r, unsigned char *g, unsigned char *b,
|
||||
unsigned char *a)
|
||||
{
|
||||
(*(((TIFFRGBAImage_Extra *) img)->put_separate))
|
||||
(img, rast, x, y, w, h, fromskew, toskew, r, g, b, a);
|
||||
raster((TIFFRGBAImage_Extra *) img, rast, x, y, w, h);
|
||||
}
|
||||
|
||||
/* needs orientation code */
|
||||
|
||||
static void
|
||||
raster(TIFFRGBAImage_Extra * img, uint32 * rast,
|
||||
uint32 x, uint32 y, uint32 w, uint32 h)
|
||||
{
|
||||
uint32 image_width, image_height;
|
||||
uint32 *pixel, pixel_value;
|
||||
int i, j, dy, rast_offset;
|
||||
DATA32 *buffer_pixel, *buffer = img->image->data;
|
||||
|
||||
image_width = img->image->w;
|
||||
image_height = img->image->h;
|
||||
|
||||
dy = h > y ? -1 : y - h;
|
||||
|
||||
/* rast seems to point to the beginning of the last strip processed */
|
||||
/* so you need use negative offsets. Bizzare. Someone please check this */
|
||||
/* I don't understand why, but that seems to be what's going on. */
|
||||
/* libtiff needs better docs! */
|
||||
|
||||
for (i = y, rast_offset = 0; i > dy; i--, rast_offset--)
|
||||
{
|
||||
pixel = rast + (rast_offset * image_width);
|
||||
buffer_pixel = buffer + ((((image_height - 1) - i) * image_width) + x);
|
||||
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
pixel_value = (*(pixel++));
|
||||
(*(buffer_pixel++)) =
|
||||
(TIFFGetA(pixel_value) << 24) |
|
||||
(TIFFGetR(pixel_value) << 16) | (TIFFGetG(pixel_value) << 8) |
|
||||
TIFFGetB(pixel_value);
|
||||
}
|
||||
}
|
||||
|
||||
if (img->progress)
|
||||
{
|
||||
char per;
|
||||
uint32 real_y = (image_height - 1) - y;
|
||||
|
||||
if (w >= image_width)
|
||||
{
|
||||
per = (char)(((real_y + h - 1) * 100) / image_height);
|
||||
|
||||
if (((per - img->pper) >= img->progress_granularity) ||
|
||||
(real_y + h) >= image_height)
|
||||
{
|
||||
(*img->progress) (img->image, per, 0, img->py, w,
|
||||
(real_y + h) - img->py);
|
||||
img->py = real_y + h;
|
||||
img->pper = per;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for tile based images, we just progress each tile because */
|
||||
/* of laziness. Couldn't think of a good way to do this */
|
||||
per = (char)((w * h * 100) / img->num_pixels);
|
||||
img->pper += per;
|
||||
(*img->progress) (img->image, img->pper, x,
|
||||
(image_height - 1) - y, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
TIFF *tif = NULL;
|
||||
FILE *file;
|
||||
int fd;
|
||||
uint16 magic_number;
|
||||
TIFFRGBAImage_Extra rgba_image;
|
||||
uint32 *rast = NULL;
|
||||
uint32 width, height, num_pixels;
|
||||
char txt[1024];
|
||||
|
||||
if (im->data)
|
||||
return 0;
|
||||
|
||||
file = fopen(im->real_file, "rb");
|
||||
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
fread(&magic_number, sizeof(uint16), 1, file);
|
||||
/* Apparently rewind(f) isn't sufficient */
|
||||
fseek(file, (long)0, SEEK_SET);
|
||||
|
||||
if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
|
||||
&& (magic_number != TIFF_LITTLEENDIAN))
|
||||
{
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = fileno(file);
|
||||
fd = dup(fd);
|
||||
lseek(fd, (long)0, SEEK_SET);
|
||||
fclose(file);
|
||||
|
||||
tif = TIFFFdOpen(fd, im->real_file, "r");
|
||||
|
||||
if (!tif)
|
||||
return 0;
|
||||
|
||||
strcpy(txt, "Cannot be processed by libtiff");
|
||||
if (!TIFFRGBAImageOK(tif, txt))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
return 0;
|
||||
}
|
||||
strcpy(txt, "Cannot begin reading tiff");
|
||||
if (!TIFFRGBAImageBegin((TIFFRGBAImage *) & rgba_image, tif, 0,
|
||||
txt))
|
||||
{
|
||||
TIFFClose(tif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rgba_image.image = im;
|
||||
im->w = width = rgba_image.rgba.width;
|
||||
im->h = height = rgba_image.rgba.height;
|
||||
rgba_image.num_pixels = num_pixels = width * height;
|
||||
if (rgba_image.rgba.alpha != EXTRASAMPLE_UNSPECIFIED)
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
else
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
if (!im->format)
|
||||
im->format = strdup("tiff");
|
||||
|
||||
if ((im->loader) || (immediate_load) || (progress))
|
||||
{
|
||||
rgba_image.progress = progress;
|
||||
rgba_image.pper = rgba_image.py = 0;
|
||||
rgba_image.progress_granularity = progress_granularity;
|
||||
rast = (uint32 *) _TIFFmalloc(sizeof(uint32) * num_pixels);
|
||||
im->data = (DATA32 *) malloc(sizeof(DATA32) * num_pixels);
|
||||
|
||||
if ((!rast) || (!im->data)) /* Error checking */
|
||||
{
|
||||
fprintf(stderr, "imlib2-tiffloader: Out of memory\n");
|
||||
|
||||
if (!rast)
|
||||
_TIFFfree(rast);
|
||||
if (!im->data)
|
||||
{
|
||||
free(im->data);
|
||||
im->data = NULL;
|
||||
}
|
||||
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rgba_image.rgba.put.any == NULL)
|
||||
{
|
||||
fprintf(stderr, "imlib2-tiffloader: No put function");
|
||||
|
||||
_TIFFfree(rast);
|
||||
free(im->data);
|
||||
im->data = NULL;
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rgba_image.rgba.isContig)
|
||||
{
|
||||
rgba_image.put_contig = rgba_image.rgba.put.contig;
|
||||
rgba_image.rgba.put.contig = put_contig_and_raster;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba_image.put_separate = rgba_image.rgba.put.separate;
|
||||
rgba_image.rgba.put.separate = put_separate_and_raster;
|
||||
}
|
||||
}
|
||||
/* if (rgba_image.rgba.samplesperpixel == 8)*/
|
||||
if (rgba_image.rgba.bitspersample == 8)
|
||||
{
|
||||
if (!TIFFRGBAImageGet((TIFFRGBAImage *) & rgba_image,
|
||||
rast, width, height))
|
||||
{
|
||||
_TIFFfree(rast);
|
||||
free(im->data);
|
||||
im->data = NULL;
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("channel bits == %i\n", (int)rgba_image.rgba.samplesperpixel);
|
||||
}
|
||||
|
||||
_TIFFfree(rast);
|
||||
}
|
||||
|
||||
TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
|
||||
TIFFClose(tif);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* this seems to work, except the magic number isn't written. I'm guessing */
|
||||
/* this is a problem in libtiff */
|
||||
|
||||
char
|
||||
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
|
||||
{
|
||||
TIFF *tif = NULL;
|
||||
uint8 *buf = NULL;
|
||||
DATA32 pixel, *data = im->data;
|
||||
double alpha_factor;
|
||||
uint32 x, y;
|
||||
uint8 r, g, b, a = 0;
|
||||
int has_alpha = IMAGE_HAS_ALPHA(im);
|
||||
int i = 0, pl = 0;
|
||||
char pper = 0;
|
||||
|
||||
/* By default uses patent-free use COMPRESSION_DEFLATE,
|
||||
* another lossless compression technique */
|
||||
ImlibImageTag *tag;
|
||||
int compression_type = COMPRESSION_DEFLATE;
|
||||
|
||||
if (!im->data)
|
||||
return 0;
|
||||
|
||||
tif = TIFFOpen(im->real_file, "w");
|
||||
|
||||
if (!tif)
|
||||
return 0;
|
||||
|
||||
/* None of the TIFFSetFields are checked for errors, but since they */
|
||||
/* shouldn't fail, this shouldn't be a problem */
|
||||
|
||||
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->h);
|
||||
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->w);
|
||||
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
|
||||
|
||||
/* look for tags attached to image to get extra parameters like quality */
|
||||
/* settings etc. - this is the "api" to hint for extra information for */
|
||||
/* saver modules */
|
||||
|
||||
/* compression */
|
||||
tag = __imlib_GetTag(im, "compression_type");
|
||||
if (tag)
|
||||
{
|
||||
compression_type = tag->val;
|
||||
switch (compression_type)
|
||||
{
|
||||
case COMPRESSION_NONE:
|
||||
break;
|
||||
case COMPRESSION_CCITTRLE:
|
||||
break;
|
||||
case COMPRESSION_CCITTFAX3:
|
||||
break;
|
||||
case COMPRESSION_CCITTFAX4:
|
||||
break;
|
||||
case COMPRESSION_LZW:
|
||||
break;
|
||||
case COMPRESSION_OJPEG:
|
||||
break;
|
||||
case COMPRESSION_JPEG:
|
||||
break;
|
||||
case COMPRESSION_NEXT:
|
||||
break;
|
||||
case COMPRESSION_CCITTRLEW:
|
||||
break;
|
||||
case COMPRESSION_PACKBITS:
|
||||
break;
|
||||
case COMPRESSION_THUNDERSCAN:
|
||||
break;
|
||||
case COMPRESSION_IT8CTPAD:
|
||||
break;
|
||||
case COMPRESSION_IT8LW:
|
||||
break;
|
||||
case COMPRESSION_IT8MP:
|
||||
break;
|
||||
case COMPRESSION_IT8BL:
|
||||
break;
|
||||
case COMPRESSION_PIXARFILM:
|
||||
break;
|
||||
case COMPRESSION_PIXARLOG:
|
||||
break;
|
||||
case COMPRESSION_DEFLATE:
|
||||
break;
|
||||
case COMPRESSION_ADOBE_DEFLATE:
|
||||
break;
|
||||
case COMPRESSION_DCS:
|
||||
break;
|
||||
case COMPRESSION_JBIG:
|
||||
break;
|
||||
case COMPRESSION_SGILOG:
|
||||
break;
|
||||
case COMPRESSION_SGILOG24:
|
||||
break;
|
||||
default:
|
||||
compression_type = COMPRESSION_DEFLATE;
|
||||
}
|
||||
|
||||
}
|
||||
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression_type);
|
||||
|
||||
if (has_alpha)
|
||||
{
|
||||
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
|
||||
TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
|
||||
}
|
||||
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0));
|
||||
|
||||
buf = (uint8 *) _TIFFmalloc(TIFFScanlineSize(tif));
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
TIFFClose(tif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
i = 0;
|
||||
for (x = 0; x < im->w; x++)
|
||||
{
|
||||
pixel = data[(y * im->w) + x];
|
||||
|
||||
r = (pixel >> 16) & 0xff;
|
||||
g = (pixel >> 8) & 0xff;
|
||||
b = pixel & 0xff;
|
||||
if (has_alpha)
|
||||
{
|
||||
/* TIFF makes you pre-mutiply the rgb components by alpha */
|
||||
a = (pixel >> 24) & 0xff;
|
||||
alpha_factor = ((double)a / 255.0);
|
||||
r *= alpha_factor;
|
||||
g *= alpha_factor;
|
||||
b *= alpha_factor;
|
||||
}
|
||||
|
||||
/* This might be endian dependent */
|
||||
buf[i++] = r;
|
||||
buf[i++] = g;
|
||||
buf[i++] = b;
|
||||
if (has_alpha)
|
||||
buf[i++] = a;
|
||||
}
|
||||
|
||||
if (!TIFFWriteScanline(tif, buf, y, 0))
|
||||
{
|
||||
_TIFFfree(buf);
|
||||
TIFFClose(tif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
{
|
||||
char per;
|
||||
int l;
|
||||
|
||||
per = (char)((100 * y) / im->h);
|
||||
if ((per - pper) >= progress_granularity)
|
||||
{
|
||||
l = y - pl;
|
||||
(*progress) (im, per, 0, (y - l), im->w, l);
|
||||
pper = per;
|
||||
pl = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_TIFFfree(buf);
|
||||
TIFFClose(tif);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fills the ImlibLoader struct with a strign array of format file */
|
||||
/* extensions this loader can load. eg: */
|
||||
/* loader->formats = { "jpeg", "jpg"}; */
|
||||
/* giving permutations is a good idea. case sensitivity is irrelevant */
|
||||
/* your laoder CAN load more than one format if it likes - like: */
|
||||
/* loader->formats = { "gif", "png", "jpeg", "jpg"} */
|
||||
/* if it can load those formats. */
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] = { "tiff", "tif" };
|
||||
|
||||
/* don't bother changing any of this - it just reads this in and sets */
|
||||
/* the struct values and makes copies */
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,691 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/extensions/XShm.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
|
||||
char load(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load);
|
||||
char save(ImlibImage * im, ImlibProgressFunction progress,
|
||||
char progress_granularity);
|
||||
void formats(ImlibLoader * l);
|
||||
|
||||
static FILE *rgb_txt = NULL;
|
||||
|
||||
static void
|
||||
xpm_parse_color(char *color, int *r, int *g, int *b)
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
/* is a #ff00ff like color */
|
||||
if (color[0] == '#')
|
||||
{
|
||||
int len;
|
||||
char val[32];
|
||||
|
||||
len = strlen(color) - 1;
|
||||
if (len < 96)
|
||||
{
|
||||
int i;
|
||||
|
||||
len /= 3;
|
||||
for (i = 0; i < len; i++)
|
||||
val[i] = color[1 + i + (0 * len)];
|
||||
val[i] = 0;
|
||||
sscanf(val, "%x", r);
|
||||
for (i = 0; i < len; i++)
|
||||
val[i] = color[1 + i + (1 * len)];
|
||||
val[i] = 0;
|
||||
sscanf(val, "%x", g);
|
||||
for (i = 0; i < len; i++)
|
||||
val[i] = color[1 + i + (2 * len)];
|
||||
val[i] = 0;
|
||||
sscanf(val, "%x", b);
|
||||
if (len == 1)
|
||||
{
|
||||
*r = (*r << 4) | *r;
|
||||
*g = (*g << 4) | *g;
|
||||
*b = (*b << 4) | *b;
|
||||
}
|
||||
else if (len > 2)
|
||||
{
|
||||
*r >>= (len - 2) * 4;
|
||||
*g >>= (len - 2) * 4;
|
||||
*b >>= (len - 2) * 4;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* look in rgb txt database */
|
||||
if (!rgb_txt)
|
||||
#ifndef __EMX__
|
||||
rgb_txt = fopen("/usr/X11R6/lib/X11/rgb.txt", "r");
|
||||
#else
|
||||
rgb_txt = fopen(__XOS2RedirRoot("/XFree86/lib/X11/rgb.txt"), "rt");
|
||||
#endif
|
||||
if (!rgb_txt)
|
||||
return;
|
||||
fseek(rgb_txt, 0, SEEK_SET);
|
||||
while (fgets(buf, 4000, rgb_txt))
|
||||
{
|
||||
if (buf[0] != '!')
|
||||
{
|
||||
int rr, gg, bb;
|
||||
char name[4096];
|
||||
|
||||
sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name);
|
||||
if (!strcasecmp(name, color))
|
||||
{
|
||||
*r = rr;
|
||||
*g = gg;
|
||||
*b = bb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xpm_parse_done(void)
|
||||
{
|
||||
if (rgb_txt)
|
||||
fclose(rgb_txt);
|
||||
rgb_txt = NULL;
|
||||
}
|
||||
|
||||
char
|
||||
load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
|
||||
char immediate_load)
|
||||
{
|
||||
DATA32 *ptr, *end;
|
||||
FILE *f;
|
||||
|
||||
int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
|
||||
quote, context, len, done, r, g, b;
|
||||
char *line, s[256], tok[128], col[256];
|
||||
int lsz = 256;
|
||||
struct _cmap {
|
||||
unsigned char str[6];
|
||||
unsigned char transp;
|
||||
short r, g, b;
|
||||
} *cmap;
|
||||
|
||||
short lookup[128 - 32][128 - 32];
|
||||
float per = 0.0, per_inc = 0.0;
|
||||
int last_per = 0, last_y = 0;
|
||||
int count, pixels;
|
||||
|
||||
done = 0;
|
||||
transp = -1;
|
||||
|
||||
/* if immediate_load is 1, then dont delay image laoding as below, or */
|
||||
/* already data in this image - dont load it again */
|
||||
|
||||
if (im->data)
|
||||
{
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
f = fopen(im->real_file, "rb");
|
||||
if (!f)
|
||||
{
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
fread(s, 1, 9, f);
|
||||
rewind(f);
|
||||
s[9] = 0;
|
||||
if (strcmp("/* XPM */", s))
|
||||
{
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
cmap = NULL;
|
||||
w = 10;
|
||||
h = 10;
|
||||
ptr = NULL;
|
||||
end = NULL;
|
||||
c = ' ';
|
||||
comment = 0;
|
||||
quote = 0;
|
||||
context = 0;
|
||||
pixels = 0;
|
||||
count = 0;
|
||||
line = malloc(lsz);
|
||||
memset(lookup, 0, sizeof(lookup));
|
||||
while (!done)
|
||||
{
|
||||
pc = c;
|
||||
c = fgetc(f);
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (!quote)
|
||||
{
|
||||
if ((pc == '/') && (c == '*'))
|
||||
comment = 1;
|
||||
else if ((pc == '*') && (c == '/') && (comment))
|
||||
comment = 0;
|
||||
}
|
||||
if (!comment)
|
||||
{
|
||||
if ((!quote) && (c == '"'))
|
||||
{
|
||||
quote = 1;
|
||||
i = 0;
|
||||
}
|
||||
else if ((quote) && (c == '"'))
|
||||
{
|
||||
line[i] = 0;
|
||||
quote = 0;
|
||||
if (context == 0)
|
||||
{
|
||||
/* Header */
|
||||
sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp);
|
||||
if (ncolors > 32766)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"IMLIB ERROR: XPM files with colors > 32766 not supported\n");
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
if (cpp > 5)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"IMLIB ERROR: XPM files with characters per pixel > 5 not supported\n");
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
if (w > 32767)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"IMLIB ERROR: Image width > 32767 pixels for file\n");
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
if (h > 32767)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"IMLIB ERROR: Image height > 32767 pixels for file\n");
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
if (!im->format)
|
||||
im->format = strdup("xpm");
|
||||
|
||||
cmap = malloc(sizeof(struct _cmap) * ncolors);
|
||||
|
||||
if (!cmap)
|
||||
{
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
|
||||
per_inc = 100.0 / (((float)w) * h);
|
||||
|
||||
j = 0;
|
||||
context++;
|
||||
}
|
||||
else if (context == 1)
|
||||
{
|
||||
/* Color Table */
|
||||
if (j < ncolors)
|
||||
{
|
||||
int slen;
|
||||
int hascolor, iscolor;
|
||||
|
||||
iscolor = 0;
|
||||
hascolor = 0;
|
||||
tok[0] = 0;
|
||||
col[0] = 0;
|
||||
s[0] = 0;
|
||||
len = strlen(line);
|
||||
strncpy(cmap[j].str, line, cpp);
|
||||
cmap[j].str[cpp] = 0;
|
||||
cmap[j].r = -1;
|
||||
cmap[j].transp = 0;
|
||||
for (k = cpp; k < len; k++)
|
||||
{
|
||||
if (line[k] != ' ')
|
||||
{
|
||||
s[0] = 0;
|
||||
sscanf(&line[k], "%65535s", s);
|
||||
slen = strlen(s);
|
||||
k += slen;
|
||||
if (!strcmp(s, "c"))
|
||||
iscolor = 1;
|
||||
if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
|
||||
|| (!strcmp(s, "g4"))
|
||||
|| (!strcmp(s, "g"))
|
||||
|| (!strcmp(s, "c")) || (k >= len))
|
||||
{
|
||||
if (k >= len)
|
||||
{
|
||||
if (col[0])
|
||||
strcat(col, " ");
|
||||
if (strlen(col) + strlen(s) <
|
||||
sizeof(col))
|
||||
strcat(col, s);
|
||||
}
|
||||
if (col[0])
|
||||
{
|
||||
if (!strcasecmp(col, "none"))
|
||||
{
|
||||
transp = 1;
|
||||
cmap[j].transp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((((cmap[j].r < 0) ||
|
||||
(!strcmp(tok, "c")))
|
||||
&& (!hascolor)))
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
xpm_parse_color(col,
|
||||
&r,
|
||||
&g,
|
||||
&b);
|
||||
cmap[j].r = r;
|
||||
cmap[j].g = g;
|
||||
cmap[j].b = b;
|
||||
if (iscolor)
|
||||
hascolor = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
strcpy(tok, s);
|
||||
col[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col[0])
|
||||
strcat(col, " ");
|
||||
strcat(col, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j++;
|
||||
if (j >= ncolors)
|
||||
{
|
||||
if (cpp == 1)
|
||||
for (i = 0; i < ncolors; i++)
|
||||
lookup[(int)cmap[i].str[0] - 32][0] = i;
|
||||
if (cpp == 2)
|
||||
for (i = 0; i < ncolors; i++)
|
||||
lookup[(int)cmap[i].str[0] -
|
||||
32][(int)cmap[i].str[1] - 32] = i;
|
||||
context++;
|
||||
}
|
||||
|
||||
if (transp >= 0)
|
||||
{
|
||||
SET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNSET_FLAG(im->flags, F_HAS_ALPHA);
|
||||
}
|
||||
|
||||
if (im->loader || immediate_load || progress)
|
||||
{
|
||||
im->data =
|
||||
(DATA32 *) malloc(sizeof(DATA32) * im->w *
|
||||
im->h);
|
||||
if (!im->data)
|
||||
{
|
||||
free(cmap);
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 0;
|
||||
}
|
||||
ptr = im->data;
|
||||
end = ptr + (sizeof(DATA32) * w * h);
|
||||
pixels = w * h;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(cmap);
|
||||
free(line);
|
||||
fclose(f);
|
||||
xpm_parse_done();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Image Data */
|
||||
i = 0;
|
||||
if (cpp == 0)
|
||||
{
|
||||
/* Chars per pixel = 0? well u never know */
|
||||
}
|
||||
if (cpp == 1)
|
||||
{
|
||||
if (transp)
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
col[0] = line[i];
|
||||
if (cmap[lookup[(int)col[0] - 32][0]].
|
||||
transp)
|
||||
{
|
||||
r = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[0]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[0]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[0]].b;
|
||||
*ptr++ =
|
||||
0x00ffffff & ((r << 16) |
|
||||
(g << 8) | b);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[0]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[0]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[0]].b;
|
||||
*ptr++ =
|
||||
(0xff << 24) | (r << 16) | (g <<
|
||||
8) |
|
||||
b;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
col[0] = line[i];
|
||||
r = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32][0]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32][0]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32][0]].b;
|
||||
*ptr++ =
|
||||
(0xff << 24) | (r << 16) | (g << 8) |
|
||||
b;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cpp == 2)
|
||||
{
|
||||
if (transp)
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
col[0] = line[i++];
|
||||
col[1] = line[i];
|
||||
if (cmap
|
||||
[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].transp)
|
||||
{
|
||||
r = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].b;
|
||||
*ptr++ =
|
||||
0x00ffffff & ((r << 16) |
|
||||
(g << 8) | b);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].b;
|
||||
*ptr++ =
|
||||
(0xff << 24) | (r << 16) | (g <<
|
||||
8) |
|
||||
b;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
col[0] = line[i++];
|
||||
col[1] = line[i];
|
||||
r = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup[(int)col[0] - 32]
|
||||
[(int)col[1] - 32]].b;
|
||||
*ptr++ =
|
||||
(0xff << 24) | (r << 16) | (g << 8) |
|
||||
b;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transp)
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
for (j = 0; j < cpp; j++, i++)
|
||||
{
|
||||
col[j] = line[i];
|
||||
}
|
||||
col[j] = 0;
|
||||
i--;
|
||||
for (j = 0; j < ncolors; j++)
|
||||
{
|
||||
if (!strcmp(col, cmap[j].str))
|
||||
{
|
||||
if (cmap[j].transp)
|
||||
{
|
||||
r = (unsigned char)
|
||||
cmap[lookup
|
||||
[(int)col[0] -
|
||||
32][0]].r;
|
||||
g = (unsigned char)
|
||||
cmap[lookup
|
||||
[(int)col[0] -
|
||||
32][0]].g;
|
||||
b = (unsigned char)
|
||||
cmap[lookup
|
||||
[(int)col[0] -
|
||||
32][0]].b;
|
||||
*ptr++ =
|
||||
0x00ffffff & ((r << 16)
|
||||
| (g <<
|
||||
8) |
|
||||
b);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (unsigned char)cmap[j].
|
||||
r;
|
||||
g = (unsigned char)cmap[j].
|
||||
g;
|
||||
b = (unsigned char)cmap[j].
|
||||
b;
|
||||
*ptr++ =
|
||||
(0xff << 24) | (r <<
|
||||
16) |
|
||||
(g << 8) | b;
|
||||
count++;
|
||||
}
|
||||
j = ncolors;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0;
|
||||
((i < 65536) && (ptr < end) && (line[i]));
|
||||
i++)
|
||||
{
|
||||
for (j = 0; j < cpp; j++, i++)
|
||||
{
|
||||
col[j] = line[i];
|
||||
}
|
||||
col[j] = 0;
|
||||
i--;
|
||||
for (j = 0; j < ncolors; j++)
|
||||
{
|
||||
if (!strcmp(col, cmap[j].str))
|
||||
{
|
||||
r = (unsigned char)cmap[j].r;
|
||||
g = (unsigned char)cmap[j].g;
|
||||
b = (unsigned char)cmap[j].b;
|
||||
*ptr++ =
|
||||
(0xff << 24) | (r << 16) |
|
||||
(g << 8) | b;
|
||||
count++;
|
||||
j = ncolors;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
per += per_inc;
|
||||
if (progress && (((int)per) != last_per)
|
||||
&& (((int)per) % progress_granularity == 0))
|
||||
{
|
||||
last_per = (int)per;
|
||||
if (!(progress(im, (int)per, 0, last_y, w, i)))
|
||||
{
|
||||
fclose(f);
|
||||
free(cmap);
|
||||
free(line);
|
||||
xpm_parse_done();
|
||||
return 2;
|
||||
}
|
||||
last_y = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Scan in line from XPM file */
|
||||
if ((!comment) && (quote) && (c != '"'))
|
||||
{
|
||||
if (c < 32)
|
||||
c = 32;
|
||||
else if (c > 127)
|
||||
c = 127;
|
||||
line[i++] = c;
|
||||
}
|
||||
if (i >= lsz)
|
||||
{
|
||||
lsz += 256;
|
||||
line = realloc(line, lsz);
|
||||
}
|
||||
if (((ptr) && ((ptr - im->data) >= (w * h * sizeof(DATA32)))) ||
|
||||
((context > 1) && (count >= pixels)))
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
{
|
||||
progress(im, 100, 0, last_y, w, h);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(cmap);
|
||||
free(line);
|
||||
|
||||
xpm_parse_done();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fills the ImlibLoader struct with a strign array of format file */
|
||||
/* extensions this loader can load. eg: */
|
||||
/* loader->formats = { "jpeg", "jpg"}; */
|
||||
/* giving permutations is a good idea. case sensitivity is irrelevant */
|
||||
/* your laoder CAN load more than one format if it likes - like: */
|
||||
/* loader->formats = { "gif", "png", "jpeg", "jpg"} */
|
||||
/* if it can load those formats. */
|
||||
void
|
||||
formats(ImlibLoader * l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] = { "xpm" };
|
||||
|
||||
/* don't bother changing any of this - it just reads this in and sets */
|
||||
/* the struct values and makes copies */
|
||||
{
|
||||
int i;
|
||||
|
||||
l->num_formats = (sizeof(list_formats) / sizeof(char *));
|
||||
l->formats = malloc(sizeof(char *) * l->num_formats);
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup(list_formats[i]);
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "image.h"
|
||||
|
||||
#define OUTBUF_SIZE 16484
|
||||
#define INBUF_SIZE 1024
|
||||
|
||||
static int handle_buffer (DATA8 *src, unsigned long src_len,
|
||||
DATA8 **dest, unsigned long *dest_len)
|
||||
{
|
||||
static DATA8 outbuf[OUTBUF_SIZE];
|
||||
uLongf outbuf_len = OUTBUF_SIZE;
|
||||
int res;
|
||||
|
||||
assert (src);
|
||||
assert (src_len);
|
||||
assert (dest);
|
||||
assert (dest_len);
|
||||
|
||||
res = uncompress (outbuf, &outbuf_len, src, src_len);
|
||||
|
||||
switch (res) {
|
||||
case Z_OK:
|
||||
*dest = outbuf;
|
||||
*dest_len = (unsigned long) outbuf_len;
|
||||
return 1;
|
||||
case Z_BUF_ERROR:
|
||||
return 0;
|
||||
default:
|
||||
*dest = NULL;
|
||||
*dest_len = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void uncompress_file (int src, int dest, off_t size)
|
||||
{
|
||||
DATA8 inbuf[INBUF_SIZE], *outbuf;
|
||||
off_t left;
|
||||
ssize_t inlen;
|
||||
unsigned long outlen = 0;
|
||||
|
||||
for (left = size; left; left -= inlen) {
|
||||
inlen = read (src, inbuf, MIN (left, INBUF_SIZE));
|
||||
|
||||
if (inlen <= 0)
|
||||
break;
|
||||
|
||||
if (handle_buffer (inbuf, inlen, &outbuf, &outlen))
|
||||
write (dest, outbuf, outlen);
|
||||
}
|
||||
}
|
||||
|
||||
char load (ImlibImage *im, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
{
|
||||
ImlibLoader *loader;
|
||||
int src, dest;
|
||||
char *file, tmp[] = "/tmp/imlib2_loader_zlib-XXXXXX";
|
||||
struct stat st;
|
||||
|
||||
assert (im);
|
||||
|
||||
/* we'll need a copy of it later */
|
||||
file = im->real_file;
|
||||
|
||||
if (stat (im->real_file, &st) < 0)
|
||||
return 0;
|
||||
|
||||
if ((dest = mkstemp (tmp)) < 0)
|
||||
return 0;
|
||||
|
||||
if ((src = open (im->real_file, O_RDONLY)) < 0) {
|
||||
unlink (tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uncompress_file (src, dest, st.st_size);
|
||||
|
||||
close (src);
|
||||
close (dest);
|
||||
|
||||
if (!(loader = __imlib_FindBestLoaderForFile (tmp, 0))) {
|
||||
unlink (tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free (im->real_file);
|
||||
im->real_file = strdup (tmp);
|
||||
loader->load (im, progress, progress_granularity, immediate_load);
|
||||
|
||||
free (im->real_file);
|
||||
im->real_file = strdup (file);
|
||||
unlink (tmp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void formats (ImlibLoader *l)
|
||||
{
|
||||
/* this is the only bit you have to change... */
|
||||
char *list_formats[] = {"gz"};
|
||||
int i;
|
||||
|
||||
/* don't bother changing any of this - it just reads this in
|
||||
* and sets the struct values and makes copies
|
||||
*/
|
||||
l->num_formats = sizeof (list_formats) / sizeof (char *);
|
||||
l->formats = malloc (sizeof (char *) * l->num_formats);
|
||||
|
||||
for (i = 0; i < l->num_formats; i++)
|
||||
l->formats[i] = strdup (list_formats[i]);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
dnl AC_EXPAND_DIR(VARNAME, DIR)
|
||||
dnl expands occurrences of ${prefix} and ${exec_prefix} in the given DIR,
|
||||
dnl and assigns the resulting string to VARNAME
|
||||
dnl example: AC_DEFINE_DIR(DATADIR, "$datadir")
|
||||
dnl by Alexandre Oliva <oliva@dcc.unicamp.br>
|
||||
AC_DEFUN([AC_EXPAND_DIR], [
|
||||
$1=$2
|
||||
$1=`(
|
||||
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
|
||||
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
|
||||
eval echo \""[$]$1"\"
|
||||
)`
|
||||
])
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
dnl @synopsis AC_PATH_GENERIC(LIBRARY [, MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||
dnl
|
||||
dnl Runs a LIBRARY-config script and defines LIBRARY_CFLAGS and LIBRARY_LIBS
|
||||
dnl
|
||||
dnl The script must support `--cflags' and `--libs' args.
|
||||
dnl If MINIMUM-VERSION is specified, the script must also support the
|
||||
dnl `--version' arg.
|
||||
dnl If the `--with-library-[exec-]prefix' arguments to ./configure are given,
|
||||
dnl it must also support `--prefix' and `--exec-prefix'.
|
||||
dnl (In other words, it must be like gtk-config.)
|
||||
dnl
|
||||
dnl For example:
|
||||
dnl
|
||||
dnl AC_PATH_GENERIC(Foo, 1.0.0)
|
||||
dnl
|
||||
dnl would run `foo-config --version' and check that it is at least 1.0.0
|
||||
dnl
|
||||
dnl If so, the following would then be defined:
|
||||
dnl
|
||||
dnl FOO_CFLAGS to `foo-config --cflags`
|
||||
dnl FOO_LIBS to `foo-config --libs`
|
||||
dnl
|
||||
dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK)
|
||||
dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount)
|
||||
dnl
|
||||
dnl @author Angus Lees <gusl@cse.unsw.edu.au>
|
||||
|
||||
AC_DEFUN([AC_PATH_GENERIC],
|
||||
[dnl
|
||||
dnl we're going to need uppercase, lowercase and user-friendly versions of the
|
||||
dnl string `LIBRARY'
|
||||
pushdef([UP], translit([$1], [a-z], [A-Z]))dnl
|
||||
pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
|
||||
|
||||
dnl
|
||||
dnl Get the cflags and libraries from the LIBRARY-config script
|
||||
dnl
|
||||
AC_ARG_WITH(DOWN-prefix,[ --with-]DOWN[-prefix=PFX Prefix where $1 is installed (optional)],
|
||||
DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="")
|
||||
AC_ARG_WITH(DOWN-exec-prefix,[ --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)],
|
||||
DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="")
|
||||
|
||||
if test x$DOWN[]_config_exec_prefix != x ; then
|
||||
DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix"
|
||||
if test x${UP[]_CONFIG+set} != xset ; then
|
||||
UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config
|
||||
fi
|
||||
fi
|
||||
if test x$DOWN[]_config_prefix != x ; then
|
||||
DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix"
|
||||
if test x${UP[]_CONFIG+set} != xset ; then
|
||||
UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no)
|
||||
ifelse([$2], ,
|
||||
AC_MSG_CHECKING(for $1),
|
||||
AC_MSG_CHECKING(for $1 - version >= $2)
|
||||
)
|
||||
no_[]DOWN=""
|
||||
if test "$UP[]_CONFIG" = "no" ; then
|
||||
no_[]DOWN=yes
|
||||
else
|
||||
UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`"
|
||||
UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`"
|
||||
ifelse([$2], , ,[
|
||||
DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \
|
||||
--version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \
|
||||
--version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \
|
||||
--version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])"
|
||||
DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])"
|
||||
DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])"
|
||||
|
||||
# Compare wanted version to what config script returned.
|
||||
# If I knew what library was being run, i'd probably also compile
|
||||
# a test program at this point (which also extracted and tested
|
||||
# the version in some library-specific way)
|
||||
if test "$DOWN[]_config_major_version" -lt \
|
||||
"$DOWN[]_wanted_major_version" \
|
||||
-o \( "$DOWN[]_config_major_version" -eq \
|
||||
"$DOWN[]_wanted_major_version" \
|
||||
-a "$DOWN[]_config_minor_version" -lt \
|
||||
"$DOWN[]_wanted_minor_version" \) \
|
||||
-o \( "$DOWN[]_config_major_version" -eq \
|
||||
"$DOWN[]_wanted_major_version" \
|
||||
-a "$DOWN[]_config_minor_version" -eq \
|
||||
"$DOWN[]_wanted_minor_version" \
|
||||
-a "$DOWN[]_config_micro_version" -lt \
|
||||
"$DOWN[]_wanted_micro_version" \) ; then
|
||||
# older version found
|
||||
no_[]DOWN=yes
|
||||
echo -n "*** An old version of $1 "
|
||||
echo -n "($DOWN[]_config_major_version"
|
||||
echo -n ".$DOWN[]_config_minor_version"
|
||||
echo ".$DOWN[]_config_micro_version) was found."
|
||||
echo -n "*** You need a version of $1 newer than "
|
||||
echo -n "$DOWN[]_wanted_major_version"
|
||||
echo -n ".$DOWN[]_wanted_minor_version"
|
||||
echo ".$DOWN[]_wanted_micro_version."
|
||||
echo "***"
|
||||
echo "*** If you have already installed a sufficiently new version, this error"
|
||||
echo "*** probably means that the wrong copy of the DOWN-config shell script is"
|
||||
echo "*** being found. The easiest way to fix this is to remove the old version"
|
||||
echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the"
|
||||
echo "*** correct copy of DOWN-config. (In this case, you will have to"
|
||||
echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf"
|
||||
echo "*** so that the correct libraries are found at run-time)"
|
||||
fi
|
||||
])
|
||||
fi
|
||||
if test "x$no_[]DOWN" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$3], , :, [$3])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$UP[]_CONFIG" = "no" ; then
|
||||
echo "*** The DOWN-config script installed by $1 could not be found"
|
||||
echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the UP[]_CONFIG environment variable to the"
|
||||
echo "*** full path to DOWN-config."
|
||||
fi
|
||||
UP[]_CFLAGS=""
|
||||
UP[]_LIBS=""
|
||||
ifelse([$4], , :, [$4])
|
||||
fi
|
||||
AC_SUBST(UP[]_CFLAGS)
|
||||
AC_SUBST(UP[]_LIBS)
|
||||
|
||||
popdef([UP])
|
||||
popdef([DOWN])
|
||||
])
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
config.guess
|
||||
config.h.in
|
||||
config.sub
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
aclocal.m4
|
||||
stamp-h.in
|
||||
Makefile.in
|
||||
configure
|
||||
config.log
|
||||
config.h
|
||||
config.cache
|
||||
libtool
|
||||
config.status
|
||||
stamp-h
|
||||
Makefile
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
imlib2
|
||||
loaderpath.h
|
||||
.icons
|
481
src/Imlib2.h
481
src/Imlib2.h
|
@ -1,481 +0,0 @@
|
|||
#ifndef __IMLIB_API_H
|
||||
# define __IMLIB_API_H 1
|
||||
|
||||
/* Data types to use */
|
||||
# ifndef DATA64
|
||||
# define DATA64 unsigned long long
|
||||
# define DATA32 unsigned int
|
||||
# define DATA16 unsigned short
|
||||
# define DATA8 unsigned char
|
||||
# endif
|
||||
|
||||
/* opaque data types */
|
||||
typedef void *Imlib_Context;
|
||||
typedef void *Imlib_Image;
|
||||
typedef void *Imlib_Color_Modifier;
|
||||
typedef void *Imlib_Updates;
|
||||
typedef void *Imlib_Font;
|
||||
typedef void *Imlib_Color_Range;
|
||||
typedef void *Imlib_Filter;
|
||||
typedef struct _imlib_border Imlib_Border;
|
||||
typedef struct _imlib_color Imlib_Color;
|
||||
typedef void *ImlibPolygon;
|
||||
|
||||
/* blending operations */
|
||||
enum _imlib_operation
|
||||
{
|
||||
IMLIB_OP_COPY,
|
||||
IMLIB_OP_ADD,
|
||||
IMLIB_OP_SUBTRACT,
|
||||
IMLIB_OP_RESHADE
|
||||
};
|
||||
|
||||
enum _imlib_text_direction
|
||||
{
|
||||
IMLIB_TEXT_TO_RIGHT = 0,
|
||||
IMLIB_TEXT_TO_LEFT = 1,
|
||||
IMLIB_TEXT_TO_DOWN = 2,
|
||||
IMLIB_TEXT_TO_UP = 3,
|
||||
IMLIB_TEXT_TO_ANGLE = 4
|
||||
};
|
||||
|
||||
enum _imlib_load_error
|
||||
{
|
||||
IMLIB_LOAD_ERROR_NONE,
|
||||
IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST,
|
||||
IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY,
|
||||
IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ,
|
||||
IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT,
|
||||
IMLIB_LOAD_ERROR_PATH_TOO_LONG,
|
||||
IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT,
|
||||
IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY,
|
||||
IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE,
|
||||
IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS,
|
||||
IMLIB_LOAD_ERROR_OUT_OF_MEMORY,
|
||||
IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS,
|
||||
IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE,
|
||||
IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE,
|
||||
IMLIB_LOAD_ERROR_UNKNOWN
|
||||
};
|
||||
|
||||
/* Encodings known to Imlib2 (so far) */
|
||||
enum _imlib_TTF_encoding
|
||||
{
|
||||
IMLIB_TTF_ENCODING_ISO_8859_1,
|
||||
IMLIB_TTF_ENCODING_ISO_8859_2,
|
||||
IMLIB_TTF_ENCODING_ISO_8859_3,
|
||||
IMLIB_TTF_ENCODING_ISO_8859_4,
|
||||
IMLIB_TTF_ENCODING_ISO_8859_5
|
||||
};
|
||||
|
||||
typedef enum _imlib_operation Imlib_Operation;
|
||||
typedef enum _imlib_load_error Imlib_Load_Error;
|
||||
typedef enum _imlib_text_direction Imlib_Text_Direction;
|
||||
typedef enum _imlib_TTF_encoding Imlib_TTF_Encoding;
|
||||
|
||||
struct _imlib_border
|
||||
{
|
||||
int left, right, top, bottom;
|
||||
};
|
||||
|
||||
struct _imlib_color
|
||||
{
|
||||
int alpha, red, green, blue;
|
||||
};
|
||||
|
||||
/* Progressive loading callbacks */
|
||||
typedef int (*Imlib_Progress_Function) (Imlib_Image im, char percent,
|
||||
int update_x, int update_y,
|
||||
int update_w, int update_h);
|
||||
typedef void (*Imlib_Data_Destructor_Function) (Imlib_Image im, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* context handling */
|
||||
Imlib_Context imlib_context_new(void);
|
||||
void imlib_context_free(Imlib_Context context);
|
||||
|
||||
void imlib_context_push(Imlib_Context context);
|
||||
void imlib_context_pop(void);
|
||||
Imlib_Context imlib_context_get(void);
|
||||
|
||||
/* context setting */
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
void imlib_context_set_display(Display * display);
|
||||
void imlib_context_set_visual(Visual * visual);
|
||||
void imlib_context_set_colormap(Colormap colormap);
|
||||
void imlib_context_set_drawable(Drawable drawable);
|
||||
void imlib_context_set_mask(Pixmap mask);
|
||||
#endif
|
||||
void imlib_context_set_dither_mask(char dither_mask);
|
||||
void imlib_context_set_anti_alias(char anti_alias);
|
||||
void imlib_context_set_dither(char dither);
|
||||
void imlib_context_set_blend(char blend);
|
||||
void imlib_context_set_color_modifier(Imlib_Color_Modifier color_modifier);
|
||||
void imlib_context_set_operation(Imlib_Operation operation);
|
||||
void imlib_context_set_font(Imlib_Font font);
|
||||
void imlib_context_set_direction(Imlib_Text_Direction direction);
|
||||
void imlib_context_set_angle(double angle);
|
||||
void imlib_context_set_color(int red, int green, int blue, int alpha);
|
||||
void imlib_context_set_color_hsva(float hue, float saturation, float value, int alpha);
|
||||
void imlib_context_set_color_hlsa(float hue, float lightness, float saturation, int alpha);
|
||||
void imlib_context_set_color_cmya(int cyan, int magenta, int yellow, int alpha);
|
||||
void imlib_context_set_color_range(Imlib_Color_Range color_range);
|
||||
void imlib_context_set_progress_function(Imlib_Progress_Function
|
||||
progress_function);
|
||||
void imlib_context_set_progress_granularity(char progress_granularity);
|
||||
void imlib_context_set_image(Imlib_Image image);
|
||||
void imlib_context_set_cliprect(int x, int y, int w, int h);
|
||||
void imlib_context_set_TTF_encoding(Imlib_TTF_Encoding encoding);
|
||||
|
||||
/* context getting */
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
Display *imlib_context_get_display(void);
|
||||
Visual *imlib_context_get_visual(void);
|
||||
Colormap imlib_context_get_colormap(void);
|
||||
Drawable imlib_context_get_drawable(void);
|
||||
Pixmap imlib_context_get_mask(void);
|
||||
#endif
|
||||
char imlib_context_get_dither_mask(void);
|
||||
char imlib_context_get_anti_alias(void);
|
||||
char imlib_context_get_dither(void);
|
||||
char imlib_context_get_blend(void);
|
||||
Imlib_Color_Modifier imlib_context_get_color_modifier(void);
|
||||
Imlib_Operation imlib_context_get_operation(void);
|
||||
Imlib_Font imlib_context_get_font(void);
|
||||
double imlib_context_get_angle(void);
|
||||
Imlib_Text_Direction imlib_context_get_direction(void);
|
||||
void imlib_context_get_color(int *red, int *green, int *blue, int *alpha);
|
||||
void imlib_context_get_color_hsva(float *hue, float *saturation, float *value, int *alpha);
|
||||
void imlib_context_get_color_hlsa(float *hue, float *lightness, float *saturation, int *alpha);
|
||||
void imlib_context_get_color_cmya(int *cyan, int *magenta, int *yellow, int *alpha);
|
||||
Imlib_Color *imlib_context_get_imlib_color(void);
|
||||
Imlib_Color_Range imlib_context_get_color_range(void);
|
||||
Imlib_Progress_Function imlib_context_get_progress_function(void);
|
||||
char imlib_context_get_progress_granularity(void);
|
||||
Imlib_Image imlib_context_get_image(void);
|
||||
void imlib_context_get_cliprect(int *x, int *y, int *w, int *h);
|
||||
Imlib_TTF_Encoding imlib_context_get_TTF_encoding(void);
|
||||
|
||||
int imlib_get_cache_size(void);
|
||||
void imlib_set_cache_size(int bytes);
|
||||
int imlib_get_color_usage(void);
|
||||
void imlib_set_color_usage(int max);
|
||||
void imlib_flush_loaders(void);
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
int imlib_get_visual_depth(Display * display, Visual * visual);
|
||||
Visual *imlib_get_best_visual(Display * display, int screen,
|
||||
int *depth_return);
|
||||
#endif
|
||||
|
||||
Imlib_Image imlib_load_image(const char *file);
|
||||
Imlib_Image imlib_load_image_immediately(const char *file);
|
||||
Imlib_Image imlib_load_image_without_cache(const char *file);
|
||||
Imlib_Image imlib_load_image_immediately_without_cache(const char *file);
|
||||
Imlib_Image imlib_load_image_with_error_return(const char *file,
|
||||
Imlib_Load_Error *
|
||||
error_return);
|
||||
void imlib_free_image(void);
|
||||
void imlib_free_image_and_decache(void);
|
||||
|
||||
/* query/modify image parameters */
|
||||
int imlib_image_get_width(void);
|
||||
int imlib_image_get_height(void);
|
||||
const char *imlib_image_get_filename(void);
|
||||
DATA32 *imlib_image_get_data(void);
|
||||
DATA32 *imlib_image_get_data_for_reading_only(void);
|
||||
void imlib_image_put_back_data(DATA32 * data);
|
||||
char imlib_image_has_alpha(void);
|
||||
void imlib_image_set_changes_on_disk(void);
|
||||
void imlib_image_get_border(Imlib_Border * border);
|
||||
void imlib_image_set_border(Imlib_Border * border);
|
||||
void imlib_image_set_format(const char *format);
|
||||
void imlib_image_set_irrelevant_format(char irrelevant);
|
||||
void imlib_image_set_irrelevant_border(char irrelevant);
|
||||
void imlib_image_set_irrelevant_alpha(char irrelevant);
|
||||
char *imlib_image_format(void);
|
||||
void imlib_image_set_has_alpha(char has_alpha);
|
||||
void imlib_image_query_pixel(int x, int y, Imlib_Color * color_return);
|
||||
void imlib_image_query_pixel_hsva(int x, int y, float *hue, float *saturation, float *value, int *alpha);
|
||||
void imlib_image_query_pixel_hlsa(int x, int y, float *hue, float *lightness, float *saturation, int *alpha);
|
||||
void imlib_image_query_pixel_cmya(int x, int y, int *cyan, int *magenta, int *yellow, int *alpha);
|
||||
|
||||
/* rendering functions */
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
void imlib_render_pixmaps_for_whole_image(Pixmap * pixmap_return,
|
||||
Pixmap * mask_return);
|
||||
void imlib_render_pixmaps_for_whole_image_at_size(Pixmap * pixmap_return,
|
||||
Pixmap * mask_return,
|
||||
int width, int height);
|
||||
void imlib_free_pixmap_and_mask(Pixmap pixmap);
|
||||
void imlib_render_image_on_drawable(int x, int y);
|
||||
void imlib_render_image_on_drawable_at_size(int x, int y, int width,
|
||||
int height);
|
||||
void imlib_render_image_part_on_drawable_at_size(int source_x,
|
||||
int source_y,
|
||||
int source_width,
|
||||
int source_height, int x,
|
||||
int y, int width,
|
||||
int height);
|
||||
DATA32 imlib_render_get_pixel_color(void);
|
||||
#endif
|
||||
void imlib_blend_image_onto_image(Imlib_Image source_image,
|
||||
char merge_alpha, int source_x,
|
||||
int source_y, int source_width,
|
||||
int source_height, int destination_x,
|
||||
int destination_y, int destination_width,
|
||||
int destination_height);
|
||||
|
||||
/* creation functions */
|
||||
Imlib_Image imlib_create_image(int width, int height);
|
||||
Imlib_Image imlib_create_image_using_data(int width, int height,
|
||||
DATA32 * data);
|
||||
Imlib_Image imlib_create_image_using_copied_data(int width, int height,
|
||||
DATA32 * data);
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
Imlib_Image imlib_create_image_from_drawable(Pixmap mask, int x, int y,
|
||||
int width, int height,
|
||||
char need_to_grab_x);
|
||||
Imlib_Image imlib_create_image_from_ximage(XImage *image, XImage *mask, int x, int y,
|
||||
int width, int height,
|
||||
char need_to_grab_x);
|
||||
Imlib_Image imlib_create_scaled_image_from_drawable(Pixmap mask,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int destination_width,
|
||||
int destination_height,
|
||||
char need_to_grab_x,
|
||||
char
|
||||
get_mask_from_shape);
|
||||
char imlib_copy_drawable_to_image(Pixmap mask, int x, int y, int width,
|
||||
int height, int destination_x,
|
||||
int destination_y, char need_to_grab_x);
|
||||
#endif
|
||||
Imlib_Image imlib_clone_image(void);
|
||||
Imlib_Image imlib_create_cropped_image(int x, int y, int width,
|
||||
int height);
|
||||
Imlib_Image imlib_create_cropped_scaled_image(int source_x, int source_y,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int destination_width,
|
||||
int destination_height);
|
||||
|
||||
/* imlib updates. lists of rectangles for storing required update draws */
|
||||
Imlib_Updates imlib_updates_clone(Imlib_Updates updates);
|
||||
Imlib_Updates imlib_update_append_rect(Imlib_Updates updates, int x, int y,
|
||||
int w, int h);
|
||||
Imlib_Updates imlib_updates_merge(Imlib_Updates updates, int w, int h);
|
||||
Imlib_Updates imlib_updates_merge_for_rendering(Imlib_Updates updates,
|
||||
int w, int h);
|
||||
void imlib_updates_free(Imlib_Updates updates);
|
||||
Imlib_Updates imlib_updates_get_next(Imlib_Updates updates);
|
||||
void imlib_updates_get_coordinates(Imlib_Updates updates, int *x_return,
|
||||
int *y_return, int *width_return,
|
||||
int *height_return);
|
||||
void imlib_updates_set_coordinates(Imlib_Updates updates, int x, int y,
|
||||
int width, int height);
|
||||
void imlib_render_image_updates_on_drawable(Imlib_Updates updates, int x,
|
||||
int y);
|
||||
Imlib_Updates imlib_updates_init(void);
|
||||
Imlib_Updates imlib_updates_append_updates(Imlib_Updates updates,
|
||||
Imlib_Updates appended_updates);
|
||||
|
||||
/* image modification */
|
||||
void imlib_image_flip_horizontal(void);
|
||||
void imlib_image_flip_vertical(void);
|
||||
void imlib_image_flip_diagonal(void);
|
||||
void imlib_image_orientate(int orientation);
|
||||
void imlib_image_blur(int radius);
|
||||
void imlib_image_sharpen(int radius);
|
||||
void imlib_image_tile_horizontal(void);
|
||||
void imlib_image_tile_vertical(void);
|
||||
void imlib_image_tile(void);
|
||||
|
||||
/* fonts and text */
|
||||
Imlib_Font imlib_load_font(const char *font_name);
|
||||
void imlib_free_font(void);
|
||||
void imlib_text_draw(int x, int y, const char *text);
|
||||
void imlib_text_draw_with_return_metrics(int x, int y, const char *text,
|
||||
int *width_return,
|
||||
int *height_return,
|
||||
int *horizontal_advance_return,
|
||||
int *vertical_advance_return);
|
||||
void imlib_get_text_size(const char *text, int *width_return,
|
||||
int *height_return);
|
||||
void imlib_get_text_advance(const char *text,
|
||||
int *horizontal_advance_return,
|
||||
int *vertical_advance_return);
|
||||
int imlib_get_text_inset(const char *text);
|
||||
void imlib_add_path_to_font_path(const char *path);
|
||||
void imlib_remove_path_from_font_path(const char *path);
|
||||
char **imlib_list_font_path(int *number_return);
|
||||
int imlib_text_get_index_and_location(const char *text, int x, int y,
|
||||
int *char_x_return,
|
||||
int *char_y_return,
|
||||
int *char_width_return,
|
||||
int *char_height_return);
|
||||
void imlib_text_get_location_at_index(const char *text, int index,
|
||||
int *char_x_return,
|
||||
int *char_y_return,
|
||||
int *char_width_return,
|
||||
int *char_height_return);
|
||||
char **imlib_list_fonts(int *number_return);
|
||||
void imlib_free_font_list(char **font_list, int number);
|
||||
int imlib_get_font_cache_size(void);
|
||||
void imlib_set_font_cache_size(int bytes);
|
||||
void imlib_flush_font_cache(void);
|
||||
int imlib_get_font_ascent(void);
|
||||
int imlib_get_font_descent(void);
|
||||
int imlib_get_maximum_font_ascent(void);
|
||||
int imlib_get_maximum_font_descent(void);
|
||||
|
||||
/* color modifiers */
|
||||
Imlib_Color_Modifier imlib_create_color_modifier(void);
|
||||
void imlib_free_color_modifier(void);
|
||||
void imlib_modify_color_modifier_gamma(double gamma_value);
|
||||
void imlib_modify_color_modifier_brightness(double brightness_value);
|
||||
void imlib_modify_color_modifier_contrast(double contrast_value);
|
||||
void imlib_set_color_modifier_tables(DATA8 * red_table,
|
||||
DATA8 * green_table,
|
||||
DATA8 * blue_table,
|
||||
DATA8 * alpha_table);
|
||||
void imlib_get_color_modifier_tables(DATA8 * red_table,
|
||||
DATA8 * green_table,
|
||||
DATA8 * blue_table,
|
||||
DATA8 * alpha_table);
|
||||
void imlib_reset_color_modifier(void);
|
||||
void imlib_apply_color_modifier(void);
|
||||
void imlib_apply_color_modifier_to_rectangle(int x, int y, int width,
|
||||
int height);
|
||||
|
||||
/* drawing on images */
|
||||
Imlib_Updates imlib_image_draw_pixel(int x, int y, char make_updates);
|
||||
Imlib_Updates imlib_image_draw_line(int x1, int y1, int x2, int y2,
|
||||
char make_updates);
|
||||
int imlib_clip_line(int x0, int y0, int x1, int y1, int xmin, int xmax,
|
||||
int ymin, int ymax, int *clip_x0, int *clip_y0,
|
||||
int *clip_x1, int *clip_y1);
|
||||
void imlib_image_draw_rectangle(int x, int y, int width, int height);
|
||||
void imlib_image_fill_rectangle(int x, int y, int width, int height);
|
||||
void imlib_image_copy_alpha_to_image(Imlib_Image image_source, int x,
|
||||
int y);
|
||||
void imlib_image_copy_alpha_rectangle_to_image(Imlib_Image image_source,
|
||||
int x, int y, int width,
|
||||
int height,
|
||||
int destination_x,
|
||||
int destination_y);
|
||||
void imlib_image_scroll_rect(int x, int y, int width, int height,
|
||||
int delta_x, int delta_y);
|
||||
void imlib_image_copy_rect(int x, int y, int width, int height, int new_x,
|
||||
int new_y);
|
||||
|
||||
/* polygons */
|
||||
ImlibPolygon imlib_polygon_new(void);
|
||||
void imlib_polygon_free(ImlibPolygon poly);
|
||||
void imlib_polygon_add_point(ImlibPolygon poly, int x, int y);
|
||||
void imlib_image_draw_polygon(ImlibPolygon poly, unsigned char closed);
|
||||
void imlib_image_fill_polygon(ImlibPolygon poly);
|
||||
void imlib_polygon_get_bounds(ImlibPolygon poly, int *px1, int *py1,
|
||||
int *px2, int *py2);
|
||||
unsigned char imlib_polygon_contains_point(ImlibPolygon poly, int x,
|
||||
int y);
|
||||
|
||||
/* ellipses */
|
||||
void imlib_image_draw_ellipse(int xc, int yc, int a, int b);
|
||||
void imlib_image_fill_ellipse(int xc, int yc, int a, int b);
|
||||
|
||||
/* color ranges */
|
||||
Imlib_Color_Range imlib_create_color_range(void);
|
||||
void imlib_free_color_range(void);
|
||||
void imlib_add_color_to_color_range(int distance_away);
|
||||
void imlib_image_fill_color_range_rectangle(int x, int y, int width,
|
||||
int height, double angle);
|
||||
void imlib_image_fill_hsva_color_range_rectangle(int x, int y, int width,
|
||||
int height, double angle);
|
||||
|
||||
/* image data */
|
||||
void imlib_image_attach_data_value(const char *key, void *data, int value,
|
||||
Imlib_Data_Destructor_Function
|
||||
destructor_function);
|
||||
void *imlib_image_get_attached_data(const char *key);
|
||||
int imlib_image_get_attached_value(const char *key);
|
||||
void imlib_image_remove_attached_data_value(const char *key);
|
||||
void imlib_image_remove_and_free_attached_data_value(const char *key);
|
||||
|
||||
/* saving */
|
||||
void imlib_save_image(const char *filename);
|
||||
void imlib_save_image_with_error_return(const char *filename,
|
||||
Imlib_Load_Error * error_return);
|
||||
|
||||
/* FIXME: */
|
||||
/* need to add arbitary rotation routines */
|
||||
|
||||
/* rotation/skewing */
|
||||
Imlib_Image imlib_create_rotated_image(double angle);
|
||||
|
||||
/* rotation from buffer to context (without copying)*/
|
||||
void imlib_rotate_image_from_buffer(double angle,
|
||||
Imlib_Image source_image);
|
||||
|
||||
void imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,
|
||||
char merge_alpha, int source_x,
|
||||
int source_y, int source_width,
|
||||
int source_height,
|
||||
int destination_x,
|
||||
int destination_y, int angle_x,
|
||||
int angle_y);
|
||||
void imlib_blend_image_onto_image_skewed(Imlib_Image source_image,
|
||||
char merge_alpha, int source_x,
|
||||
int source_y, int source_width,
|
||||
int source_height,
|
||||
int destination_x,
|
||||
int destination_y, int h_angle_x,
|
||||
int h_angle_y, int v_angle_x,
|
||||
int v_angle_y);
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
void imlib_render_image_on_drawable_skewed(int source_x, int source_y,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int destination_x,
|
||||
int destination_y,
|
||||
int h_angle_x, int h_angle_y,
|
||||
int v_angle_x, int v_angle_y);
|
||||
void imlib_render_image_on_drawable_at_angle(int source_x, int source_y,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int destination_x,
|
||||
int destination_y,
|
||||
int angle_x, int angle_y);
|
||||
#endif
|
||||
|
||||
/* image filters */
|
||||
void imlib_image_filter(void);
|
||||
Imlib_Filter imlib_create_filter(int initsize);
|
||||
void imlib_context_set_filter(Imlib_Filter filter);
|
||||
Imlib_Filter imlib_context_get_filter(void);
|
||||
void imlib_free_filter(void);
|
||||
void imlib_filter_set(int xoff, int yoff, int a, int r, int g, int b);
|
||||
void imlib_filter_set_alpha(int xoff, int yoff, int a, int r, int g,
|
||||
int b);
|
||||
void imlib_filter_set_red(int xoff, int yoff, int a, int r, int g, int b);
|
||||
void imlib_filter_set_green(int xoff, int yoff, int a, int r, int g,
|
||||
int b);
|
||||
void imlib_filter_set_blue(int xoff, int yoff, int a, int r, int g, int b);
|
||||
void imlib_filter_constants(int a, int r, int g, int b);
|
||||
void imlib_filter_divisors(int a, int r, int g, int b);
|
||||
|
||||
void imlib_apply_filter(char *script, ...);
|
||||
|
||||
void imlib_image_clear(void);
|
||||
void imlib_image_clear_color(int r, int g, int b, int a);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
## 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
|
||||
|
||||
INCLUDES = -I. -I$(top_srcdir) -I$(top_srcdir)/src \
|
||||
-I$(top_builddir)/src \
|
||||
-I$(top_srcdir)/loaders \
|
||||
$(freetype_cflags) -I/usr/X11R6/include $(X_CFLAGS) \
|
||||
-I$(prefix)/include -I$(includedir) @XMISS@
|
||||
MMX_SRCS = asm_blend.S asm_rgba.S asm_scale.S asm_rotate.S \
|
||||
asm_blend_cmod.S
|
||||
MMX_OBJS = $(MMX_SRCS:.S=.lo)
|
||||
|
||||
lib_LTLIBRARIES = libImlib2.la
|
||||
include_HEADERS = Imlib2.h
|
||||
libImlib2_la_SOURCES = scale.c image.c blend.c file.c rgbadraw.c api.c \
|
||||
updates.c colormod.c format.c grad.c rotate.c \
|
||||
span.c line.c rectangle.c ellipse.c polygon.c \
|
||||
filter.c script.c dynamic_filters.c color_helpers.c \
|
||||
font_main.c font_load.c font_query.c font_draw.c \
|
||||
Imlib2.h image.h scale.h blend.h updates.h colormod.h \
|
||||
file.h common.h span.h rgbadraw.h font.h format.h \
|
||||
rotate.h grad.h filter.h script.h dynamic_filters.h \
|
||||
color_helpers.h loaderpath.h
|
||||
|
||||
EXTRA_libImlib2_la_SOURCES = rend.c ximage.c rgba.c color.c grab.c draw.c \
|
||||
context.c color.h context.h draw.h grab.h rend.h \
|
||||
rgba.h ximage.h $(MMX_SRCS)
|
||||
libImlib2_la_LDFLAGS = $(LDFLAGS) -L/usr/X11R6/lib -version-info 2:2:1
|
||||
|
||||
if HAVE_MMX
|
||||
libImlib2_la_LIBADD = $(X_OBJS) @DLLDFLAGS@ $(MMX_OBJS) \
|
||||
-lltdl \
|
||||
$(x_libs) $(freetype_libs) -lm
|
||||
libImlib2_la_DEPENDENCIES = $(top_builddir)/config.h $(X_OBJS) $(MMX_OBJS)
|
||||
else
|
||||
libImlib2_la_LIBADD = $(X_OBJS) @DLLDFLAGS@ \
|
||||
-lltdl \
|
||||
$(x_libs) $(freetype_libs) -lm
|
||||
libImlib2_la_DEPENDENCIES = $(top_builddir)/config.h $(X_OBJS)
|
||||
endif
|
1059
src/asm_blend.S
1059
src/asm_blend.S
File diff suppressed because it is too large
Load Diff
1604
src/asm_blend_cmod.S
1604
src/asm_blend_cmod.S
File diff suppressed because it is too large
Load Diff
301
src/asm_rgba.S
301
src/asm_rgba.S
|
@ -1,301 +0,0 @@
|
|||
#include <config.h>
|
||||
|
||||
#ifdef __EMX__
|
||||
/* Due to strange behaviour of as.exe we use this macros */
|
||||
/* For all OS/2 coders - please use PGCC to compile this code */
|
||||
#define PR_(foo) ___##foo
|
||||
#define PT_(foo,func) ___##foo,##func
|
||||
#define SIZE(sym) \
|
||||
.___end_##sym:; \
|
||||
.size ___##sym,.___end_##sym-___##sym; \
|
||||
.align 8;
|
||||
#else
|
||||
#define PR_(foo) __##foo
|
||||
#define PT_(foo,func) __##foo,##func
|
||||
#define SIZE(sym) \
|
||||
.__end_##sym:; \
|
||||
.size __##sym,.__end_##sym-__##sym; \
|
||||
.align 8;
|
||||
#endif
|
||||
|
||||
#ifdef DO_MMX_ASM
|
||||
|
||||
/*\
|
||||
|*| MMX assembly rgba rendering routines for Imlib2
|
||||
|*| Written by Willem Monsuwe <willem@stack.nl>
|
||||
|*|
|
||||
|*| Special (hairy) constructs are only commented on first use.
|
||||
\*/
|
||||
|
||||
/*\ All functions have the same calling convention:
|
||||
|*| __imlib_mmx_rgbXXX(void *src, int sjmp, void *dst, int dw,
|
||||
|*| int w, int h, int dx, int dy)
|
||||
\*/
|
||||
|
||||
#define src 8(%ebp)
|
||||
#define sjmp 12(%ebp)
|
||||
#define dst 16(%ebp)
|
||||
#define dw 20(%ebp)
|
||||
#define w 24(%ebp)
|
||||
#define h 28(%ebp)
|
||||
#define dx 32(%ebp)
|
||||
#define dy 36(%ebp)
|
||||
|
||||
.text
|
||||
.align 8
|
||||
.globl PR_(imlib_mmx_rgb565_fast)
|
||||
.type PT_(imlib_mmx_rgb565_fast,@function)
|
||||
.globl PR_(imlib_mmx_bgr565_fast)
|
||||
.type PT_(imlib_mmx_bgr565_fast,@function)
|
||||
.globl PR_(imlib_mmx_rgb555_fast)
|
||||
.type PT_(imlib_mmx_rgb555_fast,@function)
|
||||
.globl PR_(imlib_mmx_bgr555_fast)
|
||||
.type PT_(imlib_mmx_bgr555_fast,@function)
|
||||
|
||||
.globl PR_(imlib_get_cpuid)
|
||||
.type PT_(imlib_get_cpuid,@function)
|
||||
|
||||
/*\ Some useful masks \*/
|
||||
m_rb: .long 0x00f800f8, 0x00f800f8
|
||||
m_r: .long 0xf800f800, 0xf800f800
|
||||
m_g6: .long 0x0000fc00, 0x0000fc00
|
||||
m_g5: .long 0x0000f800, 0x0000f800
|
||||
/*\ Multiply constants to fake two shifts at once \*/
|
||||
mul_rgb565: .long 0x20000004, 0x20000004
|
||||
mul_bgr565: .long 0x00042000, 0x00042000
|
||||
mul_rgb555: .long 0x20000008, 0x20000008
|
||||
mul_bgr555: .long 0x00082000, 0x00082000
|
||||
|
||||
/*\ Common code \*/
|
||||
/*\ Save registers, load common parameters \*/
|
||||
#define ENTER \
|
||||
pushl %ebp; \
|
||||
movl %esp, %ebp; \
|
||||
pushl %ebx; \
|
||||
pushl %ecx; \
|
||||
pushl %edx; \
|
||||
pushl %edi; \
|
||||
pushl %esi; \
|
||||
movl src, %esi; \
|
||||
movl dst, %edi; \
|
||||
movl w, %ebx; \
|
||||
movl h, %edx; \
|
||||
addl %ebx, sjmp
|
||||
|
||||
#define LOOP_START \
|
||||
testl %edx, %edx; \
|
||||
jz 4f; \
|
||||
testl %ebx, %ebx; \
|
||||
jz 4f; \
|
||||
0: \
|
||||
movl %ebx, %ecx
|
||||
|
||||
#define LOOP_END \
|
||||
3: \
|
||||
movl sjmp, %ecx; \
|
||||
leal (%esi, %ecx, 4), %esi; \
|
||||
addl dw, %edi; \
|
||||
decl %edx; \
|
||||
jnz 0b; \
|
||||
4:
|
||||
|
||||
/*\ Unset MMX mode, reset registers, return \*/
|
||||
#define LEAVE \
|
||||
emms; \
|
||||
popl %esi; \
|
||||
popl %edi; \
|
||||
popl %edx; \
|
||||
popl %ecx; \
|
||||
popl %ebx; \
|
||||
movl %ebp, %esp; \
|
||||
popl %ebp; \
|
||||
ret
|
||||
|
||||
|
||||
|
||||
PR_(imlib_mmx_bgr565_fast):
|
||||
movq mul_bgr565, %mm7 /*\ This constant is the only difference \*/
|
||||
jmp .rgb565_fast_entry
|
||||
|
||||
SIZE(imlib_mmx_bgr565_fast)
|
||||
|
||||
PR_(imlib_mmx_rgb565_fast):
|
||||
movq mul_rgb565, %mm7
|
||||
.rgb565_fast_entry:
|
||||
ENTER
|
||||
|
||||
movq m_rb, %mm5
|
||||
movq m_g6, %mm6
|
||||
|
||||
LOOP_START
|
||||
|
||||
test $1, %ecx
|
||||
jz 1f
|
||||
decl %ecx
|
||||
movd (%esi, %ecx, 4), %mm0
|
||||
movq %mm0, %mm1
|
||||
pand %mm5, %mm0
|
||||
pand %mm6, %mm1
|
||||
pmaddwd %mm7, %mm0
|
||||
por %mm1, %mm0
|
||||
psrad $5, %mm0
|
||||
|
||||
movd %mm0, %eax
|
||||
movw %ax, (%edi, %ecx, 2)
|
||||
|
||||
jz 3f
|
||||
1:
|
||||
test $2, %ecx
|
||||
jz 2f
|
||||
subl $2, %ecx
|
||||
movq (%esi, %ecx, 4), %mm0
|
||||
movq %mm0, %mm1
|
||||
pand %mm5, %mm0
|
||||
pand %mm6, %mm1
|
||||
pmaddwd %mm7, %mm0
|
||||
por %mm1, %mm0
|
||||
pslld $11, %mm0
|
||||
psrad $16, %mm0
|
||||
|
||||
packssdw %mm0, %mm0
|
||||
|
||||
movd %mm0, (%edi, %ecx, 2)
|
||||
|
||||
jz 3f
|
||||
2:
|
||||
subl $4, %ecx
|
||||
movq (%esi, %ecx, 4), %mm0
|
||||
movq 8(%esi, %ecx, 4), %mm2
|
||||
movq %mm0, %mm1 /*\ a r g b (2x) \*/
|
||||
movq %mm2, %mm3
|
||||
pand %mm5, %mm0 /*\ 0 rrrrr000 0 bbbbb000 (2 x) \*/
|
||||
pand %mm5, %mm2
|
||||
pand %mm6, %mm1 /*\ 0 0 gggggg00 00000000 (2 x) \*/
|
||||
pand %mm6, %mm3
|
||||
pmaddwd %mm7, %mm0 /*\ 0 000rrrrr 000000bb bbb00000 (2 x) \*/
|
||||
pmaddwd %mm7, %mm2
|
||||
por %mm1, %mm0 /*\ 0 000rrrrr ggggggbb bbb00000 (2 x) \*/
|
||||
por %mm3, %mm2
|
||||
pslld $11, %mm0 /*\ rrrrrggg gggbbbbb 0 0 (2 x) \*/
|
||||
pslld $11, %mm2
|
||||
psrad $16, %mm0 /*\ x x rrrrrggg gggbbbbb (2 x) \*/
|
||||
psrad $16, %mm2
|
||||
|
||||
packssdw %mm2, %mm0 /*\ rrrrrggg gggbbbbb (4 x) \*/
|
||||
|
||||
movq %mm0, (%edi, %ecx, 2)
|
||||
|
||||
jnz 2b
|
||||
LOOP_END
|
||||
LEAVE
|
||||
|
||||
SIZE(imlib_mmx_rgb565_fast)
|
||||
|
||||
|
||||
PR_(imlib_mmx_bgr555_fast):
|
||||
movq mul_bgr555, %mm7 /*\ This constant is the only difference \*/
|
||||
jmp .rgb555_fast_entry
|
||||
|
||||
SIZE(imlib_mmx_bgr555_fast)
|
||||
|
||||
PR_(imlib_mmx_rgb555_fast):
|
||||
movq mul_rgb555, %mm7
|
||||
.rgb555_fast_entry:
|
||||
ENTER
|
||||
|
||||
movq m_rb, %mm5
|
||||
movq m_g5, %mm6
|
||||
|
||||
LOOP_START
|
||||
|
||||
test $1, %ecx
|
||||
jz 1f
|
||||
decl %ecx
|
||||
movd (%esi, %ecx, 4), %mm0
|
||||
movq %mm0, %mm1
|
||||
pand %mm5, %mm0
|
||||
pand %mm6, %mm1
|
||||
pmaddwd %mm7, %mm0
|
||||
por %mm1, %mm0
|
||||
psrad $5, %mm0
|
||||
|
||||
movd %mm0, %eax
|
||||
movw %ax, (%edi, %ecx, 2)
|
||||
|
||||
jz 3f
|
||||
1:
|
||||
test $2, %ecx
|
||||
jz 2f
|
||||
subl $2, %ecx
|
||||
movq (%esi, %ecx, 4), %mm0
|
||||
movq %mm0, %mm1
|
||||
pand %mm5, %mm0
|
||||
pand %mm6, %mm1
|
||||
pmaddwd %mm7, %mm0
|
||||
por %mm1, %mm0
|
||||
psrld $6, %mm0
|
||||
|
||||
packssdw %mm0, %mm0
|
||||
|
||||
movd %mm0, (%edi, %ecx, 2)
|
||||
|
||||
jz 3f
|
||||
2:
|
||||
subl $4, %ecx
|
||||
movq (%esi, %ecx, 4), %mm0
|
||||
movq 8(%esi, %ecx, 4), %mm2
|
||||
movq %mm0, %mm1 /*\ a r g b (2x) \*/
|
||||
movq %mm2, %mm3
|
||||
pand %mm5, %mm0 /*\ 0 rrrrr000 0 bbbbb000 (2 x) \*/
|
||||
pand %mm5, %mm2
|
||||
pand %mm6, %mm1 /*\ 0 0 ggggg000 00000000 (2 x) \*/
|
||||
pand %mm6, %mm3
|
||||
pmaddwd %mm7, %mm0 /*\ 0 000rrrrr 00000bbb bb000000 (2 x) \*/
|
||||
pmaddwd %mm7, %mm2
|
||||
por %mm1, %mm0 /*\ 0 000rrrrr gggggbbb bb000000 (2 x) \*/
|
||||
por %mm3, %mm2
|
||||
psrld $6, %mm0 /*\ 0 0 0rrrrrgg gggbbbbb (2 x) \*/
|
||||
psrld $6, %mm2
|
||||
|
||||
packssdw %mm2, %mm0 /*\ 0rrrrrgg gggbbbbb (4 x) \*/
|
||||
|
||||
movq %mm0, (%edi, %ecx, 2)
|
||||
|
||||
jnz 2b
|
||||
LOOP_END
|
||||
LEAVE
|
||||
|
||||
SIZE(imlib_mmx_rgb555_fast)
|
||||
|
||||
PR_(imlib_get_cpuid):
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
|
||||
pushf
|
||||
popl %eax
|
||||
movl %eax, %ebx
|
||||
xorl $0x200000, %eax
|
||||
pushl %eax
|
||||
popf
|
||||
pushf
|
||||
popl %eax
|
||||
xorl %ebx, %eax
|
||||
andl $0x200000, %eax
|
||||
jz 1f
|
||||
xorl %eax, %eax
|
||||
cpuid
|
||||
testl %eax, %eax
|
||||
jz 1f
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
and $0x00000f00, %eax
|
||||
and $0xfffff0ff, %edx
|
||||
orl %edx, %eax
|
||||
1:
|
||||
popl %edx
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
SIZE(imlib_get_cpuid)
|
||||
|
||||
#endif
|
469
src/asm_rotate.S
469
src/asm_rotate.S
|
@ -1,469 +0,0 @@
|
|||
#include <config.h>
|
||||
|
||||
#ifdef __EMX__
|
||||
/* Due to strange behaviour of as.exe we use this macros */
|
||||
/* For all OS/2 coders - please use PGCC to compile this code */
|
||||
#define PR_(foo) ___##foo
|
||||
#define PT_(foo,func) ___##foo,##func
|
||||
#define SIZE(sym) \
|
||||
.___end_##sym:; \
|
||||
.size ___##sym,.___end_##sym-___##sym; \
|
||||
.align 8;
|
||||
#else
|
||||
#define PR_(foo) __##foo
|
||||
#define PT_(foo,func) __##foo,##func
|
||||
#define SIZE(sym) \
|
||||
.__end_##sym:; \
|
||||
.size __##sym,.__end_##sym-__##sym; \
|
||||
.align 8;
|
||||
#endif
|
||||
|
||||
#ifdef DO_MMX_ASM
|
||||
|
||||
/*\
|
||||
|*| MMX assembly rotation routine for Imlib2
|
||||
|*| Written by Willem Monsuwe <willem@stack.nl>
|
||||
\*/
|
||||
|
||||
.text
|
||||
.align 8
|
||||
.globl PR_(imlib_mmx_RotateAA)
|
||||
.type PT_(imlib_mmx_RotateAA,@function)
|
||||
|
||||
|
||||
/*\ Prototype: __imlib_mmx_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw,
|
||||
|*| int sh, int dow, int dw, int dh, int x, int y,
|
||||
|*| int dxh, int dyh, int dxv, int dyv)
|
||||
\*/
|
||||
|
||||
#define src 8(%ebp)
|
||||
#define dest 12(%ebp)
|
||||
#define sow 16(%ebp)
|
||||
#define sw 20(%ebp)
|
||||
#define sh 24(%ebp)
|
||||
#define dow 28(%ebp)
|
||||
#define dw 32(%ebp)
|
||||
#define dh 36(%ebp)
|
||||
#define x 40(%ebp)
|
||||
#define y 44(%ebp)
|
||||
#define dxh 48(%ebp)
|
||||
#define dyh 52(%ebp)
|
||||
#define dxv 56(%ebp)
|
||||
#define dyv 60(%ebp)
|
||||
|
||||
/*\ Local variables \*/
|
||||
#define j -4(%ebp)
|
||||
#define dly -8(%ebp)
|
||||
#define dlx -12(%ebp)
|
||||
#define sht -16(%ebp)
|
||||
#define swt -20(%ebp)
|
||||
#define m0fffh -24(%ebp)
|
||||
#define m0fff -28(%ebp)
|
||||
#define mulsow -32(%ebp)
|
||||
|
||||
PR_(imlib_mmx_RotateAA):
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
subl $40, %esp
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
|
||||
/*\ Check (dw > 0) && (dh > 0) \*/
|
||||
cmpl $0, dw
|
||||
jle .rotate_leave
|
||||
cmpl $0, dh
|
||||
jle .rotate_leave
|
||||
|
||||
pxor %mm7, %mm7
|
||||
movl sow, %eax
|
||||
sall $16, %eax
|
||||
orl $1, %eax
|
||||
movl %eax, mulsow
|
||||
movl $0x0fff, %eax
|
||||
movl %eax, m0fff
|
||||
movl %eax, m0fffh
|
||||
|
||||
/*\ mm6 = x, y \*/
|
||||
movq x, %mm6
|
||||
|
||||
/*\ edi = dest + dw \*/
|
||||
movl dest, %edi
|
||||
movl dw, %eax
|
||||
leal (%edi, %eax, 4), %edi
|
||||
|
||||
/*\ dlx = dxv - dw * dxh \*/
|
||||
movl dw, %eax
|
||||
imull dxh, %eax
|
||||
negl %eax
|
||||
addl dxv, %eax
|
||||
movl %eax, dlx
|
||||
|
||||
/*\ dly = dyv - dw * dyh \*/
|
||||
movl dw, %eax
|
||||
imull dyh, %eax
|
||||
negl %eax
|
||||
addl dyv, %eax
|
||||
movl %eax, dly
|
||||
|
||||
/*\ j = dh \*/
|
||||
movl dh, %eax
|
||||
movl %eax, j
|
||||
|
||||
/*\ Check if all coordinates will be inside the source \*/
|
||||
/*\ x < sw \*/
|
||||
movl sw, %edx
|
||||
movl x, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
/*\ x + dxh * dw < sw \*/
|
||||
movl dxh, %ebx
|
||||
imull dw, %ebx
|
||||
addl %ebx, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
/*\ x + dxh * dw + dxv * dh < sw \*/
|
||||
movl dxv, %eax
|
||||
imull dh, %eax
|
||||
subl %eax, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
/*\ x + dxv * dh < sw \*/
|
||||
subl %ebx, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
|
||||
/*\ y < sh \*/
|
||||
movl sh, %edx
|
||||
movl y, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
/*\ y + dyh * dw < sh \*/
|
||||
movl dyh, %ebx
|
||||
imull dw, %ebx
|
||||
addl %ebx, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
/*\ y + dyh * dw + dyv * dh < sh \*/
|
||||
movl dyv, %eax
|
||||
imull dh, %eax
|
||||
addl %eax, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
/*\ y + dyv * dh < sh \*/
|
||||
subl %ebx, %ecx
|
||||
cmpl %edx, %ecx
|
||||
jae .rotate_outside
|
||||
|
||||
.rotate_inside:
|
||||
movl sow, %ebx
|
||||
movl src, %edx
|
||||
.inside_loop_y:
|
||||
|
||||
/*\ i = -dw \*/
|
||||
movl dw, %ecx
|
||||
negl %ecx
|
||||
.inside_loop_x:
|
||||
/*\ esi = src + x >> 12 + (y >> 12) * sow \*/
|
||||
movq %mm6, %mm0
|
||||
psrad $12, %mm0
|
||||
packssdw %mm0, %mm0
|
||||
pmaddwd mulsow, %mm0
|
||||
movd %mm0, %eax
|
||||
leal (%edx, %eax, 4), %esi
|
||||
|
||||
/*\ x and y \*/
|
||||
movq %mm6, %mm0
|
||||
pand m0fff, %mm0
|
||||
movq %mm0, %mm1
|
||||
/*\ mm0 = x & 0xfff \*/
|
||||
punpcklwd %mm0, %mm0
|
||||
punpckldq %mm0, %mm0
|
||||
/*\ mm1 = y & 0xfff \*/
|
||||
punpckhwd %mm1, %mm1
|
||||
punpckldq %mm1, %mm1
|
||||
|
||||
/*\ Load and unpack four pixels in parralel
|
||||
|*| %mm2 = ptr[0], %mm3 = ptr[1]
|
||||
|*| %mm4 = ptr[sow], %mm5 = ptr[sow + 1]
|
||||
\*/
|
||||
movq (%esi), %mm2
|
||||
movq (%esi, %ebx, 4), %mm4
|
||||
movq %mm2, %mm3
|
||||
movq %mm4, %mm5
|
||||
punpcklbw %mm7, %mm2
|
||||
punpcklbw %mm7, %mm4
|
||||
punpckhbw %mm7, %mm3
|
||||
punpckhbw %mm7, %mm5
|
||||
|
||||
/*\ X interpolation: r = l + (r - l) * xap \*/
|
||||
psubw %mm2, %mm3
|
||||
psubw %mm4, %mm5
|
||||
psllw $4, %mm3
|
||||
psllw $4, %mm5
|
||||
pmulhw %mm0, %mm3
|
||||
pmulhw %mm0, %mm5
|
||||
paddw %mm2, %mm3
|
||||
paddw %mm4, %mm5
|
||||
|
||||
/*\ Y interpolation: d = u + (d - u) * yap \*/
|
||||
psubw %mm3, %mm5
|
||||
psllw $4, %mm5
|
||||
pmulhw %mm1, %mm5
|
||||
paddw %mm3, %mm5
|
||||
packuswb %mm5, %mm5
|
||||
movd %mm5, (%edi, %ecx, 4)
|
||||
|
||||
paddd dxh, %mm6
|
||||
|
||||
incl %ecx
|
||||
jnz .inside_loop_x
|
||||
|
||||
paddd dlx, %mm6
|
||||
movl dow, %ecx
|
||||
leal (%edi, %ecx, 4), %edi
|
||||
decl j
|
||||
jnz .inside_loop_y
|
||||
|
||||
jmp .rotate_leave
|
||||
|
||||
.rotate_outside:
|
||||
movl sw, %eax
|
||||
decl %eax
|
||||
sall $12, %eax
|
||||
movl %eax, swt
|
||||
movl sh, %eax
|
||||
decl %eax
|
||||
sall $12, %eax
|
||||
movl %eax, sht
|
||||
|
||||
movl sow, %ebx
|
||||
movl src, %edx
|
||||
.outside_loop_y:
|
||||
|
||||
/*\ i = -dw \*/
|
||||
movl dw, %ecx
|
||||
negl %ecx
|
||||
.outside_loop_x:
|
||||
/*\ esi = src + x >> 12 + (y >> 12) * sow \*/
|
||||
movq %mm6, %mm0
|
||||
psrad $12, %mm0
|
||||
packssdw %mm0, %mm0
|
||||
pmaddwd mulsow, %mm0
|
||||
movd %mm0, %eax
|
||||
leal (%edx, %eax, 4), %esi
|
||||
|
||||
/*\ x & 0xfff and y & 0xfff \*/
|
||||
movq %mm6, %mm0
|
||||
pand m0fff, %mm0
|
||||
movq %mm0, %mm1
|
||||
|
||||
/*\ x < swt \*/
|
||||
movq %mm6, %mm2
|
||||
psrlq $32, %mm2
|
||||
movd %mm6, %eax
|
||||
cmpl swt, %eax
|
||||
jae 2f
|
||||
|
||||
/*\ y < sht \*/
|
||||
movd %mm2, %eax
|
||||
cmpl sht, %eax
|
||||
jae 1f
|
||||
/*\ 1234 \*/
|
||||
.interp_argb:
|
||||
/*\ Unpack x and y \*/
|
||||
punpcklwd %mm0, %mm0
|
||||
punpckldq %mm0, %mm0
|
||||
punpckhwd %mm1, %mm1
|
||||
punpckldq %mm1, %mm1
|
||||
/*\ Load and unpack four pixels in parralel
|
||||
|*| %mm2 = ptr[0], %mm3 = ptr[1]
|
||||
|*| %mm4 = ptr[sow], %mm5 = ptr[sow + 1]
|
||||
\*/
|
||||
movq (%esi), %mm2
|
||||
movq (%esi, %ebx, 4), %mm4
|
||||
movq %mm2, %mm3
|
||||
movq %mm4, %mm5
|
||||
punpcklbw %mm7, %mm2
|
||||
punpcklbw %mm7, %mm4
|
||||
punpckhbw %mm7, %mm3
|
||||
punpckhbw %mm7, %mm5
|
||||
|
||||
/*\ X interpolation: r = l + (r - l) * xap \*/
|
||||
psubw %mm2, %mm3
|
||||
psubw %mm4, %mm5
|
||||
psllw $4, %mm3
|
||||
psllw $4, %mm5
|
||||
pmulhw %mm0, %mm3
|
||||
pmulhw %mm0, %mm5
|
||||
paddw %mm2, %mm3
|
||||
paddw %mm4, %mm5
|
||||
|
||||
/*\ Y interpolation: d = u + (d - u) * yap \*/
|
||||
psubw %mm3, %mm5
|
||||
psllw $4, %mm5
|
||||
pmulhw %mm1, %mm5
|
||||
paddw %mm3, %mm5
|
||||
packuswb %mm5, %mm5
|
||||
movd %mm5, (%edi, %ecx, 4)
|
||||
jmp .outside_il_end
|
||||
1:
|
||||
/*\ (-y-1) < 4096 \*/
|
||||
notl %eax
|
||||
cmpl $4095, %eax
|
||||
ja 1f
|
||||
/*\ ..34 \*/
|
||||
pxor m0fff, %mm1
|
||||
movd (%esi, %ebx, 4), %mm2
|
||||
movd 4(%esi, %ebx, 4), %mm4
|
||||
|
||||
.interp_rgb_a0:
|
||||
/*\ Unpack x and y \*/
|
||||
punpcklwd %mm0, %mm0
|
||||
punpckldq %mm0, %mm0
|
||||
punpckhwd %mm1, %mm1
|
||||
/*\ Unpack two pixels \*/
|
||||
punpcklbw %mm7, %mm2
|
||||
punpcklbw %mm7, %mm4
|
||||
/*\ Interpolate \*/
|
||||
psubw %mm2, %mm4
|
||||
psllw $4, %mm4
|
||||
pmulhw %mm0, %mm4
|
||||
paddw %mm2, %mm4
|
||||
/*\ Separate out alpha, multiply with mm1, and subtract \*/
|
||||
movq %mm4, %mm2
|
||||
psllq $48, %mm1
|
||||
psllw $4, %mm4
|
||||
pmulhw %mm1, %mm4
|
||||
psubw %mm4, %mm2
|
||||
packuswb %mm2, %mm2
|
||||
movd %mm2, (%edi, %ecx, 4)
|
||||
jmp .outside_il_end
|
||||
1:
|
||||
/*\ (y - sht) < 4096 \*/
|
||||
notl %eax
|
||||
subl sht, %eax
|
||||
cmpl $4095, %eax
|
||||
ja .outside_il_0
|
||||
/*\ 12.. \*/
|
||||
movd (%esi), %mm2
|
||||
movd 4(%esi), %mm4
|
||||
jmp .interp_rgb_a0
|
||||
2:
|
||||
/*\ Switch x and y \*/
|
||||
psrlq $32, %mm0
|
||||
psllq $32, %mm1
|
||||
/*\ -x-1 < 4096 \*/
|
||||
notl %eax
|
||||
cmpl $4095, %eax
|
||||
ja 2f
|
||||
|
||||
pxor m0fff, %mm1
|
||||
/*\ y < sht \*/
|
||||
movd %mm2, %eax
|
||||
cmpl sht, %eax
|
||||
jae 1f
|
||||
/*\ .2.4 \*/
|
||||
movd 4(%esi), %mm2
|
||||
movd 4(%esi, %ebx, 4), %mm4
|
||||
jmp .interp_rgb_a0
|
||||
1:
|
||||
/*\ (-y-1) < 4096 \*/
|
||||
notl %eax
|
||||
cmpl $4095, %eax
|
||||
ja 1f
|
||||
/*\ ...4 \*/
|
||||
movd 4(%esi, %ebx, 4), %mm2
|
||||
.interp_a000:
|
||||
/*\ Separate out alpha, multiply with mm0 and mm1 \*/
|
||||
pxor m0fff, %mm1
|
||||
punpcklbw %mm7, %mm2
|
||||
movq %mm2, %mm3
|
||||
psllq $2, %mm0
|
||||
psrlq $30, %mm1
|
||||
pmulhw %mm0, %mm1
|
||||
pxor m0fff, %mm1
|
||||
psllq $48, %mm1
|
||||
psllw $4, %mm3
|
||||
pmulhw %mm1, %mm3
|
||||
psubw %mm3, %mm2
|
||||
packuswb %mm2, %mm2
|
||||
movd %mm2, (%edi, %ecx, 4)
|
||||
jmp .outside_il_end
|
||||
1:
|
||||
/*\ (y - sht) < 4096 \*/
|
||||
notl %eax
|
||||
subl sht, %eax
|
||||
cmpl $4095, %eax
|
||||
ja .outside_il_0
|
||||
/*\ .2.. \*/
|
||||
pxor m0fff, %mm0
|
||||
movd 4(%esi), %mm2
|
||||
jmp .interp_a000
|
||||
2:
|
||||
/*\ (x - swt) < 4096 \*/
|
||||
notl %eax
|
||||
subl swt, %eax
|
||||
cmpl $4095, %eax
|
||||
ja .outside_il_0
|
||||
|
||||
/*\ y < sht \*/
|
||||
movd %mm2, %eax
|
||||
cmpl sht, %eax
|
||||
jae 1f
|
||||
/*\ 1.3. \*/
|
||||
movd (%esi), %mm2
|
||||
movd (%esi, %ebx, 4), %mm4
|
||||
jmp .interp_rgb_a0
|
||||
1:
|
||||
/*\ (-y-1) < 4096 \*/
|
||||
notl %eax
|
||||
cmpl $4095, %eax
|
||||
ja 1f
|
||||
/*\ ..3. \*/
|
||||
movd (%esi, %ebx, 4), %mm2
|
||||
jmp .interp_a000
|
||||
1:
|
||||
/*\ (y - sht) < 4096 \*/
|
||||
notl %eax
|
||||
subl sht, %eax
|
||||
cmpl $4095, %eax
|
||||
ja .outside_il_0
|
||||
/*\ 1... \*/
|
||||
pxor m0fff, %mm0
|
||||
movd (%esi), %mm2
|
||||
jmp .interp_a000
|
||||
|
||||
.outside_il_0:
|
||||
movl $0, %eax
|
||||
movl %eax, (%edi, %ecx, 4)
|
||||
|
||||
.outside_il_end:
|
||||
paddd dxh, %mm6
|
||||
|
||||
incl %ecx
|
||||
jnz .outside_loop_x
|
||||
|
||||
paddd dlx, %mm6
|
||||
movl dow, %ecx
|
||||
leal (%edi, %ecx, 4), %edi
|
||||
decl j
|
||||
jnz .outside_loop_y
|
||||
|
||||
.rotate_leave:
|
||||
emms
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
SIZE(imlib_mmx_RotateAA)
|
||||
|
||||
#endif
|
||||
|
809
src/asm_scale.S
809
src/asm_scale.S
|
@ -1,809 +0,0 @@
|
|||
#include <config.h>
|
||||
|
||||
#ifdef __EMX__
|
||||
/* Due to strange behaviour of as.exe we use this macros */
|
||||
/* For all OS/2 coders - please use PGCC to compile this code */
|
||||
#define PR_(foo) ___##foo
|
||||
#define PT_(foo,func) ___##foo,##func
|
||||
#define SIZE(sym) \
|
||||
.___end_##sym:; \
|
||||
.size ___##sym,.___end_##sym-___##sym; \
|
||||
.align 8;
|
||||
#else
|
||||
#define PR_(foo) __##foo
|
||||
#define PT_(foo,func) __##foo,##func
|
||||
#define SIZE(sym) \
|
||||
.__end_##sym:; \
|
||||
.size __##sym,.__end_##sym-__##sym; \
|
||||
.align 8;
|
||||
#endif
|
||||
|
||||
#ifdef DO_MMX_ASM
|
||||
|
||||
/*\
|
||||
|*| MMX assembly scaling routine for Imlib2
|
||||
|*| Written by Willem Monsuwe <willem@stack.nl>
|
||||
\*/
|
||||
|
||||
.text
|
||||
.align 8
|
||||
.globl PR_(imlib_Scale_mmx_AARGBA)
|
||||
.type PT_(imlib_Scale_mmx_AARGBA,@function)
|
||||
|
||||
/*\ Prototype: __imlib_Scale_mmx_AARGBA(ImlibScaleInfo *isi, DATA32 *dest,
|
||||
|*| int dxx, int dyy, int dx, int dy, int dw, int dh, int dow, int sow)
|
||||
\*/
|
||||
|
||||
#define isi 8(%ebp)
|
||||
#define dest 12(%ebp)
|
||||
#define dxx 16(%ebp)
|
||||
#define dyy 20(%ebp)
|
||||
#define dx 24(%ebp)
|
||||
#define dy 28(%ebp)
|
||||
#define dw 32(%ebp)
|
||||
#define dh 36(%ebp)
|
||||
#define dow 40(%ebp)
|
||||
#define sow 44(%ebp)
|
||||
|
||||
/*\ Local variables that didn't fit in registers \*/
|
||||
#define y -4(%ebp)
|
||||
#define yp -8(%ebp)
|
||||
#define yap -12(%ebp)
|
||||
#define xp -16(%ebp)
|
||||
#define xap -20(%ebp)
|
||||
#define Cx -24(%ebp)
|
||||
#define Mx -28(%ebp)
|
||||
#define Cy -32(%ebp)
|
||||
#define My -36(%ebp)
|
||||
#define sow_4 -40(%ebp)
|
||||
|
||||
/*\ When %edx points to ImlibScaleInfo, these are the members \*/
|
||||
#define xpoints (%edx)
|
||||
#define ypoints 4(%edx)
|
||||
#define xapoints 8(%edx)
|
||||
#define yapoints 12(%edx)
|
||||
#define xup_yup 16(%edx)
|
||||
|
||||
PR_(imlib_Scale_mmx_AARGBA):
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
subl $40, %esp
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
movl isi, %edx
|
||||
|
||||
/*\ Check (dw > 0) && (dh > 0) \*/
|
||||
cmpl $0, dw
|
||||
jle .scale_leave
|
||||
cmpl $0, dh
|
||||
jle .scale_leave
|
||||
|
||||
/*\ X-based array pointers point to the end; we're looping up to 0 \*/
|
||||
/*\ %edi = dest + dow * dy + dx + dw \*/
|
||||
movl dow, %eax
|
||||
imull dy, %eax
|
||||
addl dx, %eax
|
||||
addl dw, %eax
|
||||
movl dest, %edi
|
||||
leal (%edi, %eax, 4), %edi
|
||||
/*\ xp = xpoints + dxx + dw \*/
|
||||
movl dxx, %ebx
|
||||
addl dw, %ebx
|
||||
movl xpoints, %eax
|
||||
leal (%eax, %ebx, 4), %eax
|
||||
movl %eax, xp
|
||||
/*\ xap = xapoints + dxx + dw \*/
|
||||
movl xapoints, %eax
|
||||
leal (%eax, %ebx, 4), %eax
|
||||
movl %eax, xap
|
||||
/*\ y = dh \*/
|
||||
movl dh, %eax
|
||||
movl %eax, y
|
||||
/*\ yp = ypoints + dyy \*/
|
||||
movl dyy, %ebx
|
||||
movl ypoints, %eax
|
||||
leal (%eax, %ebx, 4), %eax
|
||||
movl %eax, yp
|
||||
/*\ yap = yapoints + dyy \*/
|
||||
movl yapoints, %eax
|
||||
leal (%eax, %ebx, 4), %eax
|
||||
movl %eax, yap
|
||||
|
||||
pxor %mm7, %mm7
|
||||
|
||||
/*\ Test xup bit \*/
|
||||
movl xup_yup, %eax
|
||||
sarl $1, %eax
|
||||
jnc .scale_x_down
|
||||
|
||||
.scale_x_up:
|
||||
/*\ Test yup bit \*/
|
||||
sarl $1, %eax
|
||||
jnc .scale_x_up_y_down
|
||||
|
||||
|
||||
/*\ Scaling up both ways \*/
|
||||
|
||||
.scale_x_up_y_up:
|
||||
movl sow, %ebx
|
||||
|
||||
.up_up_loop_y:
|
||||
|
||||
/*\ x = -dw \*/
|
||||
movl dw, %ecx
|
||||
negl %ecx
|
||||
|
||||
/*\ %eax = *yap << 4 \*/
|
||||
movl yap, %eax
|
||||
movl (%eax), %eax
|
||||
sall $4, %eax
|
||||
jz .up_up_yap_0
|
||||
movd %eax, %mm1
|
||||
punpcklwd %mm1, %mm1
|
||||
punpckldq %mm1, %mm1
|
||||
|
||||
.up_up_loop1_x:
|
||||
/*\ %esi = *yp + xp[x] \*/
|
||||
movl yp, %eax
|
||||
movl (%eax), %esi
|
||||
movl xp, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
leal (%esi, %eax, 4), %esi
|
||||
|
||||
/*\ %eax = xap[x] << 4 \*/
|
||||
movl xap, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
sall $4, %eax
|
||||
jz .up_up_xap_0
|
||||
|
||||
/*\ %mm0 = xap[x] << 4 \*/
|
||||
movd %eax, %mm0
|
||||
punpcklwd %mm0, %mm0
|
||||
punpckldq %mm0, %mm0
|
||||
|
||||
/*\ Load and unpack four pixels in parralel
|
||||
|*| %mm2 = ptr[0], %mm3 = ptr[1]
|
||||
|*| %mm4 = ptr[sow], %mm5 = ptr[sow + 1]
|
||||
\*/
|
||||
movq (%esi), %mm2
|
||||
movq (%esi, %ebx, 4), %mm4
|
||||
movq %mm2, %mm3
|
||||
movq %mm4, %mm5
|
||||
punpcklbw %mm7, %mm2
|
||||
punpcklbw %mm7, %mm4
|
||||
punpckhbw %mm7, %mm3
|
||||
punpckhbw %mm7, %mm5
|
||||
|
||||
/*\ X interpolation: r = l + (r - l) * xap \*/
|
||||
psubw %mm2, %mm3
|
||||
psubw %mm4, %mm5
|
||||
psllw $4, %mm3
|
||||
psllw $4, %mm5
|
||||
pmulhw %mm0, %mm3
|
||||
pmulhw %mm0, %mm5
|
||||
paddw %mm2, %mm3
|
||||
paddw %mm4, %mm5
|
||||
/*\ Now %mm3 = I(ptr[0], ptr[1]), %mm5 = I(ptr[sow], ptr[sow + 1]) \*/
|
||||
jmp .up_up_common
|
||||
.up_up_xap_0:
|
||||
/*\ Load and unpack two pixels
|
||||
|*| %mm3 = ptr[0], %mm5 = ptr[sow]
|
||||
\*/
|
||||
movd (%esi), %mm3
|
||||
movd (%esi, %ebx, 4), %mm5
|
||||
punpcklbw %mm7, %mm3
|
||||
punpcklbw %mm7, %mm5
|
||||
.up_up_common:
|
||||
/*\ Y interpolation: d = u + (d - u) * yap \*/
|
||||
psubw %mm3, %mm5
|
||||
psllw $4, %mm5
|
||||
pmulhw %mm1, %mm5
|
||||
paddw %mm3, %mm5
|
||||
packuswb %mm5, %mm5
|
||||
movd %mm5, (%edi, %ecx, 4)
|
||||
|
||||
/*\ while (++x) \*/
|
||||
incl %ecx
|
||||
jnz .up_up_loop1_x
|
||||
jmp .up_up_yap_end
|
||||
.up_up_yap_0:
|
||||
|
||||
.up_up_loop2_x:
|
||||
/*\ %esi = *yp + xp[x] \*/
|
||||
movl yp, %eax
|
||||
movl (%eax), %esi
|
||||
movl xp, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
leal (%esi, %eax, 4), %esi
|
||||
|
||||
/*\ %eax = xap[x] << 4 \*/
|
||||
movl xap, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
sall $4, %eax
|
||||
jz .up_up_0
|
||||
|
||||
/*\ %mm0 = xap[x] << 4 \*/
|
||||
movd %eax, %mm0
|
||||
punpcklwd %mm0, %mm0
|
||||
punpckldq %mm0, %mm0
|
||||
|
||||
/*\ Load and unpack two pixels in parralel
|
||||
|*| %mm2 = ptr[0], %mm3 = ptr[1]
|
||||
\*/
|
||||
movq (%esi), %mm2
|
||||
movq %mm2, %mm3
|
||||
punpcklbw %mm7, %mm2
|
||||
punpckhbw %mm7, %mm3
|
||||
|
||||
/*\ X interpolation: r = l + (r - l) * xap \*/
|
||||
psubw %mm2, %mm3
|
||||
psllw $4, %mm3
|
||||
pmulhw %mm0, %mm3
|
||||
paddw %mm2, %mm3
|
||||
packuswb %mm3, %mm3
|
||||
movd %mm3, (%edi, %ecx, 4)
|
||||
jmp .up_up_1
|
||||
.up_up_0:
|
||||
/*\ dptr[x] = *sptr \*/
|
||||
movl (%esi), %eax
|
||||
movl %eax, (%edi, %ecx, 4)
|
||||
.up_up_1:
|
||||
incl %ecx
|
||||
jnz .up_up_loop2_x
|
||||
|
||||
.up_up_yap_end:
|
||||
/*\ dptr += dow \*/
|
||||
movl dow, %eax
|
||||
leal (%edi, %eax, 4), %edi
|
||||
/*\ yap++; yp++ \*/
|
||||
addl $4, yap
|
||||
addl $4, yp
|
||||
/*\ while (y--) \*/
|
||||
decl y
|
||||
jnz .up_up_loop_y
|
||||
|
||||
jmp .scale_leave
|
||||
|
||||
|
||||
/*\ Scaling down vertically \*/
|
||||
|
||||
.scale_x_up_y_down:
|
||||
/*\ sow_4 = sow * 4 \*/
|
||||
movl sow, %eax
|
||||
sall $2, %eax
|
||||
movl %eax, sow_4
|
||||
|
||||
.up_down_loop_y:
|
||||
|
||||
/*\ Setup My and Cy \*/
|
||||
movl yap, %eax
|
||||
movzwl (%eax), %ebx
|
||||
movl %ebx, My
|
||||
movzwl 2(%eax), %eax
|
||||
movl %eax, Cy
|
||||
|
||||
/*\ mm4 = Cy \*/
|
||||
movd %eax, %mm4
|
||||
punpcklwd %mm4, %mm4
|
||||
punpckldq %mm4, %mm4
|
||||
/*\ mm5 = My \*/
|
||||
movd %ebx, %mm5
|
||||
punpcklwd %mm5, %mm5
|
||||
punpckldq %mm5, %mm5
|
||||
|
||||
/*\ x = -dw \*/
|
||||
movl dw, %ecx
|
||||
negl %ecx
|
||||
.up_down_loop_x:
|
||||
/*\ %esi = *yp + xp[x] \*/
|
||||
movl yp, %eax
|
||||
movl (%eax), %esi
|
||||
movl xp, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
leal (%esi, %eax, 4), %esi
|
||||
|
||||
movl %esi, %eax
|
||||
/*\ v = (*p * My) >> 10 \*/
|
||||
movd (%eax), %mm0
|
||||
punpcklbw %mm7, %mm0
|
||||
psllw $6, %mm0
|
||||
pmulhw %mm5, %mm0
|
||||
|
||||
/*\ i = 0x4000 - My \*/
|
||||
movl $0x4000, %ebx
|
||||
subl My, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ p += sow; v += (*p * Cy) >> 10 \*/
|
||||
addl sow_4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm4, %mm1
|
||||
paddw %mm1, %mm0
|
||||
|
||||
/*\ i -= Cy; while (i > Cy) \*/
|
||||
subl Cy, %ebx
|
||||
2:
|
||||
cmpl Cy, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ mm6 = i \*/
|
||||
movd %ebx, %mm6
|
||||
punpcklwd %mm6, %mm6
|
||||
punpckldq %mm6, %mm6
|
||||
|
||||
/*\ p += sow; v += (*p * i) >> 10 \*/
|
||||
addl sow_4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm6, %mm1
|
||||
paddw %mm1, %mm0
|
||||
5:
|
||||
/*\ %eax = xap[x] << 5 \*/
|
||||
movl xap, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
sall $5, %eax
|
||||
jz 6f
|
||||
/*\ mm3 = xap[x] << 5 \*/
|
||||
movd %eax, %mm3
|
||||
punpcklwd %mm3, %mm3
|
||||
punpckldq %mm3, %mm3
|
||||
|
||||
/*\ p + 1 \*/
|
||||
movl %esi, %eax
|
||||
addl $4, %eax
|
||||
/*\ vv = (*p * My) >> 10 \*/
|
||||
movd (%eax), %mm2
|
||||
punpcklbw %mm7, %mm2
|
||||
psllw $6, %mm2
|
||||
pmulhw %mm5, %mm2
|
||||
|
||||
/*\ i = 0x4000 - My \*/
|
||||
movl $0x4000, %ebx
|
||||
subl My, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ p += sow; vv += (*p * Cy) >> 10 \*/
|
||||
addl sow_4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm4, %mm1
|
||||
paddw %mm1, %mm2
|
||||
|
||||
/*\ i -= Cy; while (i > Cy) \*/
|
||||
subl Cy, %ebx
|
||||
2:
|
||||
cmpl Cy, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ p += sow; v += (*p * i) >> 10 \*/
|
||||
addl sow_4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm6, %mm1
|
||||
paddw %mm1, %mm2
|
||||
5:
|
||||
/*\ v = v + (vv - v) * xap \*/
|
||||
psubw %mm0, %mm2
|
||||
psllw $3, %mm2
|
||||
pmulhw %mm3, %mm2
|
||||
paddw %mm2, %mm0
|
||||
6:
|
||||
/*\ dest[x] = v >> 4 \*/
|
||||
psrlw $4, %mm0
|
||||
packuswb %mm0, %mm0
|
||||
movd %mm0, (%edi, %ecx, 4)
|
||||
|
||||
/*\ while (++x) \*/
|
||||
incl %ecx
|
||||
jnz .up_down_loop_x
|
||||
|
||||
/*\ dptr += dow \*/
|
||||
movl dow, %eax
|
||||
leal (%edi, %eax, 4), %edi
|
||||
/*\ yap++; yp++ \*/
|
||||
addl $4, yap
|
||||
addl $4, yp
|
||||
/*\ while (y--) \*/
|
||||
decl y
|
||||
jnz .up_down_loop_y
|
||||
|
||||
jmp .scale_leave
|
||||
|
||||
.scale_x_down:
|
||||
/*\ Test yup bit \*/
|
||||
sarl $1, %eax
|
||||
jnc .scale_x_down_y_down
|
||||
|
||||
|
||||
/*\ Scaling down horizontally \*/
|
||||
|
||||
.scale_x_down_y_up:
|
||||
/*\ sow_4 = sow * 4 \*/
|
||||
movl sow, %eax
|
||||
sall $2, %eax
|
||||
movl %eax, sow_4
|
||||
|
||||
.down_up_loop_y:
|
||||
|
||||
/*\ %eax = *yap << 5 \*/
|
||||
movl yap, %eax
|
||||
movl (%eax), %eax
|
||||
sall $5, %eax
|
||||
/*\ mm3 = *yap << 5 \*/
|
||||
movd %eax, %mm3
|
||||
punpcklwd %mm3, %mm3
|
||||
punpckldq %mm3, %mm3
|
||||
|
||||
/*\ x = -dw \*/
|
||||
movl dw, %ecx
|
||||
negl %ecx
|
||||
.down_up_loop_x:
|
||||
/*\ %esi = *yp + xp[x] \*/
|
||||
movl yp, %eax
|
||||
movl (%eax), %esi
|
||||
movl xp, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
leal (%esi, %eax, 4), %esi
|
||||
|
||||
/*\ Setup Mx and Cx \*/
|
||||
movl xap, %eax
|
||||
movzwl (%eax, %ecx, 4), %ebx
|
||||
movl %ebx, Mx
|
||||
movzwl 2(%eax, %ecx, 4), %eax
|
||||
movl %eax, Cx
|
||||
|
||||
/*\ mm4 = Cx \*/
|
||||
movd %eax, %mm4
|
||||
punpcklwd %mm4, %mm4
|
||||
punpckldq %mm4, %mm4
|
||||
/*\ mm5 = Mx \*/
|
||||
movd %ebx, %mm5
|
||||
punpcklwd %mm5, %mm5
|
||||
punpckldq %mm5, %mm5
|
||||
|
||||
movl %esi, %eax
|
||||
/*\ v = (*p * Mx) >> 10 \*/
|
||||
movd (%eax), %mm0
|
||||
punpcklbw %mm7, %mm0
|
||||
psllw $6, %mm0
|
||||
pmulhw %mm5, %mm0
|
||||
|
||||
/*\ i = 0x4000 - Mx \*/
|
||||
movl $0x4000, %ebx
|
||||
subl Mx, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ p += sow; v += (*p * Cx) >> 10 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm4, %mm1
|
||||
paddw %mm1, %mm0
|
||||
|
||||
/*\ i -= Cx; while (i > Cx) \*/
|
||||
subl Cx, %ebx
|
||||
2:
|
||||
cmpl Cx, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ mm6 = i \*/
|
||||
movd %ebx, %mm6
|
||||
punpcklwd %mm6, %mm6
|
||||
punpckldq %mm6, %mm6
|
||||
|
||||
/*\ p += sow; v += (*p * i) >> 10 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm6, %mm1
|
||||
paddw %mm1, %mm0
|
||||
5:
|
||||
movd %mm3, %eax
|
||||
testl %eax, %eax
|
||||
jz 6f
|
||||
/*\ p + sow \*/
|
||||
movl %esi, %eax
|
||||
addl sow_4, %eax
|
||||
/*\ vv = (*p * Mx) >> 10 \*/
|
||||
movd (%eax), %mm2
|
||||
punpcklbw %mm7, %mm2
|
||||
psllw $6, %mm2
|
||||
pmulhw %mm5, %mm2
|
||||
|
||||
/*\ i = 0x4000 - Mx \*/
|
||||
movl $0x4000, %ebx
|
||||
subl Mx, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ p += sow; vv += (*p * Cx) >> 10 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm4, %mm1
|
||||
paddw %mm1, %mm2
|
||||
|
||||
/*\ i -= Cx; while (i > Cx) \*/
|
||||
subl Cx, %ebx
|
||||
2:
|
||||
cmpl Cx, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ p += sow; v += (*p * i) >> 10 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $6, %mm1
|
||||
pmulhw %mm6, %mm1
|
||||
paddw %mm1, %mm2
|
||||
5:
|
||||
/*\ v = v + (vv - v) * yap \*/
|
||||
psubw %mm0, %mm2
|
||||
psllw $3, %mm2
|
||||
pmulhw %mm3, %mm2
|
||||
paddw %mm2, %mm0
|
||||
6:
|
||||
/*\ dest[x] = v >> 4 \*/
|
||||
psrlw $4, %mm0
|
||||
packuswb %mm0, %mm0
|
||||
movd %mm0, (%edi, %ecx, 4)
|
||||
|
||||
/*\ while (++x) \*/
|
||||
incl %ecx
|
||||
jnz .down_up_loop_x
|
||||
|
||||
/*\ dptr += dow \*/
|
||||
movl dow, %eax
|
||||
leal (%edi, %eax, 4), %edi
|
||||
/*\ yap++; yp++ \*/
|
||||
addl $4, yap
|
||||
addl $4, yp
|
||||
/*\ while (y--) \*/
|
||||
decl y
|
||||
jnz .down_up_loop_y
|
||||
|
||||
jmp .scale_leave
|
||||
|
||||
|
||||
/*\ Scaling down both ways \*/
|
||||
|
||||
.scale_x_down_y_down:
|
||||
/*\ sow_4 = sow * 4 \*/
|
||||
movl sow, %eax
|
||||
sall $2, %eax
|
||||
movl %eax, sow_4
|
||||
|
||||
.down_down_loop_y:
|
||||
|
||||
/*\ Setup My and Cy \*/
|
||||
movl yap, %eax
|
||||
movzwl (%eax), %ebx
|
||||
movl %ebx, My
|
||||
movzwl 2(%eax), %eax
|
||||
movl %eax, Cy
|
||||
|
||||
/*\ x = -dw \*/
|
||||
movl dw, %ecx
|
||||
negl %ecx
|
||||
.down_down_loop_x:
|
||||
/*\ %esi = *yp + xp[x] \*/
|
||||
movl yp, %eax
|
||||
movl (%eax), %esi
|
||||
movl xp, %eax
|
||||
movl (%eax, %ecx, 4), %eax
|
||||
leal (%esi, %eax, 4), %esi
|
||||
|
||||
/*\ Setup Mx and Cx \*/
|
||||
movl xap, %eax
|
||||
movzwl (%eax, %ecx, 4), %ebx
|
||||
movl %ebx, Mx
|
||||
movzwl 2(%eax, %ecx, 4), %eax
|
||||
movl %eax, Cx
|
||||
|
||||
/*\ mm3 = Cx \*/
|
||||
movd %eax, %mm3
|
||||
punpcklwd %mm3, %mm3
|
||||
punpckldq %mm3, %mm3
|
||||
/*\ mm5 = Mx \*/
|
||||
movd %ebx, %mm5
|
||||
punpcklwd %mm5, %mm5
|
||||
punpckldq %mm5, %mm5
|
||||
|
||||
/*\ p = sptr; v = (*p * Mx) >> 9 \*/
|
||||
movl %esi, %eax
|
||||
movd (%eax), %mm0
|
||||
punpcklbw %mm7, %mm0
|
||||
psllw $7, %mm0
|
||||
pmulhw %mm5, %mm0
|
||||
|
||||
/*\ i = 0x4000 - Mx \*/
|
||||
movl $0x4000, %ebx
|
||||
subl Mx, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ v += (*++p * Cx) >> 9 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $7, %mm1
|
||||
pmulhw %mm3, %mm1
|
||||
paddw %mm1, %mm0
|
||||
|
||||
/*\ i -= Cx; while (i > Cx) \*/
|
||||
subl Cx, %ebx
|
||||
2:
|
||||
cmpl Cx, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ mm6 = i \*/
|
||||
movd %ebx, %mm6
|
||||
punpcklwd %mm6, %mm6
|
||||
punpckldq %mm6, %mm6
|
||||
|
||||
/*\ v += (*++p * i) >> 9 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $7, %mm1
|
||||
pmulhw %mm6, %mm1
|
||||
paddw %mm1, %mm0
|
||||
5:
|
||||
/*\ v *= My \*/
|
||||
movd My, %mm4
|
||||
punpcklwd %mm4, %mm4
|
||||
punpckldq %mm4, %mm4
|
||||
psllw $2, %mm0
|
||||
pmulhw %mm4, %mm0
|
||||
|
||||
/*\ j = 0x4000 - My \*/
|
||||
movl $0x4000, %edx
|
||||
subl My, %edx
|
||||
jbe 6f
|
||||
jmp 4f
|
||||
3:
|
||||
/*\ sptr += sow; p = sptr \*/
|
||||
addl sow_4, %esi
|
||||
movl %esi, %eax
|
||||
/*\ vx = (*p * Mx) >> 9 \*/
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $7, %mm1
|
||||
pmulhw %mm5, %mm1
|
||||
|
||||
/*\ i = 0x4000 - Mx \*/
|
||||
movl $0x4000, %ebx
|
||||
subl Mx, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ vx += (*++p * Cx) >> 9 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm2
|
||||
punpcklbw %mm7, %mm2
|
||||
psllw $7, %mm2
|
||||
pmulhw %mm3, %mm2
|
||||
paddw %mm2, %mm1
|
||||
|
||||
/*\ i -= Cx; while (i > Cx) \*/
|
||||
subl Cx, %ebx
|
||||
2:
|
||||
cmpl Cx, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ vx += (*++p * i) >> 9 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm2
|
||||
punpcklbw %mm7, %mm2
|
||||
psllw $7, %mm2
|
||||
pmulhw %mm6, %mm2
|
||||
paddw %mm2, %mm1
|
||||
5:
|
||||
/*\ v += (vx * Cy) >> 14 \*/
|
||||
movd Cy, %mm4
|
||||
punpcklwd %mm4, %mm4
|
||||
punpckldq %mm4, %mm4
|
||||
psllw $2, %mm1
|
||||
pmulhw %mm4, %mm1
|
||||
paddw %mm1, %mm0
|
||||
|
||||
/*\ j -= Cy; while (j > Cy) \*/
|
||||
subl Cy, %edx
|
||||
4:
|
||||
cmpl Cy, %edx
|
||||
jg 3b
|
||||
|
||||
/*\ sptr += sow; p = sptr \*/
|
||||
addl sow_4, %esi
|
||||
movl %esi, %eax
|
||||
/*\ vx = (*p * Mx) >> 9 \*/
|
||||
movd (%eax), %mm1
|
||||
punpcklbw %mm7, %mm1
|
||||
psllw $7, %mm1
|
||||
pmulhw %mm5, %mm1
|
||||
|
||||
/*\ i = 0x4000 - Mx \*/
|
||||
movl $0x4000, %ebx
|
||||
subl Mx, %ebx
|
||||
jbe 5f
|
||||
jmp 2f
|
||||
1:
|
||||
/*\ vx += (*++p * Cx) >> 9 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm2
|
||||
punpcklbw %mm7, %mm2
|
||||
psllw $7, %mm2
|
||||
pmulhw %mm3, %mm2
|
||||
paddw %mm2, %mm1
|
||||
|
||||
/*\ i -= Cx; while (i > Cx) \*/
|
||||
subl Cx, %ebx
|
||||
2:
|
||||
cmpl Cx, %ebx
|
||||
jg 1b
|
||||
|
||||
/*\ vx += (*++p * i) >> 9 \*/
|
||||
addl $4, %eax
|
||||
movd (%eax), %mm2
|
||||
punpcklbw %mm7, %mm2
|
||||
psllw $7, %mm2
|
||||
pmulhw %mm6, %mm2
|
||||
paddw %mm2, %mm1
|
||||
5:
|
||||
/*\ v += (vx * j) >> 14 \*/
|
||||
movd %edx, %mm4
|
||||
punpcklwd %mm4, %mm4
|
||||
punpckldq %mm4, %mm4
|
||||
psllw $2, %mm1
|
||||
pmulhw %mm4, %mm1
|
||||
paddw %mm1, %mm0
|
||||
6:
|
||||
/*\ dptr[x] = mm0 >> 5 \*/
|
||||
psrlw $5, %mm0
|
||||
packuswb %mm0, %mm0
|
||||
movd %mm0, (%edi, %ecx, 4)
|
||||
|
||||
/*\ while (++x) \*/
|
||||
incl %ecx
|
||||
jnz .down_down_loop_x
|
||||
|
||||
/*\ dptr += dow \*/
|
||||
movl dow, %eax
|
||||
leal (%edi, %eax, 4), %edi
|
||||
/*\ yap++; yp++ \*/
|
||||
addl $4, yap
|
||||
addl $4, yp
|
||||
/*\ while (y--) \*/
|
||||
decl y
|
||||
jnz .down_down_loop_y
|
||||
|
||||
jmp .scale_leave
|
||||
|
||||
.scale_leave:
|
||||
emms
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
SIZE(imlib_Scale_mmx_AARGBA)
|
||||
|
||||
#endif
|
1820
src/blend.c
1820
src/blend.c
File diff suppressed because it is too large
Load Diff
556
src/blend.h
556
src/blend.h
|
@ -1,556 +0,0 @@
|
|||
#ifndef __BLEND
|
||||
#define __BLEND 1
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
|
||||
#define A_VAL(p) ((DATA8 *)(p))[3]
|
||||
#define R_VAL(p) ((DATA8 *)(p))[2]
|
||||
#define G_VAL(p) ((DATA8 *)(p))[1]
|
||||
#define B_VAL(p) ((DATA8 *)(p))[0]
|
||||
|
||||
#else
|
||||
|
||||
#define A_VAL(p) ((DATA8 *)(p))[0]
|
||||
#define R_VAL(p) ((DATA8 *)(p))[1]
|
||||
#define G_VAL(p) ((DATA8 *)(p))[2]
|
||||
#define B_VAL(p) ((DATA8 *)(p))[3]
|
||||
|
||||
#endif
|
||||
|
||||
/* FIXME: endian dependant */
|
||||
#define READ_RGB(p, r, g, b) \
|
||||
(r) = R_VAL(p); \
|
||||
(g) = G_VAL(p); \
|
||||
(b) = B_VAL(p);
|
||||
|
||||
#define READ_ALPHA(p, a) \
|
||||
(a) = A_VAL(p);
|
||||
|
||||
#define READ_RGBA(p, r, g, b, a) \
|
||||
(r) = R_VAL(p); \
|
||||
(g) = G_VAL(p); \
|
||||
(b) = B_VAL(p); \
|
||||
(a) = A_VAL(p);
|
||||
|
||||
#define WRITE_RGB(p, r, g, b) \
|
||||
R_VAL(p) = (r); \
|
||||
G_VAL(p) = (g); \
|
||||
B_VAL(p) = (b);
|
||||
|
||||
#define WRITE_RGB_PRESERVE_ALPHA(p, r, g, b) \
|
||||
WRITE_RGB(p, r, g, b)
|
||||
|
||||
#define WRITE_RGBA(p, r, g, b, a) \
|
||||
R_VAL(p) = (r); \
|
||||
G_VAL(p) = (g); \
|
||||
B_VAL(p) = (b); \
|
||||
A_VAL(p) = (a);
|
||||
|
||||
#define INTERSECTS(x, y, w, h, xx, yy, ww, hh) \
|
||||
((x < (xx + ww)) && \
|
||||
(y < (yy + hh)) && \
|
||||
((x + w) > xx) && \
|
||||
((y + h) > yy))
|
||||
|
||||
#define CLIP_TO(_x, _y, _w, _h, _cx, _cy, _cw, _ch) \
|
||||
{ \
|
||||
if (INTERSECTS(_x, _y, _w, _h, _cx, _cy, _cw, _ch)) \
|
||||
{ \
|
||||
if (_x < _cx) \
|
||||
{ \
|
||||
_w += _x - _cx; \
|
||||
_x = _cx; \
|
||||
if (_w < 0) _w = 0; \
|
||||
} \
|
||||
if ((_x + _w) > (_cx + _cw)) \
|
||||
_w = _cx + _cw - _x; \
|
||||
if (_y < _cy) \
|
||||
{ \
|
||||
_h += _y - _cy; \
|
||||
_y = _cy; \
|
||||
if (_h < 0) _h = 0; \
|
||||
} \
|
||||
if ((_y + _h) > (_cy + _ch)) \
|
||||
_h = _cy + _ch - _y; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_w = 0; _h = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) Basic Saturation - 8 bit unsigned
|
||||
*
|
||||
* The add, subtract, and reshade operations generate new color values that may
|
||||
* be out of range for an unsigned 8 bit quantity. Therefore, we will want to
|
||||
* saturate the values into the range [0, 255]. Any value < 0 will become 0,
|
||||
* and any value > 255 will become 255. Or simply:
|
||||
*
|
||||
* saturated = (value < 0) ? 0 : ((value > 255) ? 255 : value)
|
||||
*
|
||||
* Of course the above isn't the most efficient means of saturating. Sometimes
|
||||
* due to the nature of a calculation, we know we only need to saturate from
|
||||
* above (> 255) or just from below (< 0). Or simply:
|
||||
*
|
||||
* saturated = (value < 0) ? 0 : value
|
||||
* saturated = (value > 255) ? 255 : value
|
||||
*
|
||||
* 2) Alternate Forms of Saturation
|
||||
*
|
||||
* The methods of saturation described above use testing/branching operations,
|
||||
* which are not necessarily efficient on all platforms. There are other means
|
||||
* of performing saturation using just simple arithmetic operations
|
||||
* (+, -, >>, <<, ~). A discussion of these saturation techniques follows.
|
||||
*
|
||||
* A) Saturation in the range [0, 512), or "from above".
|
||||
*
|
||||
* Assuming we have an integral value in the range [0, 512), the following
|
||||
* formula evaluates to either 0, or 255:
|
||||
*
|
||||
* (value & 255) - ((value & 256) >> 8)
|
||||
*
|
||||
* This is easy to show. Notice that if the value is in the range [0, 256)
|
||||
* the 9th bit is 0, and we get (0 - 0), which is 0. And if the value is in
|
||||
* the range [256, 512) the 9th bit is 1, and we get (256 - 1), which is 255.
|
||||
*
|
||||
* Now, using the above information and the fact that assigning an integer to
|
||||
* an 8 bit unsigned value will truncate to the lower 8 bits of the integer,
|
||||
* the following properly saturates:
|
||||
*
|
||||
* 8bit_value = value | (value & 256) - ((value & 256) >> 8)
|
||||
*
|
||||
* To prove this to yourself, just think about what the lower 8 bits look like
|
||||
* in the ranges [0, 256) and [256, 512). In particular, notice that the value
|
||||
* in the range [0, 256) are unchanged, and values in the range [256, 512)
|
||||
* always give you 255. Just what we want!
|
||||
*
|
||||
* B) Saturation in the range (-256, 256), or "from below".
|
||||
*
|
||||
* Assuming we have an integral value in the range (-256, 256), the following
|
||||
* formula evaluates to either 0, or -1:
|
||||
*
|
||||
* ~(value >> 8)
|
||||
*
|
||||
* Here's why. If the value is in the range [0, 256), then shifting right by
|
||||
* 8 bits gives us all 0 bits, or 0. And thus inverting the bits gives all
|
||||
* 1 bits, which is -1. If the value is in the range (-256, 0), then the 9th
|
||||
* bit and higher bits are all 1. So, when we shift right by 8 bits (with
|
||||
* signed extension), we get a value with all 1 bits. Which when inverted is
|
||||
* all 0 bits, or 0.
|
||||
*
|
||||
* Now, using the above information the following properly saturates:
|
||||
*
|
||||
* 8bit_value = value & (~(value >> 8))
|
||||
*
|
||||
* To prove this to yourself, noticed that values in the range (-256, 0) will
|
||||
* always be AND'd with 0, and thus map to 0. Further, values in the range
|
||||
* [0, 256) will always be AND'd with a value that is all 1 bits, and thus
|
||||
* be unchanged. Just what we want!
|
||||
*
|
||||
* C) Saturation in the range (-256, 512), or "from above and below".
|
||||
*
|
||||
* The short of it is the following works:
|
||||
*
|
||||
* 8bit_value = (tmp | ((tmp & 256) - ((tmp & 256) >> 8))) & (~(tmp >> 9))
|
||||
*
|
||||
* We leave it to the reader to prove. Looks very similar to the techniques
|
||||
* used above, eh? :)
|
||||
*/
|
||||
|
||||
/* Saturate values in the range [0, 512) */
|
||||
#define SATURATE_UPPER(nc, v) \
|
||||
tmp = (v); \
|
||||
nc = (tmp | (-(tmp >> 8)));
|
||||
|
||||
/* Saturate values in the range (-256, 256) */
|
||||
#define SATURATE_LOWER(nc, v) \
|
||||
tmp = (v); \
|
||||
nc = tmp & (~(tmp >> 8));
|
||||
|
||||
/* Saturate values in the range (-256, 512) */
|
||||
#define SATURATE_BOTH(nc, v) \
|
||||
tmp = (v); \
|
||||
nc = (tmp | (-(tmp >> 8))) & (~(tmp >> 9));
|
||||
|
||||
/*
|
||||
* 1) Operations
|
||||
*
|
||||
* There are 4 operations supported:
|
||||
*
|
||||
* Copy, Add, Subtract, and Reshade
|
||||
*
|
||||
* For each operation there are 3 different variations that can be made:
|
||||
*
|
||||
* a) Use "blend" or "copy" in the calculations? A "blend" uses the alpha
|
||||
* value of the source pixel to lighten the source pixel values. Where
|
||||
* as "copy" ignores the alpha value and uses the raw source pixel values.
|
||||
* b) Include source alpha in the calculation for new destination alpha?
|
||||
* If source alpha is not used, then destination alpha is preserved.
|
||||
* If source alpha is used, a "copy" sets the new alpha to the source
|
||||
* alpha, and a "blend" increases it by a factor given by the product
|
||||
* of the source alpha with one minus the destination alpha.
|
||||
* c) Should the source pixels be passed through a color modifier before the
|
||||
* calculations are performed?
|
||||
*
|
||||
* All together we have 4*2*2*2 = 32 combinations.
|
||||
*
|
||||
* 2) Copy operation
|
||||
*
|
||||
* The "copy" version of this operation copies the source image onto the
|
||||
* destination image.
|
||||
*
|
||||
* The "blend" version of this operation blends the source image color 'c' with
|
||||
* the destination image color 'cc' using 'a' (in the range [0, 1]) according
|
||||
* to the following formula. Also notice that saturation is not needed for
|
||||
* this calculation, the output is in the range [0, 255]:
|
||||
*
|
||||
* nc = c * alpha + (1 - alpha) * cc
|
||||
* = c * alpha - cc * alpha + cc
|
||||
* = (c - cc) * alpha + cc;
|
||||
*
|
||||
* A discussion of how we're calculating this value follows:
|
||||
*
|
||||
* We're using 'a', an integer, in the range [0, 255] for alpha (and for 'c'
|
||||
* and 'cc', BTW). Therefore, we need to slightly modify the equation to take
|
||||
* that into account. To get into the range [0, 255] we need to divide 'a'
|
||||
* by 255:
|
||||
*
|
||||
* nc = ((c - cc) * a) / 255 + cc
|
||||
*
|
||||
* Notice that it is faster to divide by 256 (bit shifting), however without a
|
||||
* fudge factor 'x' to balance things this isn't horribly accurate. So, let's
|
||||
* solve for 'x'. The equality is:
|
||||
*
|
||||
* ((c - cc) * a) / 256 + cc + x = ((c - cc) * a) / 255 + cc
|
||||
*
|
||||
* The 'cc' terms cancel, and multiply both sides by 255*256 to remove the
|
||||
* fractions:
|
||||
*
|
||||
* ((c - cc) * a) * 255 + 255 * 256 * x = ((c - cc) * a) * 256
|
||||
*
|
||||
* Get the 'x' term alone:
|
||||
*
|
||||
* 255 * 256 * x = ((c - cc) * a)
|
||||
*
|
||||
* Divide both sides by 255 * 256 to solve for 'x':
|
||||
*
|
||||
* x = ((c - cc) * a) / (255 * 256)
|
||||
*
|
||||
* And putting 'x' back into the equation we get:
|
||||
*
|
||||
* nc = ((c - cc) * a) / 256 + cc + ((c - cc) * a) / (255 * 256)
|
||||
*
|
||||
* And if we let 'tmp' represent the value '(c - cc) * a', and do a little
|
||||
* regrouping we get:
|
||||
*
|
||||
* nc = tmp / 256 + tmp / (255 * 256) + cc
|
||||
* = (tmp + tmp / 255) / 256 + cc
|
||||
*
|
||||
* We'll be using integer arithmetic, and over the range of values tmp takes
|
||||
* (in [-255*255, 255*255]) the term tmp/(255*256) is pretty much the same as
|
||||
* tmp/(256*256). So we get:
|
||||
*
|
||||
* nc = (tmp + tmp / 256) / 256 + cc
|
||||
*
|
||||
* And because the division of the sum uses integer arithmetic, it always
|
||||
* rounds up/down even if that isn't the "best" choice. If we add .5 to the
|
||||
* sum, we can get standard rounding: Like so:
|
||||
*
|
||||
* nc = (tmp + tmp / 256 + 128) / 256 + cc
|
||||
*
|
||||
* 3) Add operation
|
||||
*
|
||||
* The "copy" version of this operation sums the source image pixel values
|
||||
* with the destination image pixel values, saturating at 255 (from above).
|
||||
*
|
||||
* The "blend" version of this operation sums the source image pixel values,
|
||||
* after taking into account alpha transparency (e.g. a percentage), with the
|
||||
* destination image pixel values, saturating at 255 (from above).
|
||||
*
|
||||
* 4) Subtract operation
|
||||
*
|
||||
* This operation is the same as the Add operation, except the source values
|
||||
* are subtracted from the destination values (instead of added). Further,
|
||||
* the result must be saturated at 0 (from below).
|
||||
*
|
||||
* 5) Reshade operation
|
||||
*
|
||||
* This operation uses the source image color values to lighten/darken color
|
||||
* values in the destination image using the following formula:
|
||||
*
|
||||
* nc = cc + ((c - middle_value) * 2 * alpha)
|
||||
*
|
||||
* Recall our pixel color and alpha values are in the range [0, 255]. So, the
|
||||
* "blend" version of this operation can be calculated as:
|
||||
*
|
||||
* nc = cc + ((c - 127) * 2 * (a / 255))
|
||||
*
|
||||
* And in an integer arithmetic friendly form is:
|
||||
*
|
||||
* nc = cc + (((c - 127) * a) >> 7)
|
||||
*
|
||||
* The "copy" version of this operation treats alpha as 1.0 (or a/255), and in
|
||||
* integer arithmetic friendly form is:
|
||||
*
|
||||
* nc = cc + ((c - 127) << 1)
|
||||
*
|
||||
* Notice the color values created by this operation are in the range
|
||||
* (-256, 512), and thus must be saturated at 0 and 255 (from above and below).
|
||||
*
|
||||
* For all the operations, when the "blend" version involves computing new
|
||||
* destination alpha values via the use of some source alpha, we have that:
|
||||
*
|
||||
* nalpha = alpha + ((255 - alpha) * (a / 255))
|
||||
*
|
||||
* We can use the previous argument for approximating division by 255, and
|
||||
* calculate this by:
|
||||
*
|
||||
* tmp = (255 - alpha) * a;
|
||||
* nalpha = alpha + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||
*
|
||||
* This is again in the range [0, 255], so no saturation is needed.
|
||||
*/
|
||||
|
||||
#define BLEND_COLOR(a, nc, c, cc) \
|
||||
tmp = ((c) - (cc)) * (a); \
|
||||
nc = (cc) + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||
|
||||
#define ADD_COLOR_WITH_ALPHA(a, nc, c, cc) \
|
||||
tmp = (c) * (a); \
|
||||
tmp = (cc) + ((tmp + (tmp >> 8) + 0x80) >> 8); \
|
||||
nc = (tmp | (-(tmp >> 8)));
|
||||
|
||||
#define ADD_COLOR(nc, c, cc) \
|
||||
tmp = (cc) + (c); \
|
||||
nc = (tmp | (-(tmp >> 8)));
|
||||
|
||||
#define SUB_COLOR_WITH_ALPHA(a, nc, c, cc) \
|
||||
tmp = (c) * (a); \
|
||||
tmp = (cc) - ((tmp + (tmp >> 8) + 0x80) >> 8); \
|
||||
nc = (tmp & (~(tmp >> 8)));
|
||||
|
||||
#define SUB_COLOR(nc, c, cc) \
|
||||
tmp = (cc) - (c); \
|
||||
nc = (tmp & (~(tmp >> 8)));
|
||||
|
||||
#define RESHADE_COLOR_WITH_ALPHA(a, nc, c, cc) \
|
||||
tmp = (cc) + ((((c) - 127) * (a)) >> 7); \
|
||||
nc = (tmp | (-(tmp >> 8))) & (~(tmp >> 9));
|
||||
|
||||
#define RESHADE_COLOR(nc, c, cc) \
|
||||
tmp = (cc) + (((c) - 127) << 1); \
|
||||
nc = (tmp | (-(tmp >> 8))) & (~(tmp >> 9));
|
||||
|
||||
extern int pow_lut_initialized;
|
||||
extern DATA8 pow_lut[256][256];
|
||||
|
||||
#define BLEND_DST_ALPHA(r1, g1, b1, a1, dest) \
|
||||
{ DATA8 _aa; \
|
||||
_aa = pow_lut[a1][A_VAL(dest)]; \
|
||||
BLEND_COLOR(a1, A_VAL(dest), 255, A_VAL(dest)); \
|
||||
BLEND_COLOR(_aa, R_VAL(dest), r1, R_VAL(dest)); \
|
||||
BLEND_COLOR(_aa, G_VAL(dest), g1, G_VAL(dest)); \
|
||||
BLEND_COLOR(_aa, B_VAL(dest), b1, B_VAL(dest)); \
|
||||
}
|
||||
|
||||
#define BLEND(r1, g1, b1, a1, dest) \
|
||||
BLEND_COLOR(a1, R_VAL(dest), r1, R_VAL(dest)); \
|
||||
BLEND_COLOR(a1, G_VAL(dest), g1, G_VAL(dest)); \
|
||||
BLEND_COLOR(a1, B_VAL(dest), b1, B_VAL(dest));
|
||||
|
||||
#define BLEND_ADD(r1, g1, b1, a1, dest) \
|
||||
ADD_COLOR_WITH_ALPHA(a1, R_VAL(dest), r1, R_VAL(dest)); \
|
||||
ADD_COLOR_WITH_ALPHA(a1, G_VAL(dest), g1, G_VAL(dest)); \
|
||||
ADD_COLOR_WITH_ALPHA(a1, B_VAL(dest), b1, B_VAL(dest));
|
||||
|
||||
#define BLEND_SUB(r1, g1, b1, a1, dest) \
|
||||
SUB_COLOR_WITH_ALPHA(a1, R_VAL(dest), r1, R_VAL(dest)); \
|
||||
SUB_COLOR_WITH_ALPHA(a1, G_VAL(dest), g1, G_VAL(dest)); \
|
||||
SUB_COLOR_WITH_ALPHA(a1, B_VAL(dest), b1, B_VAL(dest));
|
||||
|
||||
#define BLEND_RE(r1, g1, b1, a1, dest) \
|
||||
RESHADE_COLOR_WITH_ALPHA(a1, R_VAL(dest), r1, R_VAL(dest)); \
|
||||
RESHADE_COLOR_WITH_ALPHA(a1, G_VAL(dest), g1, G_VAL(dest)); \
|
||||
RESHADE_COLOR_WITH_ALPHA(a1, B_VAL(dest), b1, B_VAL(dest));
|
||||
|
||||
enum _imlibop
|
||||
{
|
||||
OP_COPY,
|
||||
OP_ADD,
|
||||
OP_SUBTRACT,
|
||||
OP_RESHADE
|
||||
};
|
||||
|
||||
typedef enum _imlibop ImlibOp;
|
||||
|
||||
typedef void (*ImlibBlendFunction)(DATA32*, int, DATA32*, int, int, int,
|
||||
ImlibColorModifier *);
|
||||
|
||||
ImlibBlendFunction
|
||||
__imlib_GetBlendFunction(ImlibOp op, char merge_alpha, char blend, char rgb_src,
|
||||
ImlibColorModifier * cm);
|
||||
void
|
||||
__imlib_BlendImageToImage(ImlibImage *im_src, ImlibImage *im_dst,
|
||||
char aa, char blend, char merge_alpha,
|
||||
int ssx, int ssy, int ssw, int ssh,
|
||||
int ddx, int ddy, int ddw, int ddh,
|
||||
ImlibColorModifier *cm, ImlibOp op,
|
||||
int clx, int cly, int clw, int clh);
|
||||
void
|
||||
__imlib_BlendRGBAToData(DATA32 *src, int src_w, int src_h, DATA32 *dst,
|
||||
int dst_w, int dst_h, int sx, int sy, int dx, int dy,
|
||||
int w, int h, char blend, char merge_alpha,
|
||||
ImlibColorModifier *cm, ImlibOp op, char rgb_src);
|
||||
void
|
||||
__imlib_build_pow_lut(void);
|
||||
|
||||
#ifdef DO_MMX_ASM
|
||||
void
|
||||
__imlib_mmx_blend_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_blend_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_copy_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_copy_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_copy_rgb_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_blend_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_blend_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_copy_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_copy_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_copy_rgb_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_blend_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_blend_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_copy_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_copy_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_copy_rgb_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_blend_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_blend_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_copy_rgba_to_rgb(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_copy_rgba_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_copy_rgb_to_rgba(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
|
||||
void
|
||||
__imlib_mmx_blend_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_blend_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_blend_rgb_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_blend_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_copy_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_copy_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_copy_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_blend_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_blend_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_blend_rgb_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_blend_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_copy_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_copy_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_add_copy_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_blend_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_blend_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_blend_rgb_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_blend_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_copy_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_copy_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_subtract_copy_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_blend_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_blend_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_blend_rgb_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_blend_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_copy_rgba_to_rgb_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_copy_rgba_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
void
|
||||
__imlib_mmx_reshade_copy_rgb_to_rgba_cmod(DATA32 *src, int sw, DATA32 *dst,
|
||||
int dw, int w, int h, ImlibColorModifier *cm);
|
||||
|
||||
#endif
|
||||
#endif
|
569
src/color.c
569
src/color.c
|
@ -1,569 +0,0 @@
|
|||
#include "common.h"
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include "color.h"
|
||||
#endif
|
||||
|
||||
DATA8 _pal_type = 0;
|
||||
DATA16 _max_colors = 256;
|
||||
|
||||
int
|
||||
__imlib_XActualDepth(Display * d, Visual * v)
|
||||
{
|
||||
XVisualInfo xvi, *xvir;
|
||||
int depth = 0, num;
|
||||
|
||||
xvi.visual = v;
|
||||
xvi.visualid = XVisualIDFromVisual(v);
|
||||
xvir = XGetVisualInfo(d, VisualIDMask, &xvi, &num);
|
||||
if (xvir)
|
||||
{
|
||||
depth = xvir[0].depth;
|
||||
if ((depth == 16) &&
|
||||
((xvir->red_mask | xvir->green_mask | xvir->blue_mask) == 0x7fff))
|
||||
depth = 15;
|
||||
XFree(xvir);
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
Visual *
|
||||
__imlib_BestVisual(Display * d, int screen, int *depth_return)
|
||||
{
|
||||
XVisualInfo xvi, *xvir;
|
||||
int j, i, num, maxd = 0;
|
||||
Visual *v = NULL;
|
||||
const int visprefs[] =
|
||||
{ PseudoColor, TrueColor, DirectColor, StaticColor, GrayScale,
|
||||
StaticGray };
|
||||
|
||||
xvi.screen = screen;
|
||||
maxd = 0;
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
xvi.class = visprefs[j];
|
||||
xvir = XGetVisualInfo(d, VisualScreenMask | VisualClassMask,
|
||||
&xvi, &num);
|
||||
if (xvir)
|
||||
{
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if ((xvir[i].depth > 1) &&
|
||||
(xvir[i].depth >= maxd) && (xvi.class == PseudoColor))
|
||||
{
|
||||
maxd = xvir[i].depth;
|
||||
v = xvir[i].visual;
|
||||
}
|
||||
else if ((xvir[i].depth > maxd) && (xvir[i].depth <= 24))
|
||||
{
|
||||
maxd = xvir[i].depth;
|
||||
v = xvir[i].visual;
|
||||
}
|
||||
}
|
||||
XFree(xvir);
|
||||
}
|
||||
}
|
||||
if (depth_return)
|
||||
*depth_return = maxd;
|
||||
return v;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColorTable(Display * d, Colormap cmap, DATA8 * type_return,
|
||||
Visual * v)
|
||||
{
|
||||
DATA8 *color_lut = NULL;
|
||||
|
||||
if (v->bits_per_rgb > 1)
|
||||
{
|
||||
if ((_max_colors >= 256)
|
||||
&& (color_lut = __imlib_AllocColors332(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
if ((_max_colors >= 216)
|
||||
&& (color_lut = __imlib_AllocColors666(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
if ((_max_colors >= 128)
|
||||
&& (color_lut = __imlib_AllocColors232(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
if ((_max_colors >= 64)
|
||||
&& (color_lut = __imlib_AllocColors222(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
if ((_max_colors >= 32)
|
||||
&& (color_lut = __imlib_AllocColors221(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
if ((_max_colors >= 16)
|
||||
&& (color_lut = __imlib_AllocColors121(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
}
|
||||
if ((_max_colors >= 8) && (color_lut = __imlib_AllocColors111(d, cmap, v)))
|
||||
{
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
color_lut = __imlib_AllocColors1(d, cmap, v);
|
||||
*type_return = _pal_type;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors332(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(256 * sizeof(DATA8));
|
||||
for (r = 0; r < 8; r++)
|
||||
{
|
||||
for (g = 0; g < 8; g++)
|
||||
{
|
||||
for (b = 0; b < 4; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val = (r << 6) | (r << 3) | (r);
|
||||
xcl.red = (unsigned short)((val << 7) | (val >> 2));
|
||||
val = (g << 6) | (g << 3) | (g);
|
||||
xcl.green = (unsigned short)((val << 7) | (val >> 2));
|
||||
val = (b << 6) | (b << 4) | (b << 2) | (b);
|
||||
xcl.blue = (unsigned short)((val << 8) | (val));
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 0;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors666(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(256 * sizeof(DATA8));
|
||||
for (r = 0; r < 6; r++)
|
||||
{
|
||||
for (g = 0; g < 6; g++)
|
||||
{
|
||||
for (b = 0; b < 6; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val = (int)((((double)r) / 5.0) * 65535);
|
||||
xcl.red = (unsigned short)(val);
|
||||
val = (int)((((double)g) / 5.0) * 65535);
|
||||
xcl.green = (unsigned short)(val);
|
||||
val = (int)((((double)b) / 5.0) * 65535);
|
||||
xcl.blue = (unsigned short)(val);
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 7;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors232(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(128 * sizeof(DATA8));
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (g = 0; g < 8; g++)
|
||||
{
|
||||
for (b = 0; b < 4; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val = (r << 6) | (r << 4) | (r << 2) | (r);
|
||||
xcl.red = (unsigned short)((val << 8) | (val));
|
||||
val = (g << 6) | (g << 3) | (g);
|
||||
xcl.green = (unsigned short)((val << 7) | (val >> 2));
|
||||
val = (b << 6) | (b << 4) | (b << 2) | (b);
|
||||
xcl.blue = (unsigned short)((val << 8) | (val));
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 1;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors222(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(64 * sizeof(DATA8));
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (g = 0; g < 4; g++)
|
||||
{
|
||||
for (b = 0; b < 4; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val = (r << 6) | (r << 4) | (r << 2) | (r);
|
||||
xcl.red = (unsigned short)((val << 8) | (val));
|
||||
val = (g << 6) | (g << 4) | (g << 2) | (g);
|
||||
xcl.green = (unsigned short)((val << 8) | (val));
|
||||
val = (b << 6) | (b << 4) | (b << 2) | (b);
|
||||
xcl.blue = (unsigned short)((val << 8) | (val));
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 2;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors221(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(32 * sizeof(DATA8));
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (g = 0; g < 4; g++)
|
||||
{
|
||||
for (b = 0; b < 2; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val = (r << 6) | (r << 4) | (r << 2) | (r);
|
||||
xcl.red = (unsigned short)((val << 8) | (val));
|
||||
val = (g << 6) | (g << 4) | (g << 2) | (g);
|
||||
xcl.green = (unsigned short)((val << 8) | (val));
|
||||
val =
|
||||
(b << 7) | (b << 6) | (b << 5) | (b << 4) | (b << 3) | (b
|
||||
<<
|
||||
2)
|
||||
| (b << 1) | (b);
|
||||
xcl.blue = (unsigned short)((val << 8) | (val));
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 3;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors121(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(16 * sizeof(DATA8));
|
||||
for (r = 0; r < 2; r++)
|
||||
{
|
||||
for (g = 0; g < 4; g++)
|
||||
{
|
||||
for (b = 0; b < 2; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val =
|
||||
(r << 7) | (r << 6) | (r << 5) | (r << 4) | (r << 3) | (r
|
||||
<<
|
||||
2)
|
||||
| (r << 1) | (r);
|
||||
xcl.red = (unsigned short)((val << 8) | (val));
|
||||
val = (g << 6) | (g << 4) | (g << 2) | (g);
|
||||
xcl.green = (unsigned short)((val << 8) | (val));
|
||||
val =
|
||||
(b << 7) | (b << 6) | (b << 5) | (b << 4) | (b << 3) | (b
|
||||
<<
|
||||
2)
|
||||
| (b << 1) | (b);
|
||||
xcl.blue = (unsigned short)((val << 8) | (val));
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 4;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors111(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
int r, g, b, i;
|
||||
DATA8 *color_lut;
|
||||
int sig_mask = 0;
|
||||
|
||||
for (i = 0; i < v->bits_per_rgb; i++)
|
||||
sig_mask |= (0x1 << i);
|
||||
sig_mask <<= (16 - v->bits_per_rgb);
|
||||
i = 0;
|
||||
color_lut = malloc(8 * sizeof(DATA8));
|
||||
for (r = 0; r < 2; r++)
|
||||
{
|
||||
for (g = 0; g < 2; g++)
|
||||
{
|
||||
for (b = 0; b < 2; b++)
|
||||
{
|
||||
XColor xcl;
|
||||
XColor xcl_in;
|
||||
int val;
|
||||
Status ret;
|
||||
|
||||
val =
|
||||
(r << 7) | (r << 6) | (r << 5) | (r << 4) | (r << 3) | (r
|
||||
<<
|
||||
2)
|
||||
| (r << 1) | (r);
|
||||
xcl.red = (unsigned short)((val << 8) | (val));
|
||||
val =
|
||||
(g << 7) | (g << 6) | (g << 5) | (g << 4) | (g << 3) | (g
|
||||
<<
|
||||
2)
|
||||
| (g << 1) | (g);
|
||||
xcl.green = (unsigned short)((val << 8) | (val));
|
||||
val =
|
||||
(b << 7) | (b << 6) | (b << 5) | (b << 4) | (b << 3) | (b
|
||||
<<
|
||||
2)
|
||||
| (b << 1) | (b);
|
||||
xcl.blue = (unsigned short)((val << 8) | (val));
|
||||
xcl_in = xcl;
|
||||
ret = XAllocColor(d, cmap, &xcl);
|
||||
if ((ret == Success) ||
|
||||
((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
|
||||
((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
|
||||
((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
|
||||
{
|
||||
unsigned long pixels[256];
|
||||
int j;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
pixels[j] = (unsigned long)color_lut[j];
|
||||
XFreeColors(d, cmap, pixels, i, 0);
|
||||
}
|
||||
free(color_lut);
|
||||
return NULL;
|
||||
}
|
||||
color_lut[i] = xcl.pixel;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pal_type = 5;
|
||||
return color_lut;
|
||||
}
|
||||
|
||||
DATA8 *
|
||||
__imlib_AllocColors1(Display * d, Colormap cmap, Visual * v)
|
||||
{
|
||||
XColor xcl;
|
||||
DATA8 *color_lut;
|
||||
|
||||
color_lut = malloc(2 * sizeof(DATA8));
|
||||
xcl.red = (unsigned short)(0x0000);
|
||||
xcl.green = (unsigned short)(0x0000);
|
||||
xcl.blue = (unsigned short)(0x0000);
|
||||
XAllocColor(d, cmap, &xcl);
|
||||
color_lut[0] = xcl.pixel;
|
||||
xcl.red = (unsigned short)(0xffff);
|
||||
xcl.green = (unsigned short)(0xffff);
|
||||
xcl.blue = (unsigned short)(0xffff);
|
||||
XAllocColor(d, cmap, &xcl);
|
||||
color_lut[1] = xcl.pixel;
|
||||
_pal_type = 6;
|
||||
return color_lut;
|
||||
}
|
16
src/color.h
16
src/color.h
|
@ -1,16 +0,0 @@
|
|||
#ifndef __COLOR
|
||||
#define __COLOR 1
|
||||
extern DATA16 _max_colors;
|
||||
|
||||
int __imlib_XActualDepth(Display *d, Visual *v);
|
||||
Visual *__imlib_BestVisual(Display *d, int screen, int *depth_return);
|
||||
DATA8 * __imlib_AllocColorTable(Display *d, Colormap cmap, DATA8 *type_return, Visual *v);
|
||||
DATA8 * __imlib_AllocColors332(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors666(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors232(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors222(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors221(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors121(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors111(Display *d, Colormap cmap, Visual *v);
|
||||
DATA8 * __imlib_AllocColors1(Display *d, Colormap cmap, Visual *v);
|
||||
#endif
|
|
@ -1,235 +0,0 @@
|
|||
#include "color_helpers.h"
|
||||
/*
|
||||
* Color space conversion helper routines
|
||||
* Convert between rgb and hsv adn between rgb and hls
|
||||
*/
|
||||
|
||||
void
|
||||
__imlib_rgb_to_hsv(int r, int g, int b, float *hue, float *saturation,
|
||||
float *value)
|
||||
{
|
||||
int f;
|
||||
float i, j, k, max, min, d;
|
||||
|
||||
i = ((float)r) / 255.0;
|
||||
j = ((float)g) / 255.0;
|
||||
k = ((float)b) / 255.0;
|
||||
|
||||
f = 0;
|
||||
max = min = i;
|
||||
if (j > max)
|
||||
{
|
||||
max = j;
|
||||
f = 1;
|
||||
}
|
||||
else
|
||||
min = j;
|
||||
if (k > max)
|
||||
{
|
||||
max = k;
|
||||
f = 2;
|
||||
}
|
||||
else if (k < min)
|
||||
min = k;
|
||||
d = max - min;
|
||||
|
||||
*value = max;
|
||||
if (max != 0)
|
||||
*saturation = d / max;
|
||||
else
|
||||
*saturation = 0;
|
||||
if (*saturation == 0)
|
||||
*hue = 0;
|
||||
else
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
case 0:
|
||||
*hue = (j - k) / d;
|
||||
break;
|
||||
case 1:
|
||||
*hue = 2 + (k - i) / d;
|
||||
break;
|
||||
case 2:
|
||||
*hue = 4 + (i - j) / d;
|
||||
break;
|
||||
}
|
||||
*hue *= 60.0;
|
||||
if (*hue < 0)
|
||||
*hue += 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_hsv_to_rgb(float hue, float saturation, float value, int *r, int *g,
|
||||
int *b)
|
||||
{
|
||||
int i, p, q, t, h;
|
||||
float vs, vsf;
|
||||
|
||||
i = (int)(value * 255.0);
|
||||
if (saturation == 0)
|
||||
*r = *g = *b = i;
|
||||
else
|
||||
{
|
||||
if (hue == 360)
|
||||
hue = 0;
|
||||
hue = hue / 60.0;
|
||||
h = (int)hue;
|
||||
vs = value * saturation;
|
||||
vsf = vs * (hue - h);
|
||||
p = (int)(255.0 * (value - vs));
|
||||
q = (int)(255.0 * (value - vsf));
|
||||
t = (int)(255.0 * (value - vs + vsf));
|
||||
switch (h)
|
||||
{
|
||||
case 0:
|
||||
*r = i;
|
||||
*g = t;
|
||||
*b = p;
|
||||
break;
|
||||
case 1:
|
||||
*r = q;
|
||||
*g = i;
|
||||
*b = p;
|
||||
break;
|
||||
case 2:
|
||||
*r = p;
|
||||
*g = i;
|
||||
*b = t;
|
||||
break;
|
||||
case 3:
|
||||
*r = p;
|
||||
*g = q;
|
||||
*b = i;
|
||||
break;
|
||||
case 4:
|
||||
*r = t;
|
||||
*g = p;
|
||||
*b = i;
|
||||
break;
|
||||
case 5:
|
||||
*r = i;
|
||||
*g = p;
|
||||
*b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_rgb_to_hls(int r, int g, int b, float *hue, float *lightness,
|
||||
float *saturation)
|
||||
{
|
||||
int f;
|
||||
float i, j, k, max, min, d;
|
||||
|
||||
i = ((float)r) / 255.0;
|
||||
j = ((float)g) / 255.0;
|
||||
k = ((float)b) / 255.0;
|
||||
|
||||
f = 0;
|
||||
max = min = i;
|
||||
if (j > max)
|
||||
{
|
||||
max = j;
|
||||
f = 1;
|
||||
}
|
||||
else
|
||||
min = j;
|
||||
if (k > max)
|
||||
{
|
||||
max = k;
|
||||
f = 2;
|
||||
}
|
||||
else if (k < min)
|
||||
min = k;
|
||||
d = max - min;
|
||||
|
||||
*lightness = (max + min) / 2.0;
|
||||
if (d == 0)
|
||||
{
|
||||
*saturation = 0;
|
||||
*hue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*lightness < 0.5)
|
||||
*saturation = d / (max + min);
|
||||
else
|
||||
*saturation = d / (2 - max - min);
|
||||
switch (f)
|
||||
{
|
||||
case 0:
|
||||
*hue = (j - k) / d;
|
||||
break;
|
||||
case 1:
|
||||
*hue = 2 + (k - i) / d;
|
||||
break;
|
||||
case 2:
|
||||
*hue = 4 + (i - j) / d;
|
||||
break;
|
||||
}
|
||||
*hue *= 60.0;
|
||||
if (*hue < 0)
|
||||
*hue += 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_hls_to_rgb(float hue, float lightness, float saturation, int *r, int *g,
|
||||
int *b)
|
||||
{
|
||||
float m1, m2, m21, h;
|
||||
|
||||
if (saturation == 0)
|
||||
*r = *g = *b = (int)(lightness * 255.0);
|
||||
else
|
||||
{
|
||||
if (lightness <= 0.5)
|
||||
m2 = lightness * (1 + saturation);
|
||||
else
|
||||
m2 = lightness + saturation + lightness * saturation;
|
||||
m1 = 2 * lightness - m2;
|
||||
m21 = m2 - m1;
|
||||
h = hue + 120;
|
||||
if (h > 360)
|
||||
h -= 360;
|
||||
else if (h < 0)
|
||||
h += 360;
|
||||
if (h < 60)
|
||||
*r = (int)(255.0 * (m1 + m21 * h / 60.0));
|
||||
else if (h < 180)
|
||||
*r = (int)(255.0 * m2);
|
||||
else if (h < 240)
|
||||
*r = (int)(255.0 * (m1 + m21 * (240.0 - h) / 60.0));
|
||||
else
|
||||
*r = (int)(255.0 * m1);
|
||||
h = hue;
|
||||
if (h > 360)
|
||||
h -= 360;
|
||||
else if (h < 0)
|
||||
h += 360;
|
||||
if (h < 60)
|
||||
*g = (int)(255.0 * (m1 + m21 * h / 60.0));
|
||||
else if (h < 180)
|
||||
*g = (int)(255.0 * m2);
|
||||
else if (h < 240)
|
||||
*g = (int)(255.0 * (m1 + m21 * (240.0 - h) / 60.0));
|
||||
else
|
||||
*g = (int)(255.0 * m1);
|
||||
h = hue - 120;
|
||||
if (h > 360)
|
||||
h -= 360;
|
||||
else if (h < 0)
|
||||
h += 360;
|
||||
if (h < 60)
|
||||
*b = (int)(255.0 * (m1 + m21 * h / 60.0));
|
||||
else if (h < 180)
|
||||
*b = (int)(255.0 * m2);
|
||||
else if (h < 240)
|
||||
*b = (int)(255.0 * (m1 + m21 * (240.0 - h) / 60.0));
|
||||
else
|
||||
*b = (int)(255.0 * m1);
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef __COLOR_HELPERS
|
||||
#define __COLOR_HELPERS 1
|
||||
|
||||
void __imlib_rgb_to_hsv(int r, int g, int b, float *hue, float *saturation, float *value);
|
||||
void __imlib_hsv_to_rgb(float hue, float saturation, float value, int *r, int *g, int *b);
|
||||
void __imlib_rgb_to_hls(int r, int g, int b, float *hue, float *lightness, float *saturation);
|
||||
void __imlib_hls_to_rgb(float hue, float lightness, float saturation, int *r, int *g, int *b);
|
||||
|
||||
#endif
|
254
src/colormod.c
254
src/colormod.c
|
@ -1,254 +0,0 @@
|
|||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "file.h"
|
||||
#include "loaderpath.h"
|
||||
#include <math.h>
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
|
||||
static DATABIG mod_count = 0;
|
||||
|
||||
ImlibColorModifier *
|
||||
__imlib_CreateCmod(void)
|
||||
{
|
||||
ImlibColorModifier *cm;
|
||||
int i;
|
||||
|
||||
cm = malloc(sizeof(ImlibColorModifier));
|
||||
cm->modification_count = mod_count;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
cm->red_mapping[i] = (DATA8) i;
|
||||
cm->green_mapping[i] = (DATA8) i;
|
||||
cm->blue_mapping[i] = (DATA8) i;
|
||||
cm->alpha_mapping[i] = (DATA8) i;
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FreeCmod(ImlibColorModifier * cm)
|
||||
{
|
||||
free(cm);
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodChanged(ImlibColorModifier * cm)
|
||||
{
|
||||
mod_count++;
|
||||
cm->modification_count = mod_count;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodSetTables(ImlibColorModifier * cm,
|
||||
DATA8 * r, DATA8 * g, DATA8 * b, DATA8 * a)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (r)
|
||||
cm->red_mapping[i] = r[i];
|
||||
if (g)
|
||||
cm->green_mapping[i] = g[i];
|
||||
if (b)
|
||||
cm->blue_mapping[i] = b[i];
|
||||
if (a)
|
||||
cm->alpha_mapping[i] = a[i];
|
||||
}
|
||||
__imlib_CmodChanged(cm);
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodReset(ImlibColorModifier * cm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
cm->red_mapping[i] = (DATA8) i;
|
||||
cm->green_mapping[i] = (DATA8) i;
|
||||
cm->blue_mapping[i] = (DATA8) i;
|
||||
cm->alpha_mapping[i] = (DATA8) i;
|
||||
}
|
||||
__imlib_CmodChanged(cm);
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_DataCmodApply(DATA32 * data, int w, int h, int jump,
|
||||
ImlibImageFlags * fl, ImlibColorModifier * cm)
|
||||
{
|
||||
int x, y;
|
||||
DATA32 *p;
|
||||
|
||||
/* We might be adding alpha */
|
||||
if (fl && !(*fl & F_HAS_ALPHA))
|
||||
{
|
||||
p = data;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
R_VAL(p) = R_CMOD(cm, R_VAL(p));
|
||||
G_VAL(p) = G_CMOD(cm, G_VAL(p));
|
||||
B_VAL(p) = B_CMOD(cm, B_VAL(p));
|
||||
A_VAL(p) = A_CMOD(cm, 255);
|
||||
p++;
|
||||
}
|
||||
p += jump;
|
||||
}
|
||||
if (A_CMOD(cm, 255) != 255)
|
||||
*fl |= F_HAS_ALPHA;
|
||||
return;
|
||||
}
|
||||
|
||||
p = data;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
R_VAL(p) = R_CMOD(cm, R_VAL(p));
|
||||
G_VAL(p) = G_CMOD(cm, G_VAL(p));
|
||||
B_VAL(p) = B_CMOD(cm, B_VAL(p));
|
||||
A_VAL(p) = A_CMOD(cm, A_VAL(p));
|
||||
p++;
|
||||
}
|
||||
p += jump;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodGetTables(ImlibColorModifier * cm, DATA8 * r, DATA8 * g,
|
||||
DATA8 * b, DATA8 * a)
|
||||
{
|
||||
if (r)
|
||||
memcpy(r, cm->red_mapping, (256 * sizeof(DATA8)));
|
||||
if (g)
|
||||
memcpy(g, cm->green_mapping, (256 * sizeof(DATA8)));
|
||||
if (b)
|
||||
memcpy(b, cm->blue_mapping, (256 * sizeof(DATA8)));
|
||||
if (a)
|
||||
memcpy(a, cm->alpha_mapping, (256 * sizeof(DATA8)));
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodModBrightness(ImlibColorModifier * cm, double v)
|
||||
{
|
||||
int i, val, val2;
|
||||
|
||||
val = (int)(v * 255);
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
val2 = (int)cm->red_mapping[i] + val;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->red_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)cm->green_mapping[i] + val;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->green_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)cm->blue_mapping[i] + val;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->blue_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)cm->alpha_mapping[i] + val;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->alpha_mapping[i] = (DATA8) val2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodModContrast(ImlibColorModifier * cm, double v)
|
||||
{
|
||||
int i, val2;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
val2 = (int)(((double)cm->red_mapping[i] - 127) * v) + 127;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->red_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)(((double)cm->green_mapping[i] - 127) * v) + 127;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->green_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)(((double)cm->blue_mapping[i] - 127) * v) + 127;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->blue_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)(((double)cm->alpha_mapping[i] - 127) * v) + 127;
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->alpha_mapping[i] = (DATA8) val2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_CmodModGamma(ImlibColorModifier * cm, double v)
|
||||
{
|
||||
int i, val2;
|
||||
|
||||
if (v < 0.01)
|
||||
v = 0.01;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
val2 = (int)(pow(((double)cm->red_mapping[i] / 255), (1 / v)) * 255);
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->red_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)(pow(((double)cm->green_mapping[i] / 255), (1 / v)) * 255);
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->green_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)(pow(((double)cm->blue_mapping[i] / 255), (1 / v)) * 255);
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->blue_mapping[i] = (DATA8) val2;
|
||||
|
||||
val2 = (int)(pow(((double)cm->alpha_mapping[i] / 255), (1 / v)) * 255);
|
||||
if (val2 < 0)
|
||||
val2 = 0;
|
||||
if (val2 > 255)
|
||||
val2 = 255;
|
||||
cm->alpha_mapping[i] = (DATA8) val2;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
__imlib_ImageCmodApply(ImlibImage * im, ImlibColorModifier * cm)
|
||||
{
|
||||
__imlib_DataCmodApply(im->data, im->w, im->h, 0, cm);
|
||||
}
|
||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||
#ifndef __COLORMOD
|
||||
#define __COLORMOD 1
|
||||
|
||||
#include "common.h"
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "image.h"
|
||||
|
||||
typedef struct _imlib_color_modifier ImlibColorModifier;
|
||||
|
||||
struct _imlib_color_modifier
|
||||
{
|
||||
DATA8 red_mapping[256];
|
||||
DATA8 green_mapping[256];
|
||||
DATA8 blue_mapping[256];
|
||||
DATA8 alpha_mapping[256];
|
||||
DATABIG modification_count;
|
||||
};
|
||||
|
||||
#define CMOD_APPLY_RGB(cm, r, g, b) \
|
||||
(r) = (cm)->red_mapping[(int)(r)]; \
|
||||
(g) = (cm)->green_mapping[(int)(g)]; \
|
||||
(b) = (cm)->blue_mapping[(int)(b)];
|
||||
|
||||
#define CMOD_APPLY_RGBA(cm, r, g, b, a) \
|
||||
(r) = (cm)->red_mapping[(int)(r)]; \
|
||||
(g) = (cm)->green_mapping[(int)(g)]; \
|
||||
(b) = (cm)->blue_mapping[(int)(b)]; \
|
||||
(a) = (cm)->alpha_mapping[(int)(a)];
|
||||
|
||||
#define CMOD_APPLY_R(cm, r) \
|
||||
(r) = (cm)->red_mapping[(int)(r)];
|
||||
#define CMOD_APPLY_G(cm, g) \
|
||||
(g) = (cm)->green_mapping[(int)(g)];
|
||||
#define CMOD_APPLY_B(cm, b) \
|
||||
(b) = (cm)->blue_mapping[(int)(b)];
|
||||
#define CMOD_APPLY_A(cm, a) \
|
||||
(a) = (cm)->alpha_mapping[(int)(a)];
|
||||
|
||||
#define R_CMOD(cm, r) \
|
||||
(cm)->red_mapping[(int)(r)]
|
||||
#define G_CMOD(cm, g) \
|
||||
(cm)->green_mapping[(int)(g)]
|
||||
#define B_CMOD(cm, b) \
|
||||
(cm)->blue_mapping[(int)(b)]
|
||||
#define A_CMOD(cm, a) \
|
||||
(cm)->alpha_mapping[(int)(a)]
|
||||
|
||||
ImlibColorModifier * __imlib_CreateCmod(void);
|
||||
void __imlib_FreeCmod(ImlibColorModifier *cm);
|
||||
void __imlib_CmodChanged(ImlibColorModifier *cm);
|
||||
void __imlib_CmodSetTables(ImlibColorModifier *cm, DATA8 *r,
|
||||
DATA8 *g, DATA8 *b, DATA8 *a);
|
||||
void __imlib_CmodReset(ImlibColorModifier *cm);
|
||||
void __imlib_DataCmodApply(DATA32 *data, int w, int h,
|
||||
int jump, ImlibImageFlags *fl,
|
||||
ImlibColorModifier *cm);
|
||||
|
||||
void __imlib_CmodGetTables(ImlibColorModifier *cm, DATA8 *r,
|
||||
DATA8 *g, DATA8 *b, DATA8 *a);
|
||||
void __imlib_CmodModBrightness(ImlibColorModifier *cm,
|
||||
double v);
|
||||
void __imlib_CmodModContrast(ImlibColorModifier *cm,
|
||||
double v);
|
||||
void __imlib_CmodModGamma(ImlibColorModifier *cm,
|
||||
double v);
|
||||
#endif
|
42
src/common.h
42
src/common.h
|
@ -1,42 +0,0 @@
|
|||
#ifndef __COMMON
|
||||
#define __COMMON 1
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#ifdef WITH_DMALLOC
|
||||
# include <dmalloc.h>
|
||||
#endif
|
||||
#ifdef __EMX__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#define DATABIG unsigned long long
|
||||
#define DATA64 unsigned long long
|
||||
#define DATA32 unsigned int
|
||||
#define DATA16 unsigned short
|
||||
#define DATA8 unsigned char
|
||||
|
||||
#ifdef DO_MMX_ASM
|
||||
int __imlib_get_cpuid(void);
|
||||
#define CPUID_MMX (1 << 23)
|
||||
#define CPUID_XMM (1 << 25)
|
||||
#endif
|
||||
|
||||
#define CLIP(x, y, w, h, xx, yy, ww, hh) \
|
||||
if (x < (xx)) {w += (x - (xx)); x = (xx);} \
|
||||
if (y < (yy)) {h += (y - (yy)); y = (yy);} \
|
||||
if ((x + w) > ((xx) + (ww))) {w = (ww) - (x - xx);} \
|
||||
if ((y + h) > ((yy) + (hh))) {h = (hh) - (y - yy);}
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#ifdef __EMX__
|
||||
extern char *__XOS2RedirRoot(const char *);
|
||||
#endif
|
||||
|
||||
#endif
|
208
src/context.c
208
src/context.c
|
@ -1,208 +0,0 @@
|
|||
#include "common.h"
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
# include "image.h"
|
||||
#include "context.h"
|
||||
#include "color.h"
|
||||
#include "rgba.h"
|
||||
|
||||
static Context *context = NULL;
|
||||
static int max_context_count = 128;
|
||||
static int context_counter = 0;
|
||||
|
||||
void
|
||||
__imlib_SetMaxContexts(int num)
|
||||
{
|
||||
max_context_count = num;
|
||||
__imlib_FlushContexts();
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_GetMaxContexts(void)
|
||||
{
|
||||
return max_context_count;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FlushContexts(void)
|
||||
{
|
||||
Context *ct, *pct, *ctt;
|
||||
|
||||
ct = context;
|
||||
pct = NULL;
|
||||
while (ct)
|
||||
{
|
||||
ctt = ct;
|
||||
ct = ct->next;
|
||||
/* it hasnt been referenced in the last max_context_count refernces */
|
||||
/* thus old and getrid of it */
|
||||
if (ctt->last_use < (context_counter - max_context_count))
|
||||
{
|
||||
if (pct)
|
||||
context = ctt->next;
|
||||
else
|
||||
pct->next = ctt->next;
|
||||
if (ctt->palette)
|
||||
{
|
||||
int i, num[] = { 256, 128, 64, 32, 16, 8, 1 };
|
||||
unsigned long pixels[256];
|
||||
|
||||
for (i = 0; i < num[ctt->palette_type]; i++)
|
||||
pixels[i] = (unsigned long)ctt->palette[i];
|
||||
XFreeColors(ctt->display, ctt->colormap, pixels,
|
||||
num[ctt->palette_type], 0);
|
||||
|
||||
free(ctt->palette);
|
||||
free(ctt->r_dither);
|
||||
free(ctt->g_dither);
|
||||
free(ctt->b_dither);
|
||||
}
|
||||
else if (ctt->r_dither)
|
||||
{
|
||||
free(ctt->r_dither);
|
||||
free(ctt->g_dither);
|
||||
free(ctt->b_dither);
|
||||
}
|
||||
free(ctt);
|
||||
}
|
||||
else
|
||||
pct = ctt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FreeContextForDisplay(Display * d)
|
||||
{
|
||||
Context *ct;
|
||||
|
||||
ct = context;
|
||||
while (ct)
|
||||
{
|
||||
if (ct->display == d)
|
||||
ct->last_use = -(max_context_count * 2);
|
||||
ct = ct->next;
|
||||
}
|
||||
__imlib_FlushContexts();
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FreeContextForColormap(Display * d, Colormap cm)
|
||||
{
|
||||
Context *ct;
|
||||
|
||||
ct = context;
|
||||
while (ct)
|
||||
{
|
||||
if ((ct->display == d) && (ct->colormap == cm))
|
||||
ct->last_use = -(max_context_count * 2);
|
||||
ct = ct->next;
|
||||
}
|
||||
__imlib_FlushContexts();
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FreeContextForVisual(Display * d, Visual * v)
|
||||
{
|
||||
Context *ct;
|
||||
|
||||
ct = context;
|
||||
while (ct)
|
||||
{
|
||||
if ((ct->display == d) && (ct->visual == v))
|
||||
ct->last_use = -(max_context_count * 2);
|
||||
ct = ct->next;
|
||||
}
|
||||
__imlib_FlushContexts();
|
||||
}
|
||||
|
||||
Context *
|
||||
__imlib_FindContext(Display * d, Visual * v, Colormap c, int depth)
|
||||
{
|
||||
Context *ct, *pct;
|
||||
|
||||
pct = NULL;
|
||||
ct = context;
|
||||
while (ct)
|
||||
{
|
||||
if ((ct->display == d) && (ct->visual == v) &&
|
||||
(ct->colormap == c) && (ct->depth == depth))
|
||||
{
|
||||
if (pct)
|
||||
{
|
||||
pct->next = ct->next;
|
||||
ct->next = context;
|
||||
context = ct;
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
pct = ct;
|
||||
ct = ct->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Context *
|
||||
__imlib_NewContext(Display * d, Visual * v, Colormap c, int depth)
|
||||
{
|
||||
Context *ct;
|
||||
|
||||
context_counter++;
|
||||
ct = malloc(sizeof(Context));
|
||||
ct->last_use = context_counter;
|
||||
ct->display = d;
|
||||
ct->visual = v;
|
||||
ct->colormap = c;
|
||||
ct->depth = depth;
|
||||
ct->next = NULL;
|
||||
|
||||
if (depth <= 8)
|
||||
{
|
||||
ct->palette = __imlib_AllocColorTable(d, c, &(ct->palette_type), v);
|
||||
ct->r_dither = malloc(sizeof(DATA8) * DM_X * DM_Y * 256);
|
||||
ct->g_dither = malloc(sizeof(DATA8) * DM_X * DM_Y * 256);
|
||||
ct->b_dither = malloc(sizeof(DATA8) * DM_X * DM_Y * 256);
|
||||
__imlib_RGBA_init((void *)ct->r_dither, (void *)ct->g_dither,
|
||||
(void *)ct->b_dither, depth, ct->palette_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
ct->palette = NULL;
|
||||
ct->palette_type = 0;
|
||||
if ((depth > 8) && (depth <= 16))
|
||||
{
|
||||
ct->r_dither = malloc(sizeof(DATA16) * 4 * 4 * 256);
|
||||
ct->g_dither = malloc(sizeof(DATA16) * 4 * 4 * 256);
|
||||
ct->b_dither = malloc(sizeof(DATA16) * 4 * 4 * 256);
|
||||
__imlib_RGBA_init((void *)ct->r_dither, (void *)ct->g_dither,
|
||||
(void *)ct->b_dither, depth, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ct->r_dither = NULL;
|
||||
ct->g_dither = NULL;
|
||||
ct->b_dither = NULL;
|
||||
__imlib_RGBA_init((void *)ct->r_dither, (void *)ct->g_dither,
|
||||
(void *)ct->b_dither, depth, 0);
|
||||
}
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
Context *
|
||||
__imlib_GetContext(Display * d, Visual * v, Colormap c, int depth)
|
||||
{
|
||||
Context *ct;
|
||||
|
||||
ct = __imlib_FindContext(d, v, c, depth);
|
||||
if (ct)
|
||||
{
|
||||
ct->last_use = context_counter;
|
||||
return ct;
|
||||
}
|
||||
ct = __imlib_NewContext(d, v, c, depth);
|
||||
ct->next = context;
|
||||
context = ct;
|
||||
__imlib_FlushContexts();
|
||||
return ct;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef __CONTEXT
|
||||
#define __CONTEXT 1
|
||||
|
||||
typedef struct _context Context;
|
||||
|
||||
struct _context
|
||||
{
|
||||
int last_use;
|
||||
Display *display;
|
||||
Visual *visual;
|
||||
Colormap colormap;
|
||||
int depth;
|
||||
Context *next;
|
||||
|
||||
DATA8 *palette;
|
||||
DATA8 palette_type;
|
||||
void *r_dither;
|
||||
void *g_dither;
|
||||
void *b_dither;
|
||||
};
|
||||
|
||||
void __imlib_SetMaxContexts(int num);
|
||||
int __imlib_GetMaxContexts(void);
|
||||
void __imlib_FlushContexts(void);
|
||||
void __imlib_FreeContextForDisplay(Display *d);
|
||||
void __imlib_FreeContextForColormap(Display *d, Colormap cm);
|
||||
void __imlib_FreeContextForVisual(Display *d, Visual *v);
|
||||
Context *__imlib_FindContext(Display *d, Visual *v, Colormap c, int depth);
|
||||
Context *__imlib_NewContext(Display *d, Visual *v, Colormap c, int depth);
|
||||
Context *__imlib_GetContext(Display *d, Visual *v, Colormap c, int depth);
|
||||
|
||||
#endif
|
88
src/draw.c
88
src/draw.c
|
@ -1,88 +0,0 @@
|
|||
#include "common.h"
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#endif
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include "rend.h"
|
||||
#include "draw.h"
|
||||
|
||||
char
|
||||
__imlib_CreatePixmapsForImage(Display * d, Drawable w, Visual * v, int depth,
|
||||
Colormap cm, ImlibImage * im, Pixmap * p,
|
||||
Mask * m, int sx, int sy, int sw, int sh, int dw,
|
||||
int dh, char antialias, char hiq,
|
||||
char dither_mask, ImlibColorModifier * cmod)
|
||||
{
|
||||
ImlibImagePixmap *ip = NULL;
|
||||
Pixmap pmap = 0;
|
||||
Pixmap mask = 0;
|
||||
long long mod_count = 0;
|
||||
|
||||
if (cmod)
|
||||
mod_count = cmod->modification_count;
|
||||
ip = __imlib_FindCachedImagePixmap(im, dw, dh, d, v, depth, sx, sy,
|
||||
sw, sh, cm, antialias, hiq, dither_mask,
|
||||
mod_count);
|
||||
if (ip)
|
||||
{
|
||||
if (p)
|
||||
*p = ip->pixmap;
|
||||
if (m)
|
||||
*m = ip->mask;
|
||||
ip->references++;
|
||||
#ifdef DEBUG_CACHE
|
||||
fprintf(stderr,
|
||||
"[Imlib2] Match found in cache. Reference count is %d, pixmap 0x%08x, mask 0x%08x\n",
|
||||
ip->references, ip->pixmap, ip->mask);
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
pmap = XCreatePixmap(d, w, dw, dh, depth);
|
||||
*p = pmap;
|
||||
}
|
||||
if (m)
|
||||
{
|
||||
if (IMAGE_HAS_ALPHA(im))
|
||||
mask = XCreatePixmap(d, w, dw, dh, 1);
|
||||
*m = mask;
|
||||
}
|
||||
__imlib_RenderImage(d, im, pmap, mask, v, cm, depth, sx, sy, sw, sh, 0, 0,
|
||||
dw, dh, antialias, hiq, 0, dither_mask, cmod, OP_COPY);
|
||||
ip = __imlib_ProduceImagePixmap();
|
||||
ip->visual = v;
|
||||
ip->depth = depth;
|
||||
ip->image = im;
|
||||
if (im->file)
|
||||
ip->file = strdup(im->file);
|
||||
ip->border.left = im->border.left;
|
||||
ip->border.right = im->border.right;
|
||||
ip->border.top = im->border.top;
|
||||
ip->border.bottom = im->border.bottom;
|
||||
ip->colormap = cm;
|
||||
ip->display = d;
|
||||
ip->w = dw;
|
||||
ip->h = dh;
|
||||
ip->source_x = sx;
|
||||
ip->source_y = sy;
|
||||
ip->source_w = sw;
|
||||
ip->source_h = sh;
|
||||
ip->antialias = antialias;
|
||||
ip->modification_count = mod_count;
|
||||
ip->dither_mask = dither_mask;
|
||||
ip->hi_quality = hiq;
|
||||
ip->references = 1;
|
||||
ip->pixmap = pmap;
|
||||
ip->mask = mask;
|
||||
__imlib_AddImagePixmapToCache(ip);
|
||||
#ifdef DEBUG_CACHE
|
||||
fprintf(stderr,
|
||||
"[Imlib2] Created pixmap. Reference count is %d, pixmap 0x%08x, mask 0x%08x\n",
|
||||
ip->references, ip->pixmap, ip->mask);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
10
src/draw.h
10
src/draw.h
|
@ -1,10 +0,0 @@
|
|||
#ifndef __DRAW
|
||||
#define __DRAW 1
|
||||
char
|
||||
__imlib_CreatePixmapsForImage(Display *d, Drawable w, Visual *v, int depth,
|
||||
Colormap cm, ImlibImage *im, Pixmap *p, Mask *m,
|
||||
int sx, int sy, int sw, int sh,
|
||||
int dw, int dh,
|
||||
char anitalias, char hiq, char dither_mask,
|
||||
ImlibColorModifier *cmod);
|
||||
#endif
|
|
@ -1,193 +0,0 @@
|
|||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "image.h"
|
||||
#include "file.h"
|
||||
#include "dynamic_filters.h"
|
||||
#include "script.h"
|
||||
#include "loaderpath.h"
|
||||
|
||||
pImlibExternalFilter filters = NULL;
|
||||
int dyn_initialised = 0;
|
||||
|
||||
#define MALLOCSHOW
|
||||
#define FREESHOW
|
||||
/*
|
||||
#define FDEBUG
|
||||
*/
|
||||
|
||||
pImlibExternalFilter
|
||||
__imlib_LoadFilter(char *file)
|
||||
{
|
||||
ImlibExternalFilter *ptr;
|
||||
struct imlib_filter_info *info;
|
||||
|
||||
/* printf( "Loading filter %s\n", file ); */
|
||||
MALLOCSHOW;
|
||||
ptr = malloc(sizeof(ImlibExternalFilter));
|
||||
ptr->filename = strdup(file);
|
||||
ptr->handle = lt_dlopenext(file);
|
||||
if (!ptr->handle)
|
||||
{
|
||||
FREESHOW;
|
||||
free(ptr->filename);
|
||||
FREESHOW;
|
||||
free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
ptr->init_filter = lt_dlsym(ptr->handle, "init");
|
||||
ptr->deinit_filter = lt_dlsym(ptr->handle, "deinit");
|
||||
ptr->exec_filter = lt_dlsym(ptr->handle, "exec");
|
||||
if (!ptr->init_filter || !ptr->deinit_filter || !ptr->exec_filter)
|
||||
{
|
||||
lt_dlclose(ptr->handle);
|
||||
FREESHOW;
|
||||
free(ptr->filename);
|
||||
FREESHOW;
|
||||
free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
info = malloc(sizeof(struct imlib_filter_info));
|
||||
ptr->init_filter(info);
|
||||
ptr->num_filters = info->num_filters;
|
||||
ptr->filters = info->filters;
|
||||
ptr->name = info->name;
|
||||
ptr->author = info->author;
|
||||
ptr->description = info->description;
|
||||
|
||||
free(info);
|
||||
|
||||
#ifdef FDEBUG
|
||||
printf("Filter has %d filters in it.\n", ptr->num_filters);
|
||||
for (i = 0; i < ptr->num_filters; i++)
|
||||
printf(" -> \"%s\"\n", ptr->filters[i]);
|
||||
#endif
|
||||
|
||||
ptr->next = NULL;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_dynamic_filters_init()
|
||||
{
|
||||
char **list;
|
||||
int num_filters, i = 0;
|
||||
ImlibExternalFilter *ptr, *tptr;
|
||||
|
||||
if (!dyn_initialised)
|
||||
{
|
||||
MALLOCSHOW;
|
||||
filters = malloc(sizeof(ImlibExternalFilter));
|
||||
filters->filename = "";
|
||||
filters->next = NULL;
|
||||
ptr = filters;
|
||||
#ifdef FDEBUG
|
||||
printf("DEBUG: Dynamic filters Initisialising\n");
|
||||
#endif
|
||||
dyn_initialised = 1;
|
||||
#ifdef FDEBUG
|
||||
printf("DEBUG: Loading Filters\n");
|
||||
#endif
|
||||
list = __imlib_ListFilters(&num_filters);
|
||||
for (i = num_filters - 1; i >= 0; i--)
|
||||
{
|
||||
tptr = NULL;
|
||||
if ((tptr = __imlib_LoadFilter(list[i])) != NULL)
|
||||
{
|
||||
ptr->next = tptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if (list[i])
|
||||
{
|
||||
FREESHOW;
|
||||
free(list[i]);
|
||||
}
|
||||
}
|
||||
FREESHOW;
|
||||
if (list)
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_dynamic_filters_deinit()
|
||||
{
|
||||
}
|
||||
|
||||
pImlibExternalFilter
|
||||
__imlib_get_dynamic_filter(char *name)
|
||||
{
|
||||
pImlibExternalFilter f_ptr;
|
||||
int i = 0;
|
||||
|
||||
/* scan the filters */
|
||||
for (f_ptr = filters->next; f_ptr != NULL; f_ptr = f_ptr->next)
|
||||
{
|
||||
/* scan the methods provided */
|
||||
for (i = 0; i < f_ptr->num_filters; i++)
|
||||
{
|
||||
if (strcmp(f_ptr->filters[i], name) == 0)
|
||||
{
|
||||
#ifdef FDEBUG
|
||||
printf("DEBUG: Found filter \"%s\"\n", name);
|
||||
#endif
|
||||
return f_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* loader dir */
|
||||
char **
|
||||
__imlib_ListFilters(int *num_ret)
|
||||
{
|
||||
char **list = NULL, **l, *s;
|
||||
int num, i, pi = 0;
|
||||
|
||||
*num_ret = 0;
|
||||
/* same for system loader path */
|
||||
s = (char *)malloc(sizeof(SYS_LOADERS_PATH) + 7 + 1);
|
||||
sprintf(s, SYS_LOADERS_PATH "/filter");
|
||||
#ifndef __EMX__
|
||||
l = __imlib_FileDir(s, &num);
|
||||
#else
|
||||
l = __imlib_FileDir(__XOS2RedirRoot(s), &num);
|
||||
#endif
|
||||
if (num > 0)
|
||||
{
|
||||
*num_ret += num;
|
||||
list = realloc(list, sizeof(char *) * *num_ret);
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
s = (char *)realloc(s,
|
||||
sizeof(SYS_LOADERS_PATH) + 8 + strlen(l[i]) +
|
||||
1);
|
||||
sprintf(s, SYS_LOADERS_PATH "/filter/%s", l[i]);
|
||||
#ifndef __EMX__
|
||||
list[pi + i] = strdup(s);
|
||||
#else
|
||||
list[pi + i] = strdup(__XOS2RedirRoot(s));
|
||||
#endif
|
||||
}
|
||||
__imlib_FileFreeDirList(l, num);
|
||||
}
|
||||
free(s);
|
||||
|
||||
/* List currently contains *everything in there* we need to weed out
|
||||
* the .so, .la, .a versions of the same loader or whatever else.
|
||||
* lt_dlopen can take an extension-less name and do the Right Thing
|
||||
* with it, so that's what we'll give it. */
|
||||
list = __imlib_TrimLoaderList(list, num_ret);
|
||||
|
||||
return list;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
#ifndef _DYNAMIC_FILTERS_H_
|
||||
#define _DYNAMIC_FILTERS_H_
|
||||
|
||||
#include "script.h"
|
||||
|
||||
struct imlib_filter_info
|
||||
{
|
||||
char *name;
|
||||
char *author;
|
||||
char *description;
|
||||
char **filters;
|
||||
int num_filters;
|
||||
};
|
||||
|
||||
typedef struct _imlib_external_filter ImlibExternalFilter;
|
||||
typedef struct _imlib_external_filter *pImlibExternalFilter;
|
||||
struct _imlib_external_filter
|
||||
{
|
||||
char *name;
|
||||
char *author;
|
||||
char *description;
|
||||
int num_filters;
|
||||
char *filename;
|
||||
void *handle;
|
||||
char **filters;
|
||||
void (*init_filter)( struct imlib_filter_info *info );
|
||||
void (*deinit_filter)();
|
||||
void *(*exec_filter)( char *filter, void *im, pIFunctionParam params );
|
||||
pImlibExternalFilter next;
|
||||
};
|
||||
|
||||
void __imlib_dynamic_filters_init();
|
||||
void __imlib_dynamic_filters_deinit();
|
||||
pImlibExternalFilter __imlib_get_dynamic_filter( char *name );
|
||||
char **__imlib_ListFilters(int *num_ret);
|
||||
pImlibExternalFilter __imlib_LoadFilter( char *file );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
737
src/ellipse.c
737
src/ellipse.c
|
@ -1,737 +0,0 @@
|
|||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include "span.h"
|
||||
#include "updates.h"
|
||||
#include "rgbadraw.h"
|
||||
|
||||
|
||||
static void
|
||||
__imlib_Ellipse_DrawToData(int xc, int yc, int a, int b, DATA32 color,
|
||||
DATA32 *dst, int dstw, int clx, int cly, int clw, int clh,
|
||||
ImlibOp op, char dst_alpha, char blend)
|
||||
{
|
||||
ImlibPointDrawFunction pfunc;
|
||||
int xx, yy, x, y, prev_x, prev_y, ty, by, lx, rx;
|
||||
DATA32 a2, b2, *tp, *bp;
|
||||
DATA64 dx, dy;
|
||||
|
||||
if (A_VAL(&color) == 0xff)
|
||||
blend = 0;
|
||||
pfunc = __imlib_GetPointDrawFunction(op, dst_alpha, blend);
|
||||
if (!pfunc)
|
||||
return;
|
||||
|
||||
xc -= clx;
|
||||
yc -= cly;
|
||||
dst += (dstw * cly) + clx;
|
||||
|
||||
a2 = a*a; b2 = b*b;
|
||||
|
||||
yy = b << 16;
|
||||
prev_y = b;
|
||||
|
||||
dx = a2 * b;
|
||||
dy = 0;
|
||||
|
||||
ty = yc - b - 1;
|
||||
by = yc + b;
|
||||
lx = xc - 1;
|
||||
rx = xc;
|
||||
|
||||
tp = dst + (dstw * ty) + lx;
|
||||
bp = dst + (dstw * by) + lx;
|
||||
|
||||
while (dy < dx)
|
||||
{
|
||||
int len;
|
||||
|
||||
y = yy >> 16;
|
||||
y += ((yy - (y << 16)) >> 15);
|
||||
|
||||
if (prev_y != y)
|
||||
{
|
||||
prev_y = y;
|
||||
dx -= a2;
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
}
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(color, tp);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(color, tp + len);
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(color, bp);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(color, bp + len);
|
||||
|
||||
dy += b2;
|
||||
yy -= ((dy << 16) / dx);
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
|
||||
if ( (lx < 0) && (rx > clw) )
|
||||
return;
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
|
||||
xx = yy;
|
||||
prev_x = xx >> 16;
|
||||
|
||||
dx = dy;
|
||||
|
||||
ty++;
|
||||
by--;
|
||||
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
while (ty < yc)
|
||||
{
|
||||
int len;
|
||||
|
||||
x = xx >> 16;
|
||||
x += ((xx - (x << 16)) >> 15);
|
||||
|
||||
if (prev_x != x)
|
||||
{
|
||||
prev_x = x;
|
||||
dy += b2;
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
}
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(color, tp);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(color, tp + len);
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(color, bp);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(color, bp + len);
|
||||
|
||||
dx -= a2;
|
||||
xx += ((dx << 16) / dy);
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
if ( (lx < 0) && (rx > clw) )
|
||||
return;
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__imlib_Ellipse_DrawToData_AA(int xc, int yc, int a, int b, DATA32 color,
|
||||
DATA32 *dst, int dstw, int clx, int cly, int clw, int clh,
|
||||
ImlibOp op, char dst_alpha, char blend)
|
||||
{
|
||||
ImlibPointDrawFunction pfunc;
|
||||
int xx, yy, x, y, prev_x, prev_y, ty, by, lx, rx;
|
||||
DATA32 a2, b2, col0, col1, *tp, *bp;
|
||||
DATA64 dx, dy;
|
||||
DATA8 ca = A_VAL(&color);
|
||||
|
||||
pfunc = __imlib_GetPointDrawFunction(op, dst_alpha, blend);
|
||||
if (!pfunc)
|
||||
return;
|
||||
|
||||
xc -= clx;
|
||||
yc -= cly;
|
||||
dst += (dstw * cly) + clx;
|
||||
|
||||
col0 = col1 = color;
|
||||
a2 = a*a; b2 = b*b;
|
||||
|
||||
yy = b << 16;
|
||||
prev_y = b;
|
||||
|
||||
dx = a2 * b;
|
||||
dy = 0;
|
||||
|
||||
ty = yc - b - 2;
|
||||
by = yc + b + 1;
|
||||
lx = xc - 1;
|
||||
rx = xc;
|
||||
|
||||
tp = dst + (dstw * ty) + lx;
|
||||
bp = dst + (dstw * by) + lx;
|
||||
|
||||
while (dy < dx)
|
||||
{
|
||||
int len;
|
||||
DATA32 tmp;
|
||||
|
||||
y = yy >> 16;
|
||||
|
||||
if (prev_y != y)
|
||||
{
|
||||
prev_y = y;
|
||||
dx -= a2;
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
}
|
||||
|
||||
A_VAL(&col1) = (yy - (y << 16)) >> 8;
|
||||
A_VAL(&col0) = 255 - A_VAL(&col1);
|
||||
|
||||
if (ca < 255)
|
||||
{
|
||||
MULT(A_VAL(&col0), ca, A_VAL(&col0), tmp)
|
||||
MULT(A_VAL(&col1), ca, A_VAL(&col1), tmp)
|
||||
}
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(col1, tp);
|
||||
if (IN_RANGE(lx, ty + 1, clw, clh))
|
||||
pfunc(col0, tp + dstw);
|
||||
|
||||
if (IN_RANGE(rx, ty + 1, clw, clh))
|
||||
pfunc(col0, tp + dstw + len);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(col1, tp + len);
|
||||
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(col1, bp);
|
||||
if (IN_RANGE(lx, by - 1, clw, clh))
|
||||
pfunc(col0, bp - dstw);
|
||||
|
||||
if (IN_RANGE(rx, by - 1, clw, clh))
|
||||
pfunc(col0, bp - dstw + len);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(col1, bp + len);
|
||||
|
||||
dy += b2;
|
||||
yy -= ((dy << 16) / dx);
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
|
||||
if ( (lx < 0) && (rx > clw) )
|
||||
return;
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
|
||||
y = yy >> 16;
|
||||
xx = yy;
|
||||
prev_x = y;
|
||||
|
||||
dx = dy;
|
||||
|
||||
ty++;
|
||||
by--;
|
||||
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
while (ty < yc)
|
||||
{
|
||||
int len;
|
||||
DATA32 tmp;
|
||||
|
||||
x = xx >> 16;
|
||||
|
||||
if (prev_x != x)
|
||||
{
|
||||
prev_x = x;
|
||||
dy += b2;
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
}
|
||||
|
||||
A_VAL(&col1) = (xx - (x << 16)) >> 8;
|
||||
A_VAL(&col0) = 255 - A_VAL(&col1);
|
||||
|
||||
if (ca < 255)
|
||||
{
|
||||
MULT(A_VAL(&col0), ca, A_VAL(&col0), tmp)
|
||||
MULT(A_VAL(&col1), ca, A_VAL(&col1), tmp)
|
||||
}
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(col1, tp);
|
||||
if (IN_RANGE(lx + 1, ty, clw, clh) && (x != y))
|
||||
pfunc(col0, tp + 1);
|
||||
|
||||
if (IN_RANGE(rx - 1, ty, clw, clh) && (x != y))
|
||||
pfunc(col0, tp + len - 1);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(col1, tp + len);
|
||||
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(col1, bp);
|
||||
if (IN_RANGE(lx + 1, by, clw, clh) && (x != y))
|
||||
pfunc(col0, bp + 1);
|
||||
|
||||
if (IN_RANGE(rx - 1, by, clw, clh) && (x != y))
|
||||
pfunc(col0, bp + len - 1);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(col1, bp + len);
|
||||
|
||||
dx -= a2;
|
||||
xx += ((dx << 16) / dy);
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
if ( (lx < 0) && (rx > clw) )
|
||||
return;
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__imlib_Ellipse_FillToData(int xc, int yc, int a, int b, DATA32 color,
|
||||
DATA32 *dst, int dstw, int clx, int cly, int clw, int clh,
|
||||
ImlibOp op, char dst_alpha, char blend)
|
||||
{
|
||||
ImlibPointDrawFunction pfunc;
|
||||
ImlibSpanDrawFunction sfunc;
|
||||
int xx, yy, x, y, prev_x, prev_y, ty, by, lx, rx;
|
||||
DATA32 a2, b2, *tp, *bp;
|
||||
DATA64 dx, dy;
|
||||
|
||||
if (A_VAL(&color) == 0xff)
|
||||
blend = 0;
|
||||
pfunc = __imlib_GetPointDrawFunction(op, dst_alpha, blend);
|
||||
sfunc = __imlib_GetSpanDrawFunction(op, dst_alpha, blend);
|
||||
if ((!sfunc) || (!pfunc))
|
||||
return;
|
||||
|
||||
xc -= clx;
|
||||
yc -= cly;
|
||||
dst += (dstw * cly) + clx;
|
||||
|
||||
a2 = a*a; b2 = b*b;
|
||||
|
||||
yy = b << 16;
|
||||
prev_y = b;
|
||||
|
||||
dx = a2 * b;
|
||||
dy = 0;
|
||||
|
||||
ty = yc - b - 1;
|
||||
by = yc + b;
|
||||
lx = xc - 1;
|
||||
rx = xc;
|
||||
|
||||
tp = dst + (dstw * ty) + lx;
|
||||
bp = dst + (dstw * by) + lx;
|
||||
|
||||
while (dy < dx)
|
||||
{
|
||||
int len;
|
||||
DATA32 *tpp, *bpp;
|
||||
|
||||
y = yy >> 16;
|
||||
y += ((yy - (y << 16)) >> 15);
|
||||
|
||||
if (prev_y != y)
|
||||
{
|
||||
prev_y = y;
|
||||
dx -= a2;
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
tpp = tp + 1;
|
||||
bpp = bp + 1;
|
||||
len = rx;
|
||||
if (len > clw) len = clw;
|
||||
len -= (lx + 1);
|
||||
if (lx < -1)
|
||||
{
|
||||
len += (lx + 1);
|
||||
tpp -= (lx + 1);
|
||||
bpp -= (lx + 1);
|
||||
}
|
||||
|
||||
if ( ((unsigned)(ty) < clh) && (len > 0) )
|
||||
sfunc(color, tpp, len);
|
||||
if ( ((unsigned)(by) < clh) && (len > 0) )
|
||||
sfunc(color, bpp, len);
|
||||
}
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(color, tp);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(color, tp + len);
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(color, bp);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(color, bp + len);
|
||||
|
||||
dy += b2;
|
||||
yy -= ((dy << 16) / dx);
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
|
||||
xx = yy;
|
||||
prev_x = xx >> 16;
|
||||
|
||||
dx = dy;
|
||||
|
||||
ty++;
|
||||
by--;
|
||||
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
while (ty < yc)
|
||||
{
|
||||
int len;
|
||||
DATA32 *tpp, *bpp;
|
||||
|
||||
x = xx >> 16;
|
||||
x += ((xx - (x << 16)) >> 15);
|
||||
|
||||
if (prev_x != x)
|
||||
{
|
||||
prev_x = x;
|
||||
dy += b2;
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
}
|
||||
|
||||
tpp = tp;
|
||||
bpp = bp;
|
||||
len = rx + 1;
|
||||
if (len > clw) len = clw;
|
||||
len -= lx;
|
||||
if (lx < 0)
|
||||
{
|
||||
len += lx;
|
||||
tpp -= lx;
|
||||
bpp -= lx;
|
||||
}
|
||||
|
||||
if ( ((unsigned)(ty) < clh) && (len > 0) )
|
||||
sfunc(color, tpp, len);
|
||||
if ( ((unsigned)(by) < clh) && (len > 0) )
|
||||
sfunc(color, bpp, len);
|
||||
|
||||
dx -= a2;
|
||||
xx += ((dx << 16) / dy);
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__imlib_Ellipse_FillToData_AA(int xc, int yc, int a, int b, DATA32 color,
|
||||
DATA32 *dst, int dstw, int clx, int cly, int clw, int clh,
|
||||
ImlibOp op, char dst_alpha, char blend)
|
||||
{
|
||||
ImlibPointDrawFunction pfunc;
|
||||
ImlibSpanDrawFunction sfunc;
|
||||
int xx, yy, x, y, prev_x, prev_y, ty, by, lx, rx;
|
||||
DATA32 a2, b2, col1, *tp, *bp;
|
||||
DATA64 dx, dy;
|
||||
DATA8 ca = A_VAL(&color);
|
||||
|
||||
pfunc = __imlib_GetPointDrawFunction(op, dst_alpha, blend);
|
||||
if (ca == 0xff)
|
||||
blend = 0;
|
||||
sfunc = __imlib_GetSpanDrawFunction(op, dst_alpha, blend);
|
||||
if ((!pfunc) || (!sfunc))
|
||||
return;
|
||||
|
||||
xc -= clx;
|
||||
yc -= cly;
|
||||
dst += (dstw * cly) + clx;
|
||||
|
||||
col1 = color;
|
||||
a2 = a*a; b2 = b*b;
|
||||
|
||||
yy = b << 16;
|
||||
prev_y = b;
|
||||
|
||||
dx = a2 * b;
|
||||
dy = 0;
|
||||
|
||||
ty = yc - b - 2;
|
||||
by = yc + b + 1;
|
||||
lx = xc - 1;
|
||||
rx = xc;
|
||||
|
||||
tp = dst + (dstw * ty) + lx;
|
||||
bp = dst + (dstw * by) + lx;
|
||||
|
||||
while (dy < dx)
|
||||
{
|
||||
int len;
|
||||
DATA32 tmp, *tpp, *bpp;
|
||||
|
||||
y = yy >> 16;
|
||||
|
||||
if (prev_y != y)
|
||||
{
|
||||
prev_y = y;
|
||||
dx -= a2;
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
tpp = tp + 1;
|
||||
bpp = bp + 1;
|
||||
len = rx;
|
||||
if (len > clw) len = clw;
|
||||
len -= (lx + 1);
|
||||
if (lx < -1)
|
||||
{
|
||||
len += (lx + 1);
|
||||
tpp -= (lx + 1);
|
||||
bpp -= (lx + 1);
|
||||
}
|
||||
|
||||
if ( ((unsigned)(ty) < clh) && (len > 0) )
|
||||
sfunc(color, tpp, len);
|
||||
if ( ((unsigned)(by) < clh) && (len > 0) )
|
||||
sfunc(color, bpp, len);
|
||||
}
|
||||
|
||||
A_VAL(&col1) = ((yy - (y << 16)) >> 8);
|
||||
if (ca < 255)
|
||||
MULT(A_VAL(&col1), ca, A_VAL(&col1), tmp)
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(col1, tp);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(col1, tp + len);
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(col1, bp);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(col1, bp + len);
|
||||
|
||||
dy += b2;
|
||||
yy -= ((dy << 16) / dx);
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
|
||||
y = yy >> 16;
|
||||
xx = yy;
|
||||
prev_x = y;
|
||||
|
||||
dx = dy;
|
||||
|
||||
ty++;
|
||||
by--;
|
||||
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
while (ty < yc)
|
||||
{
|
||||
int len;
|
||||
DATA32 tmp, *tpp, *bpp;
|
||||
|
||||
x = xx >> 16;
|
||||
|
||||
if (prev_x != x)
|
||||
{
|
||||
prev_x = x;
|
||||
dy += b2;
|
||||
lx--; rx++;
|
||||
tp--; bp--;
|
||||
}
|
||||
|
||||
tpp = tp + 1;
|
||||
bpp = bp + 1;
|
||||
len = rx;
|
||||
if (len > clw) len = clw;
|
||||
len -= (lx + 1);
|
||||
if (lx < -1)
|
||||
{
|
||||
len += (lx + 1);
|
||||
tpp -= (lx + 1);
|
||||
bpp -= (lx + 1);
|
||||
}
|
||||
|
||||
if ( ((unsigned)(ty) < clh) && (len > 0) )
|
||||
sfunc(color, tpp, len);
|
||||
if ( ((unsigned)(by) < clh) && (len > 0) )
|
||||
sfunc(color, bpp, len);
|
||||
|
||||
A_VAL(&col1) = ((xx - (x << 16)) >> 8);
|
||||
if (ca < 255)
|
||||
MULT(A_VAL(&col1), ca, A_VAL(&col1), tmp)
|
||||
|
||||
len = rx - lx;
|
||||
|
||||
if (IN_RANGE(lx, ty, clw, clh))
|
||||
pfunc(col1, tp);
|
||||
if (IN_RANGE(rx, ty, clw, clh))
|
||||
pfunc(col1, tp + len);
|
||||
if (IN_RANGE(lx, by, clw, clh))
|
||||
pfunc(col1, bp);
|
||||
if (IN_RANGE(rx, by, clw, clh))
|
||||
pfunc(col1, bp + len);
|
||||
|
||||
dx -= a2;
|
||||
xx += ((dx << 16) / dy);
|
||||
ty++; by--;
|
||||
tp += dstw;
|
||||
bp -= dstw;
|
||||
|
||||
if ( (ty > clh) || (by < 0) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__imlib_Ellipse_DrawToImage(int xc, int yc, int a, int b, DATA32 color,
|
||||
ImlibImage *im, int clx, int cly, int clw, int clh,
|
||||
ImlibOp op, char blend, char anti_alias)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
if ((a == 0) || (b == 0))
|
||||
{
|
||||
(void) __imlib_Line_DrawToImage(xc - a, yc - b, xc + a, yc + b, color,
|
||||
im, clx, cly, clw, clh,
|
||||
op, blend, anti_alias, 0);
|
||||
return;
|
||||
}
|
||||
if (blend && (!A_VAL(&color)))
|
||||
return;
|
||||
if (clw < 0)
|
||||
return;
|
||||
if (clw == 0)
|
||||
{
|
||||
clw = im->w;
|
||||
clx = 0;
|
||||
clh = im->h;
|
||||
cly = 0;
|
||||
}
|
||||
|
||||
CLIP_RECT_TO_RECT(clx, cly, clw, clh, 0, 0, im->w, im->h);
|
||||
if ((clw < 1) || (clh < 1))
|
||||
return;
|
||||
|
||||
if (a < 0) a = -a;
|
||||
if (b < 0) b = -b;
|
||||
if (a > 65535) a = 65535;
|
||||
if (b > 65535) b = 65535;
|
||||
|
||||
w = 2 * (a + 1);
|
||||
h = 2 * (b + 1);
|
||||
x = xc - a - 1;
|
||||
y = yc - b - 1;
|
||||
if (anti_alias)
|
||||
{
|
||||
w += 2; h += 2;
|
||||
x--; y--;
|
||||
}
|
||||
|
||||
CLIP_RECT_TO_RECT(x, y, w, h, clx, cly, clw, clh);
|
||||
if ((w < 1) || (h < 1))
|
||||
return;
|
||||
|
||||
if (blend && IMAGE_HAS_ALPHA(im))
|
||||
__imlib_build_pow_lut();
|
||||
|
||||
if (anti_alias)
|
||||
__imlib_Ellipse_DrawToData_AA(xc, yc, a, b, color,
|
||||
im->data, im->w, clx, cly, clw, clh,
|
||||
op, IMAGE_HAS_ALPHA(im), blend);
|
||||
else
|
||||
__imlib_Ellipse_DrawToData(xc, yc, a, b, color,
|
||||
im->data, im->w, clx, cly, clw, clh,
|
||||
op, IMAGE_HAS_ALPHA(im), blend);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__imlib_Ellipse_FillToImage(int xc, int yc, int a, int b, DATA32 color,
|
||||
ImlibImage *im, int clx, int cly, int clw, int clh,
|
||||
ImlibOp op, char blend, char anti_alias)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
if ((a == 0) || (b == 0))
|
||||
{
|
||||
(void) __imlib_Line_DrawToImage(xc - a, yc - b, xc + a, yc + b, color,
|
||||
im, clx, cly, clw, clh,
|
||||
op, blend, anti_alias, 0);
|
||||
return;
|
||||
}
|
||||
if (blend && (!A_VAL(&color)))
|
||||
return;
|
||||
if (clw < 0)
|
||||
return;
|
||||
if (clw == 0)
|
||||
{
|
||||
clw = im->w;
|
||||
clx = 0;
|
||||
clh = im->h;
|
||||
cly = 0;
|
||||
}
|
||||
|
||||
CLIP_RECT_TO_RECT(clx, cly, clw, clh, 0, 0, im->w, im->h);
|
||||
if ((clw < 1) || (clh < 1))
|
||||
return;
|
||||
|
||||
if (a < 0) a = -a;
|
||||
if (b < 0) b = -b;
|
||||
if (a > 65535) a = 65535;
|
||||
if (b > 65535) b = 65535;
|
||||
|
||||
w = 2 * (a + 1);
|
||||
h = 2 * (b + 1);
|
||||
x = xc - a - 1;
|
||||
y = yc - b - 1;
|
||||
if (anti_alias)
|
||||
{
|
||||
w += 2; h += 2;
|
||||
x--; y--;
|
||||
}
|
||||
|
||||
CLIP_RECT_TO_RECT(x, y, w, h, clx, cly, clw, clh);
|
||||
if ((w < 1) || (h < 1))
|
||||
return;
|
||||
|
||||
if (blend && IMAGE_HAS_ALPHA(im))
|
||||
__imlib_build_pow_lut();
|
||||
|
||||
if (anti_alias)
|
||||
__imlib_Ellipse_FillToData_AA(xc, yc, a, b, color,
|
||||
im->data, im->w, clx, cly, clw, clh,
|
||||
op, IMAGE_HAS_ALPHA(im), blend);
|
||||
else
|
||||
__imlib_Ellipse_FillToData(xc, yc, a, b, color,
|
||||
im->data, im->w, clx, cly, clw, clh,
|
||||
op, IMAGE_HAS_ALPHA(im), blend);
|
||||
}
|
506
src/file.c
506
src/file.c
|
@ -1,506 +0,0 @@
|
|||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#ifdef __EMX__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include "file.h"
|
||||
|
||||
static void __imlib_FileFieldWord(char *s, int num, char *wd);
|
||||
|
||||
char *
|
||||
__imlib_FileKey(const char *file)
|
||||
{
|
||||
char *newfile;
|
||||
|
||||
newfile = malloc(strlen(file) + 1);
|
||||
if (!newfile)
|
||||
return NULL;
|
||||
newfile[0] = 0;
|
||||
{
|
||||
char *p1, *p2;
|
||||
int go;
|
||||
|
||||
go = 0;
|
||||
p1 = (char *)file;
|
||||
p2 = newfile;
|
||||
while (p1[0])
|
||||
{
|
||||
if (go)
|
||||
{
|
||||
p2[0] = p1[0];
|
||||
p2++;
|
||||
}
|
||||
if ((p1[0] == ':') && (p1[1] != ':'))
|
||||
go = 1;
|
||||
if ((p1[0] == ':') && (p1[1] == ':'))
|
||||
p1++;
|
||||
p1++;
|
||||
}
|
||||
p2[0] = p1[0];
|
||||
}
|
||||
if (newfile[0])
|
||||
return newfile;
|
||||
else
|
||||
free(newfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
__imlib_FileRealFile(const char *file)
|
||||
{
|
||||
char *newfile;
|
||||
|
||||
newfile = malloc(strlen(file) + 1);
|
||||
if (!newfile)
|
||||
return NULL;
|
||||
newfile[0] = 0;
|
||||
{
|
||||
char *p1, *p2;
|
||||
|
||||
p1 = (char *)file;
|
||||
p2 = newfile;
|
||||
while (p1[0])
|
||||
{
|
||||
if (p1[0] == ':')
|
||||
{
|
||||
if (p1[1] == ':')
|
||||
{
|
||||
p2[0] = ':';
|
||||
p2++;
|
||||
p1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
p2[0] = 0;
|
||||
return newfile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p2[0] = p1[0];
|
||||
p2++;
|
||||
}
|
||||
p1++;
|
||||
}
|
||||
p2[0] = p1[0];
|
||||
}
|
||||
return newfile;
|
||||
}
|
||||
|
||||
char *
|
||||
__imlib_FileExtension(const char *file)
|
||||
{
|
||||
char *p;
|
||||
char *fl;
|
||||
|
||||
fl = __imlib_FileRealFile(file);
|
||||
if (!fl)
|
||||
return strdup("");
|
||||
p = strrchr(file, '.');
|
||||
if (p)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = strdup(p + 1);
|
||||
free(fl);
|
||||
return ret;
|
||||
}
|
||||
free(fl);
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_FileExists(const char *s)
|
||||
{
|
||||
struct stat st;
|
||||
char *fl;
|
||||
|
||||
if ((!s) || (!*s))
|
||||
return 0;
|
||||
if (__imlib_IsRealFile(s))
|
||||
fl = strdup(s);
|
||||
else
|
||||
fl = __imlib_FileRealFile(s);
|
||||
if (!fl)
|
||||
return 0;
|
||||
if (stat(fl, &st) < 0)
|
||||
{
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
free(fl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_FileIsFile(const char *s)
|
||||
{
|
||||
struct stat st;
|
||||
char *fl;
|
||||
|
||||
if ((!s) || (!*s))
|
||||
return 0;
|
||||
if (__imlib_IsRealFile(s))
|
||||
fl = strdup(s);
|
||||
else
|
||||
fl = __imlib_FileRealFile(s);
|
||||
if (!fl)
|
||||
return 0;
|
||||
if (stat(fl, &st) < 0)
|
||||
{
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
if (S_ISREG(st.st_mode))
|
||||
{
|
||||
free(fl);
|
||||
return 1;
|
||||
}
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_FileIsDir(const char *s)
|
||||
{
|
||||
struct stat st;
|
||||
char *fl;
|
||||
|
||||
if ((!s) || (!*s))
|
||||
return 0;
|
||||
if (__imlib_IsRealFile(s))
|
||||
fl = strdup(s);
|
||||
else
|
||||
fl = __imlib_FileRealFile(s);
|
||||
if (!fl)
|
||||
return 0;
|
||||
if (stat(fl, &st) < 0)
|
||||
{
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode))
|
||||
{
|
||||
free(fl);
|
||||
return 1;
|
||||
}
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_FilePermissions(const char *s)
|
||||
{
|
||||
struct stat st;
|
||||
char *fl;
|
||||
|
||||
if ((!s) || (!*s))
|
||||
return 0;
|
||||
if (__imlib_IsRealFile(s))
|
||||
fl = strdup(s);
|
||||
else
|
||||
fl = __imlib_FileRealFile(s);
|
||||
if (!fl)
|
||||
return 0;
|
||||
if (stat(fl, &st) < 0)
|
||||
{
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
free(fl);
|
||||
return st.st_mode;
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_FileCanRead(const char *s)
|
||||
{
|
||||
char *fl;
|
||||
int val;
|
||||
|
||||
if (__imlib_IsRealFile(s))
|
||||
fl = strdup(s);
|
||||
else
|
||||
fl = __imlib_FileRealFile(s);
|
||||
if (!fl)
|
||||
return 0;
|
||||
if (!(__imlib_FilePermissions(fl) & (S_IRUSR | S_IRGRP | S_IROTH)))
|
||||
{
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = (1 + access(fl, R_OK));
|
||||
free(fl);
|
||||
return val;
|
||||
}
|
||||
|
||||
char **
|
||||
__imlib_FileDir(char *dir, int *num)
|
||||
{
|
||||
int i, dirlen;
|
||||
int done = 0;
|
||||
DIR *dirp;
|
||||
char **names;
|
||||
struct dirent *dp;
|
||||
|
||||
if ((!dir) || (!*dir))
|
||||
return (0);
|
||||
dirp = opendir(dir);
|
||||
if (!dirp)
|
||||
{
|
||||
*num = 0;
|
||||
return (NULL);
|
||||
}
|
||||
/* count # of entries in dir (worst case) */
|
||||
for (dirlen = 0; (dp = readdir(dirp)) != NULL; dirlen++);
|
||||
if (!dirlen)
|
||||
{
|
||||
closedir(dirp);
|
||||
*num = dirlen;
|
||||
return (NULL);
|
||||
}
|
||||
names = (char **)malloc(dirlen * sizeof(char *));
|
||||
|
||||
if (!names)
|
||||
return (NULL);
|
||||
|
||||
rewinddir(dirp);
|
||||
for (i = 0; i < dirlen;)
|
||||
{
|
||||
dp = readdir(dirp);
|
||||
if (!dp)
|
||||
break;
|
||||
if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
|
||||
{
|
||||
names[i] = strdup(dp->d_name);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < dirlen)
|
||||
dirlen = i; /* dir got shorter... */
|
||||
closedir(dirp);
|
||||
*num = dirlen;
|
||||
/* do a simple bubble sort here to alphanumberic it */
|
||||
while (!done)
|
||||
{
|
||||
done = 1;
|
||||
for (i = 0; i < dirlen - 1; i++)
|
||||
{
|
||||
if (strcmp(names[i], names[i + 1]) > 0)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = names[i];
|
||||
names[i] = names[i + 1];
|
||||
names[i + 1] = tmp;
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (names);
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FileFreeDirList(char **l, int num)
|
||||
{
|
||||
if (!l)
|
||||
return;
|
||||
while (num--)
|
||||
if (l[num])
|
||||
free(l[num]);
|
||||
free(l);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FileDel(char *s)
|
||||
{
|
||||
if ((!s) || (!*s))
|
||||
return;
|
||||
unlink(s);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
__imlib_IsRealFile(const char *s)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
return ((stat(s, &st) != -1) && (S_ISREG(st.st_mode)));
|
||||
}
|
||||
|
||||
time_t
|
||||
__imlib_FileModDate(const char *s)
|
||||
{
|
||||
struct stat st;
|
||||
char *fl;
|
||||
|
||||
if ((!s) || (!*s))
|
||||
return 0;
|
||||
if (__imlib_IsRealFile(s))
|
||||
fl = strdup(s);
|
||||
else
|
||||
fl = __imlib_FileRealFile(s);
|
||||
if (!fl)
|
||||
return 0;
|
||||
if (stat(fl, &st) < 0)
|
||||
{
|
||||
free(fl);
|
||||
return 0;
|
||||
}
|
||||
if (st.st_mtime > st.st_ctime)
|
||||
{
|
||||
free(fl);
|
||||
return st.st_mtime;
|
||||
}
|
||||
free(fl);
|
||||
return st.st_ctime;
|
||||
}
|
||||
|
||||
char *
|
||||
__imlib_FileHomeDir(int uid)
|
||||
{
|
||||
static int usr_uid = -1;
|
||||
static char *usr_s = NULL;
|
||||
char *s;
|
||||
struct passwd *pwd;
|
||||
|
||||
#ifndef __EMX__
|
||||
s = getenv("HOME");
|
||||
if (s)
|
||||
return strdup(s);
|
||||
if (usr_uid < 0)
|
||||
usr_uid = getuid();
|
||||
if ((uid == usr_uid) && (usr_s))
|
||||
{
|
||||
return (strdup(usr_s));
|
||||
}
|
||||
pwd = getpwuid(uid);
|
||||
if (pwd)
|
||||
{
|
||||
s = strdup(pwd->pw_dir);
|
||||
if (uid == usr_uid)
|
||||
usr_s = strdup(s);
|
||||
return (s);
|
||||
}
|
||||
#else
|
||||
if ((s = getenv("HOME")) != NULL)
|
||||
return strdup(s);
|
||||
else if ((s = getenv("TMP")) != NULL)
|
||||
return strdup(s);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets word number [num] in the string [s] and copies it into [wd] */
|
||||
/* wd is NULL terminated. If word [num] does not exist wd = "" */
|
||||
/* NB: this function now handles quotes so for a line: */
|
||||
/* Hello to "Welcome sir - may I Help" Shub Foo */
|
||||
/* Word 1 = Hello */
|
||||
/* Word 2 = to */
|
||||
/* Word 3 = Welcome sir - may I Help */
|
||||
/* Word 4 = Shub */
|
||||
/* word 5 = Foo */
|
||||
|
||||
char *
|
||||
__imlib_FileField(char *s, int field)
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
buf[0] = 0;
|
||||
__imlib_FileFieldWord(s, field + 1, buf);
|
||||
if (buf[0])
|
||||
{
|
||||
if ((!strcmp(buf, "NULL")) || (!strcmp(buf, "(null)")))
|
||||
return (NULL);
|
||||
return (strdup(buf));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
__imlib_FileFieldWord(char *s, int num, char *wd)
|
||||
{
|
||||
char *cur, *start, *end;
|
||||
int count, inword, inquote, len;
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
if (!wd)
|
||||
return;
|
||||
*wd = 0;
|
||||
if (num <= 0)
|
||||
return;
|
||||
cur = s;
|
||||
count = 0;
|
||||
inword = 0;
|
||||
inquote = 0;
|
||||
start = NULL;
|
||||
end = NULL;
|
||||
while ((*cur) && (count < num))
|
||||
{
|
||||
if (inword)
|
||||
{
|
||||
if (inquote)
|
||||
{
|
||||
if (*cur == '"')
|
||||
{
|
||||
inquote = 0;
|
||||
inword = 0;
|
||||
end = cur;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isspace(*cur))
|
||||
{
|
||||
end = cur;
|
||||
inword = 0;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isspace(*cur))
|
||||
{
|
||||
if (*cur == '"')
|
||||
{
|
||||
inquote = 1;
|
||||
start = cur + 1;
|
||||
}
|
||||
else
|
||||
start = cur;
|
||||
inword = 1;
|
||||
}
|
||||
}
|
||||
if (count == num)
|
||||
break;
|
||||
cur++;
|
||||
}
|
||||
if (!start)
|
||||
return;
|
||||
if (!end)
|
||||
end = cur;
|
||||
if (end <= start)
|
||||
return;
|
||||
len = (int)(end - start);
|
||||
if (len > 4000)
|
||||
len = 4000;
|
||||
if (len > 0)
|
||||
{
|
||||
strncpy(wd, start, len);
|
||||
wd[len] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
20
src/file.h
20
src/file.h
|
@ -1,20 +0,0 @@
|
|||
#ifndef __FILE
|
||||
#define __FILE 1
|
||||
char *__imlib_FileKey(const char *file);
|
||||
char *__imlib_FileRealFile(const char *file);
|
||||
char *__imlib_FileExtension(const char *file);
|
||||
int __imlib_FileExists(const char *s);
|
||||
int __imlib_FileIsFile(const char *s);
|
||||
int __imlib_FileIsDir(const char *s);
|
||||
char **__imlib_FileDir(char *dir, int *num);
|
||||
void __imlib_FileFreeDirList(char **l, int num);
|
||||
void __imlib_FileDel(char *s);
|
||||
time_t __imlib_FileModDate(const char *s);
|
||||
char *__imlib_FileHomeDir(int uid);
|
||||
char *__imlib_FileField(char *s, int field);
|
||||
int __imlib_FilePermissions(const char *s);
|
||||
int __imlib_FileCanRead(const char *s);
|
||||
int __imlib_IsRealFile(const char *s);
|
||||
|
||||
|
||||
#endif
|
241
src/filter.c
241
src/filter.c
|
@ -1,241 +0,0 @@
|
|||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include "filter.h"
|
||||
|
||||
/*\ Create and return an empty filter struct \*/
|
||||
ImlibFilter *
|
||||
__imlib_CreateFilter(int size)
|
||||
{
|
||||
ImlibFilter *fil;
|
||||
|
||||
fil = malloc(sizeof(ImlibFilter));
|
||||
if (size > 0)
|
||||
{
|
||||
fil->alpha.pixels = malloc(size * sizeof(ImlibFilterPixel));
|
||||
fil->red.pixels = malloc(size * sizeof(ImlibFilterPixel));
|
||||
fil->green.pixels = malloc(size * sizeof(ImlibFilterPixel));
|
||||
fil->blue.pixels = malloc(size * sizeof(ImlibFilterPixel));
|
||||
fil->alpha.size = size;
|
||||
fil->red.size = size;
|
||||
fil->green.size = size;
|
||||
fil->blue.size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
fil->alpha.pixels = 0;
|
||||
fil->red.pixels = 0;
|
||||
fil->green.pixels = 0;
|
||||
fil->blue.pixels = 0;
|
||||
fil->alpha.size = 0;
|
||||
fil->red.size = 0;
|
||||
fil->green.size = 0;
|
||||
fil->blue.size = 0;
|
||||
}
|
||||
fil->alpha.entries = 0;
|
||||
fil->red.entries = 0;
|
||||
fil->green.entries = 0;
|
||||
fil->blue.entries = 0;
|
||||
fil->alpha.div = 0;
|
||||
fil->red.div = 0;
|
||||
fil->green.div = 0;
|
||||
fil->blue.div = 0;
|
||||
fil->alpha.cons = 0;
|
||||
fil->red.cons = 0;
|
||||
fil->green.cons = 0;
|
||||
fil->blue.cons = 0;
|
||||
return fil;
|
||||
}
|
||||
|
||||
/*\ Free a filter struct \*/
|
||||
void
|
||||
__imlib_FreeFilter(ImlibFilter * fil)
|
||||
{
|
||||
free(fil->alpha.pixels);
|
||||
free(fil->red.pixels);
|
||||
free(fil->green.pixels);
|
||||
free(fil->blue.pixels);
|
||||
free(fil);
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FilterSetColor(ImlibFilterColor * fil, int x, int y,
|
||||
int a, int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
ImlibFilterPixel *pix = fil->pixels;
|
||||
|
||||
/*\ Look for an entry matching (x, y) \ */
|
||||
for (i = fil->entries; --i >= 0;)
|
||||
{
|
||||
if ((pix[i].xoff == x) && (pix[i].yoff == y))
|
||||
break;
|
||||
}
|
||||
/*\ If all zero, remove the found entry \ */
|
||||
if (!(a | r | g | b))
|
||||
{
|
||||
if (i >= 0)
|
||||
{
|
||||
while (i < fil->entries)
|
||||
{
|
||||
pix[i] = pix[i + 1];
|
||||
}
|
||||
fil->entries--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*\ No match, then make a new entry \ */
|
||||
if (i < 0)
|
||||
i = fil->entries;
|
||||
if (i >= fil->size)
|
||||
{
|
||||
fil->size += 4;
|
||||
pix = realloc(pix, (fil->size * sizeof(ImlibFilterPixel)));
|
||||
if (!pix)
|
||||
return;
|
||||
fil->pixels = pix;
|
||||
}
|
||||
if (i >= fil->entries)
|
||||
fil->entries = i + 1;
|
||||
pix[i].xoff = x;
|
||||
pix[i].yoff = y;
|
||||
pix[i].a = a;
|
||||
pix[i].r = r;
|
||||
pix[i].g = g;
|
||||
pix[i].b = b;
|
||||
}
|
||||
|
||||
/*\ Set the divisors manually \*/
|
||||
void
|
||||
__imlib_FilterDivisors(ImlibFilter * fil, int a, int r, int g, int b)
|
||||
{
|
||||
fil->alpha.div = a;
|
||||
fil->red.div = r;
|
||||
fil->green.div = g;
|
||||
fil->blue.div = b;
|
||||
}
|
||||
|
||||
/*\ Set the constants \*/
|
||||
void
|
||||
__imlib_FilterConstants(ImlibFilter * fil, int a, int r, int g, int b)
|
||||
{
|
||||
fil->alpha.cons = a;
|
||||
fil->red.cons = r;
|
||||
fil->green.cons = g;
|
||||
fil->blue.cons = b;
|
||||
}
|
||||
|
||||
static int
|
||||
__imlib_FilterCalcDiv(ImlibFilterColor * fil)
|
||||
{
|
||||
int i, ret;
|
||||
ImlibFilterPixel *pix;
|
||||
|
||||
if (fil->div)
|
||||
return fil->div;
|
||||
ret = 0;
|
||||
pix = fil->pixels;
|
||||
for (i = fil->entries; --i >= 0;)
|
||||
{
|
||||
ret += pix->a + pix->r + pix->g + pix->b;
|
||||
pix++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
__imlib_FilterGet(ImlibFilterColor * fil, DATA32 * data,
|
||||
int w, int h, int x, int y)
|
||||
{
|
||||
int i, off, ret;
|
||||
ImlibFilterPixel *pix;
|
||||
DATA32 *p;
|
||||
|
||||
ret = fil->cons;
|
||||
pix = fil->pixels;
|
||||
for (i = fil->entries; --i >= 0;)
|
||||
{
|
||||
off = x + pix->xoff;
|
||||
if (off < 0)
|
||||
off = 0;
|
||||
if (off >= w)
|
||||
off = w - 1;
|
||||
p = data + off;
|
||||
off = y + pix->yoff;
|
||||
if (off < 0)
|
||||
off = 0;
|
||||
if (off >= h)
|
||||
off = h - 1;
|
||||
p += off * w;
|
||||
ret += A_VAL(p) * pix->a + R_VAL(p) * pix->r +
|
||||
G_VAL(p) * pix->g + B_VAL(p) * pix->b;
|
||||
pix++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*\ Correct saturation from [-32768, 32767] to [0, 255] \*/
|
||||
#define SATURATE(x) ((((x) | (!((x) >> 8) - 1)) & (~((x) >> 31))) & 0xff)
|
||||
|
||||
/*\ Filter an image with the a, r, g, b filters in fil
|
||||
|*| NB: This is currently not very optimal, and could probably be improved
|
||||
\*/
|
||||
void
|
||||
__imlib_FilterImage(ImlibImage * im, ImlibFilter * fil)
|
||||
{
|
||||
int x, y, a, r, g, b, ad, rd, gd, bd;
|
||||
DATA32 *data, *p1, *p2;
|
||||
|
||||
data = malloc(im->w * im->h * sizeof(DATA32));
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
ad = __imlib_FilterCalcDiv(&fil->alpha);
|
||||
rd = __imlib_FilterCalcDiv(&fil->red);
|
||||
gd = __imlib_FilterCalcDiv(&fil->green);
|
||||
bd = __imlib_FilterCalcDiv(&fil->blue);
|
||||
|
||||
p1 = im->data;
|
||||
p2 = data;
|
||||
|
||||
for (y = 0; y < im->h; y++)
|
||||
{
|
||||
for (x = 0; x < im->w; x++)
|
||||
{
|
||||
*p2 = *p1;
|
||||
if (ad)
|
||||
{
|
||||
a = __imlib_FilterGet(&fil->alpha, im->data, im->w, im->h, x,
|
||||
y);
|
||||
a /= ad;
|
||||
A_VAL(p2) = SATURATE(a);
|
||||
}
|
||||
if (rd)
|
||||
{
|
||||
r = __imlib_FilterGet(&fil->red, im->data, im->w, im->h, x,
|
||||
y);
|
||||
r /= rd;
|
||||
R_VAL(p2) = SATURATE(r);
|
||||
}
|
||||
if (gd)
|
||||
{
|
||||
g = __imlib_FilterGet(&fil->green, im->data, im->w, im->h, x,
|
||||
y);
|
||||
g /= gd;
|
||||
G_VAL(p2) = SATURATE(g);
|
||||
}
|
||||
if (bd)
|
||||
{
|
||||
b = __imlib_FilterGet(&fil->blue, im->data, im->w, im->h, x,
|
||||
y);
|
||||
b /= bd;
|
||||
B_VAL(p2) = SATURATE(b);
|
||||
}
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
free(im->data);
|
||||
im->data = data;
|
||||
}
|
42
src/filter.h
42
src/filter.h
|
@ -1,42 +0,0 @@
|
|||
#ifndef __FILTER
|
||||
#define __FILTER 1
|
||||
|
||||
typedef struct _imlib_filter ImlibFilter;
|
||||
typedef struct _imlib_filter_color ImlibFilterColor;
|
||||
typedef struct _imlib_filter_pixel ImlibFilterPixel;
|
||||
|
||||
struct _imlib_filter_pixel
|
||||
{
|
||||
int xoff, yoff;
|
||||
int a, r, g, b;
|
||||
};
|
||||
|
||||
struct _imlib_filter_color
|
||||
{
|
||||
int size, entries;
|
||||
int div, cons;
|
||||
ImlibFilterPixel *pixels;
|
||||
};
|
||||
|
||||
struct _imlib_filter
|
||||
{
|
||||
ImlibFilterColor alpha, red, green, blue;
|
||||
};
|
||||
|
||||
ImlibFilter *
|
||||
__imlib_CreateFilter(int size);
|
||||
void
|
||||
__imlib_FreeFilter(ImlibFilter *fil);
|
||||
void
|
||||
__imlib_FilterSet(ImlibFilterColor *fil, int x, int y,
|
||||
int a, int r, int g, int b);
|
||||
void
|
||||
__imlib_FilterSetColor(ImlibFilterColor * fil, int x, int y,
|
||||
int a, int r, int g, int b);
|
||||
void
|
||||
__imlib_FilterDivisors(ImlibFilter *fil, int a, int r, int g, int b);
|
||||
void
|
||||
__imlib_FilterConstants(ImlibFilter *fil, int a, int r, int g, int b);
|
||||
void
|
||||
__imlib_FilterImage(ImlibImage *im, ImlibFilter *fil);
|
||||
#endif
|
126
src/font.h
126
src/font.h
|
@ -1,126 +0,0 @@
|
|||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
|
||||
/* TODO separate fonts and data stuff */
|
||||
|
||||
typedef struct _Imlib_Font ImlibFont;
|
||||
typedef struct _Imlib_Font_Glyph Imlib_Font_Glyph;
|
||||
|
||||
typedef struct _Imlib_Object_List Imlib_Object_List;
|
||||
typedef struct _Imlib_Hash Imlib_Hash;
|
||||
typedef struct _Imlib_Hash_El Imlib_Hash_El;
|
||||
|
||||
struct _Imlib_Object_List
|
||||
{
|
||||
Imlib_Object_List *next, *prev;
|
||||
Imlib_Object_List *last;
|
||||
};
|
||||
|
||||
struct _Imlib_Hash
|
||||
{
|
||||
int population;
|
||||
Imlib_Object_List *buckets[256];
|
||||
};
|
||||
|
||||
struct _Imlib_Hash_El
|
||||
{
|
||||
Imlib_Object_List _list_data;
|
||||
char *key;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct _Imlib_Font
|
||||
{
|
||||
Imlib_Object_List _list_data;
|
||||
char *name;
|
||||
char *file;
|
||||
int size;
|
||||
|
||||
struct
|
||||
{
|
||||
FT_Face face;
|
||||
}
|
||||
ft;
|
||||
|
||||
Imlib_Hash *glyphs;
|
||||
|
||||
int usage;
|
||||
|
||||
int references;
|
||||
|
||||
};
|
||||
|
||||
struct _Imlib_Font_Glyph
|
||||
{
|
||||
FT_Glyph glyph;
|
||||
FT_BitmapGlyph glyph_out;
|
||||
};
|
||||
|
||||
/* functions */
|
||||
|
||||
void imlib_font_init(void);
|
||||
int imlib_font_ascent_get(ImlibFont * fn);
|
||||
int imlib_font_descent_get(ImlibFont * fn);
|
||||
int imlib_font_max_ascent_get(ImlibFont * fn);
|
||||
int imlib_font_max_descent_get(ImlibFont * fn);
|
||||
int imlib_font_get_line_advance(ImlibFont * fn);
|
||||
int imlib_font_utf8_get_next(unsigned char *buf, int *iindex);
|
||||
void imlib_font_add_font_path(const char *path);
|
||||
void imlib_font_del_font_path(const char *path);
|
||||
int imlib_font_path_exists(const char *path);
|
||||
char **imlib_font_list_font_path(int *num_ret);
|
||||
char **imlib_font_list_fonts(int *num_ret);
|
||||
|
||||
ImlibFont *imlib_font_load_joined(const char *name);
|
||||
ImlibFont *imlib_font_load(const char *name, int size);
|
||||
void imlib_font_free(ImlibFont * fn);
|
||||
int imlib_font_cache_get(void);
|
||||
void imlib_font_cache_set(int size);
|
||||
void imlib_font_flush(void);
|
||||
void imlib_font_modify_cache_by(ImlibFont * fn, int dir);
|
||||
void imlib_font_modify_cache_by(ImlibFont * fn, int dir);
|
||||
void imlib_font_flush_last(void);
|
||||
ImlibFont *imlib_font_find(const char *name, int size);
|
||||
|
||||
void imlib_font_query_size(ImlibFont * fn, const char *text,
|
||||
int *w, int *h);
|
||||
int imlib_font_query_inset(ImlibFont * fn, const char *text);
|
||||
void imlib_font_query_advance(ImlibFont * fn, const char *text,
|
||||
int *h_adv, int *v_adv);
|
||||
int imlib_font_query_char_coords(ImlibFont * fn,
|
||||
const char *text, int pos,
|
||||
int *cx, int *cy, int *cw,
|
||||
int *ch);
|
||||
int imlib_font_query_text_at_pos(ImlibFont * fn,
|
||||
const char *text, int x, int y,
|
||||
int *cx, int *cy, int *cw,
|
||||
int *ch);
|
||||
|
||||
Imlib_Font_Glyph *imlib_font_cache_glyph_get(ImlibFont * fn, FT_UInt index);
|
||||
void imlib_render_str(ImlibImage * im, ImlibFont * f, int drx,
|
||||
int dry, const char *text, DATA8 r,
|
||||
DATA8 g, DATA8 b, DATA8 a, char dir,
|
||||
double angle, int *retw, int *reth,
|
||||
int blur, int *nextx, int *nexty,
|
||||
ImlibOp op, int clx, int cly, int clw,
|
||||
int clh);
|
||||
void imlib_font_draw(ImlibImage * dst, DATA32 col,
|
||||
ImlibFont * fn, int x, int y,
|
||||
const char *text, int *nextx, int *nexty,
|
||||
int clx, int cly, int clw, int clh);
|
||||
|
||||
/* data manipulation */
|
||||
|
||||
void *imlib_object_list_prepend(void *in_list, void *in_item);
|
||||
void *imlib_object_list_remove(void *in_list, void *in_item);
|
||||
Imlib_Hash *imlib_hash_add(Imlib_Hash * hash, const char *key,
|
||||
const void *data);
|
||||
void *imlib_hash_find(Imlib_Hash * hash, const char *key);
|
||||
void imlib_hash_free(Imlib_Hash * hash);
|
||||
void imlib_hash_foreach(Imlib_Hash * hash,
|
||||
int (*func) (Imlib_Hash * hash,
|
||||
const char *key, void *data,
|
||||
void *fdata),
|
||||
const void *fdata);
|
421
src/font_draw.c
421
src/font_draw.c
|
@ -1,421 +0,0 @@
|
|||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include "font.h"
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "file.h"
|
||||
#include "updates.h"
|
||||
#include "rgbadraw.h"
|
||||
#include "rotate.h"
|
||||
|
||||
extern FT_Library ft_lib;
|
||||
|
||||
Imlib_Font_Glyph *
|
||||
imlib_font_cache_glyph_get(ImlibFont * fn, FT_UInt index)
|
||||
{
|
||||
Imlib_Font_Glyph *fg;
|
||||
char key[6];
|
||||
FT_Error error;
|
||||
|
||||
key[0] = ((index) & 0x7f) + 1;
|
||||
key[1] = ((index >> 7) & 0x7f) + 1;
|
||||
key[2] = ((index >> 14) & 0x7f) + 1;
|
||||
key[3] = ((index >> 21) & 0x7f) + 1;
|
||||
key[4] = ((index >> 28) & 0x0f) + 1;
|
||||
key[5] = 0;
|
||||
|
||||
fg = imlib_hash_find(fn->glyphs, key);
|
||||
if (fg)
|
||||
return fg;
|
||||
|
||||
error = FT_Load_Glyph(fn->ft.face, index, FT_LOAD_NO_BITMAP);
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
fg = malloc(sizeof(struct _Imlib_Font_Glyph));
|
||||
if (!fg)
|
||||
return NULL;
|
||||
memset(fg, 0, (sizeof(struct _Imlib_Font_Glyph)));
|
||||
|
||||
error = FT_Get_Glyph(fn->ft.face->glyph, &(fg->glyph));
|
||||
if (error)
|
||||
{
|
||||
free(fg);
|
||||
return NULL;
|
||||
}
|
||||
if (fg->glyph->format != ft_glyph_format_bitmap)
|
||||
{
|
||||
error = FT_Glyph_To_Bitmap(&(fg->glyph), ft_render_mode_normal, 0, 1);
|
||||
if (error)
|
||||
{
|
||||
FT_Done_Glyph(fg->glyph);
|
||||
free(fg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
fg->glyph_out = (FT_BitmapGlyph) fg->glyph;
|
||||
|
||||
fn->glyphs = imlib_hash_add(fn->glyphs, key, fg);
|
||||
return fg;
|
||||
}
|
||||
|
||||
void
|
||||
imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
|
||||
const char *text, DATA8 r, DATA8 g, DATA8 b, DATA8 a,
|
||||
char dir, double angle, int *retw, int *reth, int blur,
|
||||
int *nextx, int *nexty, ImlibOp op, int clx, int cly,
|
||||
int clw, int clh)
|
||||
{
|
||||
int w, h, ascent;
|
||||
ImlibImage *im2;
|
||||
DATA32 *data, col;
|
||||
int nx, ny, tmp;
|
||||
|
||||
imlib_font_query_advance(fn, text, &w, &h);
|
||||
|
||||
data = malloc(w * h * sizeof(DATA32));
|
||||
if (!data)
|
||||
return;
|
||||
memset(data, 0, w * h * sizeof(DATA32));
|
||||
/* TODO check if this is the right way of rendering. Esp for huge sizes */
|
||||
im2 = __imlib_CreateImage(w, h, data);
|
||||
if (!im2)
|
||||
{
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
SET_FLAG(im2->flags, F_HAS_ALPHA);
|
||||
|
||||
/* TODO check for endianess */
|
||||
col = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
ascent = imlib_font_max_ascent_get(fn);
|
||||
|
||||
imlib_font_draw(im2, col, fn, 0, ascent, text, &nx, &ny, clx, cly, clw, clh);
|
||||
|
||||
/* OK, now we have small ImlibImage with text rendered,
|
||||
* have to blend it on im */
|
||||
|
||||
if (blur > 0)
|
||||
__imlib_BlurImage(im2, blur);
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0: /* to right */
|
||||
angle = 0.0;
|
||||
break;
|
||||
case 1: /* to left */
|
||||
angle = 0.0;
|
||||
__imlib_FlipImageBoth(im2);
|
||||
break;
|
||||
case 2: /* to down */
|
||||
angle = 0.0;
|
||||
__imlib_FlipImageDiagonal(im2, 1);
|
||||
break;
|
||||
case 3: /* to up */
|
||||
angle = 0.0;
|
||||
__imlib_FlipImageDiagonal(im2, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (angle == 0.0)
|
||||
{
|
||||
__imlib_BlendImageToImage(im2, im, 0, 1, IMAGE_HAS_ALPHA(im), 0, 0,
|
||||
im2->w, im2->h, drx, dry, im2->w, im2->h,
|
||||
NULL, op, clx, cly, clw, clh);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xx, yy;
|
||||
double sa, ca;
|
||||
|
||||
sa = sin(angle);
|
||||
ca = cos(angle);
|
||||
xx = drx;
|
||||
yy = dry;
|
||||
if (sa > 0.0)
|
||||
xx += sa * im2->h;
|
||||
else
|
||||
yy -= sa * im2->w;
|
||||
if (ca < 0.0)
|
||||
{
|
||||
xx -= ca * im2->w;
|
||||
yy -= ca * im2->h;
|
||||
}
|
||||
__imlib_BlendImageToImageSkewed(im2, im, 1, 1, IMAGE_HAS_ALPHA(im), 0,
|
||||
0, im2->w, im2->h, xx, yy, (w * ca),
|
||||
(w * sa), 0, 0, NULL, op, clx, cly, clw,
|
||||
clh);
|
||||
}
|
||||
|
||||
__imlib_FreeImage(im2);
|
||||
|
||||
/* finally deal with return values */
|
||||
switch (dir)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
if (retw)
|
||||
*retw = w;
|
||||
if (reth)
|
||||
*reth = h;
|
||||
if (nextx)
|
||||
*nextx = nx;
|
||||
if (nexty)
|
||||
*nexty = ny;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if (retw)
|
||||
*retw = h;
|
||||
if (reth)
|
||||
*reth = w;
|
||||
if (nextx)
|
||||
*nextx = ny;
|
||||
if (nexty)
|
||||
*nexty = nx;
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
double sa, ca;
|
||||
double x1, x2, xt;
|
||||
double y1, y2, yt;
|
||||
|
||||
sa = sin(angle);
|
||||
ca = cos(angle);
|
||||
|
||||
x1 = x2 = 0.0;
|
||||
xt = ca * w;
|
||||
if (xt < x1)
|
||||
x1 = xt;
|
||||
if (xt > x2)
|
||||
x2 = xt;
|
||||
xt = -(sa * h);
|
||||
if (xt < x1)
|
||||
x1 = xt;
|
||||
if (xt > x2)
|
||||
x2 = xt;
|
||||
xt = ca * w - sa * h;
|
||||
if (xt < x1)
|
||||
x1 = xt;
|
||||
if (xt > x2)
|
||||
x2 = xt;
|
||||
w = (int)(x2 - x1);
|
||||
|
||||
y1 = y2 = 0.0;
|
||||
yt = sa * w;
|
||||
if (yt < y1)
|
||||
y1 = yt;
|
||||
if (yt > y2)
|
||||
y2 = yt;
|
||||
yt = ca * h;
|
||||
if (yt < y1)
|
||||
y1 = yt;
|
||||
if (yt > y2)
|
||||
y2 = yt;
|
||||
yt = sa * w + ca * h;
|
||||
if (yt < y1)
|
||||
y1 = yt;
|
||||
if (yt > y2)
|
||||
y2 = yt;
|
||||
h = (int)(y2 - y1);
|
||||
}
|
||||
if (retw)
|
||||
*retw = w;
|
||||
if (reth)
|
||||
*reth = h;
|
||||
if (nextx)
|
||||
*nextx = nx;
|
||||
if (nexty)
|
||||
*nexty = ny;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO this function is purely my art -- check once more */
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y,
|
||||
const char *text, int *nextx, int *nexty, int clx, int cly,
|
||||
int clw, int clh)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int chr;
|
||||
FT_UInt prev_index;
|
||||
int ext_x, ext_y, ext_w, ext_h;
|
||||
DATA32 *im;
|
||||
int im_w, im_h;
|
||||
int lut[256];
|
||||
int ii;
|
||||
|
||||
im = dst->data;
|
||||
im_w = dst->w;
|
||||
im_h = dst->h;
|
||||
|
||||
ext_x = 0;
|
||||
ext_y = 0;
|
||||
ext_w = im_w;
|
||||
ext_h = im_h;
|
||||
|
||||
if (clw)
|
||||
{
|
||||
ext_x = clx;
|
||||
ext_y = cly;
|
||||
ext_w = clw;
|
||||
ext_h = clh;
|
||||
}
|
||||
if (ext_x < 0)
|
||||
{
|
||||
ext_w += ext_x;
|
||||
ext_x = 0;
|
||||
}
|
||||
if (ext_y < 0)
|
||||
{
|
||||
ext_h += ext_y;
|
||||
ext_y = 0;
|
||||
}
|
||||
if ((ext_x + ext_w) > im_w)
|
||||
ext_w = im_w - ext_x;
|
||||
if ((ext_y + ext_h) > im_h)
|
||||
ext_h = im_h - ext_y;
|
||||
|
||||
if (ext_w <= 0)
|
||||
return;
|
||||
if (ext_h <= 0)
|
||||
return;
|
||||
|
||||
for (ii = 0; ii < 256; ii++)
|
||||
{
|
||||
lut[ii] = (col & 0x00ffffff); /* TODO check endianess */
|
||||
lut[ii] |= ((((ii + 1) * (col >> 24)) >> 8) << 24);
|
||||
}
|
||||
|
||||
pen_x = x << 8;
|
||||
pen_y = y << 8;
|
||||
use_kerning = FT_HAS_KERNING(fn->ft.face);
|
||||
prev_index = 0;
|
||||
for (chr = 0; text[chr];)
|
||||
{
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
int chr_x, chr_y;
|
||||
int gl;
|
||||
|
||||
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0)
|
||||
break;
|
||||
index = FT_Get_Char_Index(fn->ft.face, gl);
|
||||
if ((use_kerning) && (prev_index) && (index))
|
||||
{
|
||||
FT_Vector delta;
|
||||
|
||||
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
|
||||
&delta);
|
||||
pen_x += delta.x << 2;
|
||||
}
|
||||
fg = imlib_font_cache_glyph_get(fn, index);
|
||||
if (!fg)
|
||||
continue;
|
||||
|
||||
chr_x = (pen_x + (fg->glyph_out->left << 8)) >> 8;
|
||||
chr_y = (pen_y + (fg->glyph_out->top << 8)) >> 8;
|
||||
|
||||
if (chr_x < (ext_x + ext_w))
|
||||
{
|
||||
DATA8 *data;
|
||||
int i, j, w, h;
|
||||
|
||||
data = fg->glyph_out->bitmap.buffer;
|
||||
j = fg->glyph_out->bitmap.pitch;
|
||||
w = fg->glyph_out->bitmap.width;
|
||||
if (j < w)
|
||||
j = w;
|
||||
h = fg->glyph_out->bitmap.rows;
|
||||
if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
|
||||
&& (fg->glyph_out->bitmap.num_grays == 256))
|
||||
{
|
||||
if ((j > 0) && (chr_x + w > ext_x))
|
||||
{
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
int dx, dy;
|
||||
int in_x, in_w;
|
||||
|
||||
in_x = 0;
|
||||
in_w = 0;
|
||||
dx = chr_x;
|
||||
dy = y - (chr_y - i - y);
|
||||
if ((dx < (ext_x + ext_w)) && (dy >= (ext_y))
|
||||
&& (dy < (ext_y + ext_h)))
|
||||
{
|
||||
if (dx + w > (ext_x + ext_w))
|
||||
in_w += (dx + w) - (ext_x + ext_w);
|
||||
if (dx < ext_x)
|
||||
{
|
||||
in_w += ext_x - dx;
|
||||
in_x = ext_x - dx;
|
||||
dx = ext_x;
|
||||
}
|
||||
if (in_w < w)
|
||||
{
|
||||
DATA8 *src_ptr;
|
||||
DATA32 *dst_ptr;
|
||||
DATA32 *dst_end_ptr;
|
||||
|
||||
src_ptr = data + (i * j) + in_x;
|
||||
dst_ptr = im + (dy * im_w) + dx;
|
||||
dst_end_ptr = dst_ptr + w - in_w;
|
||||
|
||||
while (dst_ptr < dst_end_ptr)
|
||||
{
|
||||
/* FIXME Oops! change this op */
|
||||
if (!*dst_ptr)
|
||||
*dst_ptr =
|
||||
lut[(unsigned char)*src_ptr];
|
||||
else if (*src_ptr)
|
||||
{
|
||||
/* very rare case - I've never seen symbols
|
||||
* overlapped by kerning */
|
||||
int tmp;
|
||||
|
||||
tmp =
|
||||
(*dst_ptr >> 24) +
|
||||
(lut
|
||||
[(unsigned char)*src_ptr]
|
||||
>> 24);
|
||||
tmp = (tmp > 256) ? 256 : tmp;
|
||||
*dst_ptr &= 0x00ffffff;
|
||||
*dst_ptr |= (tmp << 24);
|
||||
}
|
||||
|
||||
dst_ptr++;
|
||||
src_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
pen_x += fg->glyph->advance.x >> 8;
|
||||
prev_index = index;
|
||||
}
|
||||
|
||||
if (nextx)
|
||||
*nextx = (pen_x >> 8) - x;
|
||||
if (nexty)
|
||||
*nexty = imlib_font_get_line_advance(fn);
|
||||
}
|
431
src/font_load.c
431
src/font_load.c
|
@ -1,431 +0,0 @@
|
|||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include "font.h"
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "file.h"
|
||||
#include "updates.h"
|
||||
#include "rgbadraw.h"
|
||||
#include "rotate.h"
|
||||
|
||||
extern FT_Library ft_lib;
|
||||
|
||||
static int font_cache_usage = 0;
|
||||
static int font_cache = 0;
|
||||
static char **fpath = NULL;
|
||||
static int fpath_num = 0;
|
||||
static Imlib_Object_List *fonts = NULL;
|
||||
|
||||
static int font_modify_cache_cb(Imlib_Hash * hash, const char *key,
|
||||
void *data, void *fdata);
|
||||
static int font_flush_free_glyph_cb(Imlib_Hash * hash, const char *key,
|
||||
void *data, void *fdata);
|
||||
|
||||
/* FIXME now! listdir() from evas_object_text.c */
|
||||
|
||||
/* separate fontname and size, find font file, start imlib_font_load() then */
|
||||
ImlibFont *
|
||||
imlib_font_load_joined(const char *fontname)
|
||||
{
|
||||
int j, size;
|
||||
char *name = NULL, *file = NULL, *tmp = NULL;
|
||||
ImlibFont *fn;
|
||||
|
||||
/* split font name (in format name/size) */
|
||||
for (j = strlen(fontname) - 1; (j >= 0) && (fontname[j] != '/'); j--);
|
||||
/* no "/" in font after the first char */
|
||||
if (j <= 0)
|
||||
return NULL;
|
||||
/* get size */
|
||||
size = atoi(&(fontname[j + 1]));
|
||||
/* split name in front off */
|
||||
name = malloc((j + 1) * sizeof(char));
|
||||
memcpy(name, fontname, j);
|
||||
name[j] = 0;
|
||||
/* find file if it exists */
|
||||
tmp = malloc(strlen(name) + 4 + 1);
|
||||
if (!tmp)
|
||||
{
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
sprintf(tmp, "%s.ttf", name);
|
||||
if (__imlib_FileIsFile(tmp))
|
||||
file = strdup(tmp);
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "%s.TTF", name);
|
||||
if (__imlib_FileIsFile(tmp))
|
||||
file = strdup(tmp);
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "%s", name);
|
||||
if (__imlib_FileIsFile(tmp))
|
||||
file = strdup(tmp);
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
if (!file)
|
||||
{
|
||||
for (j = 0; (j < fpath_num) && (!file); j++)
|
||||
{
|
||||
tmp = malloc(strlen(fpath[j]) + 1 + strlen(name) + 4 + 1);
|
||||
if (!tmp)
|
||||
{
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "%s/%s.ttf", fpath[j], name);
|
||||
if (__imlib_FileIsFile(tmp))
|
||||
file = strdup(tmp);
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "%s/%s.TTF", fpath[j], name);
|
||||
if (__imlib_FileIsFile(tmp))
|
||||
file = strdup(tmp);
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "%s/%s", fpath[j], name);
|
||||
if (__imlib_FileIsFile(tmp))
|
||||
file = strdup(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
/* didnt find a file? abort */
|
||||
if (!file)
|
||||
return NULL;
|
||||
fn = imlib_font_load(file, size);
|
||||
free(file);
|
||||
return fn;
|
||||
}
|
||||
|
||||
ImlibFont *
|
||||
imlib_font_load(const char *name, int size)
|
||||
{
|
||||
int error;
|
||||
ImlibFont *fn;
|
||||
char *file;
|
||||
|
||||
fn = imlib_font_find(name, size);
|
||||
if (fn)
|
||||
return fn;
|
||||
|
||||
imlib_font_init();
|
||||
|
||||
fn = malloc(sizeof(ImlibFont));
|
||||
file = (char *)name;
|
||||
|
||||
error = FT_New_Face(ft_lib, file, 0, &(fn->ft.face));
|
||||
if (error)
|
||||
{
|
||||
free(fn);
|
||||
return NULL;
|
||||
}
|
||||
error = FT_Set_Char_Size(fn->ft.face, 0, (size * 64), 96, 96);
|
||||
if (error)
|
||||
error = FT_Set_Pixel_Sizes(fn->ft.face, 0, size);
|
||||
if (error)
|
||||
{
|
||||
int i;
|
||||
int chosen_size = 0;
|
||||
int chosen_width = 0;
|
||||
|
||||
for (i = 0; i < fn->ft.face->num_fixed_sizes; i++)
|
||||
{
|
||||
int s;
|
||||
int d, cd;
|
||||
|
||||
s = fn->ft.face->available_sizes[i].height;
|
||||
cd = chosen_size - size;
|
||||
if (cd < 0)
|
||||
cd = -cd;
|
||||
d = s - size;
|
||||
if (d < 0)
|
||||
d = -d;
|
||||
if (d < cd)
|
||||
{
|
||||
chosen_width = fn->ft.face->available_sizes[i].width;
|
||||
chosen_size = s;
|
||||
}
|
||||
if (d == 0)
|
||||
break;
|
||||
}
|
||||
error = FT_Set_Pixel_Sizes(fn->ft.face, chosen_width, chosen_size);
|
||||
if (error)
|
||||
{
|
||||
/* couldn't choose the size anyway... what now? */
|
||||
}
|
||||
}
|
||||
|
||||
error = FT_Select_Charmap(fn->ft.face, ft_encoding_unicode);
|
||||
if (error)
|
||||
{
|
||||
}
|
||||
|
||||
fn->file = strdup(file);
|
||||
fn->name = strdup(file);
|
||||
fn->size = size;
|
||||
|
||||
fn->glyphs = NULL;
|
||||
|
||||
fn->usage = 0;
|
||||
|
||||
fn->references = 1;
|
||||
|
||||
fonts = imlib_object_list_prepend(fonts, fn);
|
||||
return fn;
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_free(ImlibFont * fn)
|
||||
{
|
||||
fn->references--;
|
||||
if (fn->references == 0)
|
||||
{
|
||||
imlib_font_modify_cache_by(fn, 1);
|
||||
imlib_font_flush();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
font_modify_cache_cb(Imlib_Hash * hash, const char *key, void *data,
|
||||
void *fdata)
|
||||
{
|
||||
int *dir;
|
||||
Imlib_Font_Glyph *fg;
|
||||
|
||||
fg = data;
|
||||
dir = fdata;
|
||||
font_cache_usage += (*dir) * ((fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows) + sizeof(Imlib_Font_Glyph) + sizeof(Imlib_Object_List) + 400); /* fudge values */
|
||||
return 1;
|
||||
hash = 0;
|
||||
key = 0;
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_modify_cache_by(ImlibFont * fn, int dir)
|
||||
{
|
||||
int sz_name = 0, sz_file = 0, sz_hash = 0;
|
||||
|
||||
if (fn->name)
|
||||
sz_name = strlen(fn->name);
|
||||
if (fn->file)
|
||||
sz_file = strlen(fn->file);
|
||||
if (fn->glyphs)
|
||||
sz_hash = sizeof(Imlib_Hash);
|
||||
imlib_hash_foreach(fn->glyphs, font_modify_cache_cb, &dir);
|
||||
font_cache_usage += dir * (sizeof(ImlibFont) + sz_name + sz_file + sz_hash + sizeof(FT_FaceRec) + 16384); /* fudge values */
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_cache_get(void)
|
||||
{
|
||||
return font_cache;
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_cache_set(int size)
|
||||
{
|
||||
font_cache = size;
|
||||
imlib_font_flush();
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_flush(void)
|
||||
{
|
||||
if (font_cache_usage < font_cache)
|
||||
return;
|
||||
while (font_cache_usage > font_cache)
|
||||
imlib_font_flush_last();
|
||||
}
|
||||
|
||||
static int
|
||||
font_flush_free_glyph_cb(Imlib_Hash * hash, const char *key, void *data,
|
||||
void *fdata)
|
||||
{
|
||||
Imlib_Font_Glyph *fg;
|
||||
|
||||
fg = data;
|
||||
FT_Done_Glyph(fg->glyph);
|
||||
free(fg);
|
||||
return 1;
|
||||
hash = 0;
|
||||
key = 0;
|
||||
fdata = 0;
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_flush_last(void)
|
||||
{
|
||||
Imlib_Object_List *l;
|
||||
ImlibFont *fn = NULL;
|
||||
|
||||
for (l = fonts; l; l = l->next)
|
||||
{
|
||||
ImlibFont *fn_tmp;
|
||||
|
||||
fn_tmp = (ImlibFont *) l;
|
||||
if (fn_tmp->references == 0)
|
||||
fn = fn_tmp;
|
||||
}
|
||||
if (!fn)
|
||||
return;
|
||||
|
||||
fonts = imlib_object_list_remove(fonts, fn);
|
||||
imlib_font_modify_cache_by(fn, -1);
|
||||
|
||||
imlib_hash_foreach(fn->glyphs, font_flush_free_glyph_cb, NULL);
|
||||
imlib_hash_free(fn->glyphs);
|
||||
|
||||
if (fn->file)
|
||||
free(fn->file);
|
||||
if (fn->name)
|
||||
free(fn->name);
|
||||
FT_Done_Face(fn->ft.face);
|
||||
free(fn);
|
||||
}
|
||||
|
||||
ImlibFont *
|
||||
imlib_font_find(const char *name, int size)
|
||||
{
|
||||
Imlib_Object_List *l;
|
||||
|
||||
for (l = fonts; l; l = l->next)
|
||||
{
|
||||
ImlibFont *fn;
|
||||
|
||||
fn = (ImlibFont *) l;
|
||||
if ((fn->size == size) && (!strcmp(name, fn->name)))
|
||||
{
|
||||
if (fn->references == 0)
|
||||
imlib_font_modify_cache_by(fn, -1);
|
||||
fn->references++;
|
||||
fonts = imlib_object_list_remove(fonts, fn);
|
||||
fonts = imlib_object_list_prepend(fonts, fn);
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* font pathes */
|
||||
void
|
||||
imlib_font_add_font_path(const char *path)
|
||||
{
|
||||
fpath_num++;
|
||||
if (!fpath)
|
||||
fpath = malloc(sizeof(char *));
|
||||
else
|
||||
fpath = realloc(fpath, (fpath_num * sizeof(char *)));
|
||||
fpath[fpath_num - 1] = strdup(path);
|
||||
}
|
||||
|
||||
void
|
||||
imlib_font_del_font_path(const char *path)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < fpath_num; i++)
|
||||
{
|
||||
if (!strcmp(path, fpath[i]))
|
||||
{
|
||||
if (fpath[i])
|
||||
free(fpath[i]);
|
||||
fpath_num--;
|
||||
for (j = i; j < fpath_num; j++)
|
||||
fpath[j] = fpath[j + 1];
|
||||
if (fpath_num > 0)
|
||||
fpath = realloc(fpath, fpath_num * sizeof(char *));
|
||||
else
|
||||
{
|
||||
free(fpath);
|
||||
fpath = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_path_exists(const char *path)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fpath_num; i++)
|
||||
{
|
||||
if (!strcmp(path, fpath[i]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **
|
||||
imlib_font_list_font_path(int *num_ret)
|
||||
{
|
||||
*num_ret = fpath_num;
|
||||
return fpath;
|
||||
}
|
||||
|
||||
/* fonts list */
|
||||
char **
|
||||
imlib_font_list_fonts(int *num_ret)
|
||||
{
|
||||
int i, j, d, l = 0;
|
||||
char **list = NULL, **dir, *path;
|
||||
FT_Error error;
|
||||
char *p;
|
||||
|
||||
imlib_font_init();
|
||||
|
||||
for (i = 0; i < fpath_num; i++)
|
||||
{
|
||||
dir = __imlib_FileDir(fpath[i], &d);
|
||||
if (dir)
|
||||
{
|
||||
for (j = 0; j < d; j++)
|
||||
{
|
||||
path = malloc(strlen(fpath[i]) + strlen(dir[j]) + 2);
|
||||
sprintf(path, "%s/%s", fpath[i], dir[j]);
|
||||
/* trim .ttf if it is there */
|
||||
if ((p = strrchr(dir[j], '.')))
|
||||
*p = '\0';
|
||||
if (!__imlib_ItemInList(list, l, dir[j]))
|
||||
{
|
||||
if (__imlib_FileIsFile(path))
|
||||
{
|
||||
FT_Face f;
|
||||
|
||||
error = FT_New_Face(ft_lib, path, 0, &f);
|
||||
if (!error)
|
||||
{
|
||||
FT_Done_Face(f);
|
||||
l++;
|
||||
if (list)
|
||||
list = realloc(list, sizeof(char *) * l);
|
||||
else
|
||||
list = malloc(sizeof(char *));
|
||||
list[l - 1] = strdup(dir[j]);
|
||||
}
|
||||
free(dir[j]);
|
||||
}
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
free(dir);
|
||||
}
|
||||
}
|
||||
*num_ret = l;
|
||||
return list;
|
||||
}
|
418
src/font_main.c
418
src/font_main.c
|
@ -1,418 +0,0 @@
|
|||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include "font.h"
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "file.h"
|
||||
#include "updates.h"
|
||||
#include "rgbadraw.h"
|
||||
#include "rotate.h"
|
||||
|
||||
FT_Library ft_lib;
|
||||
|
||||
static int imlib_hash_gen(const char *key);
|
||||
static int imlib_list_alloc_error(void);
|
||||
|
||||
static int _imlib_hash_alloc_error = 0;
|
||||
static int _imlib_list_alloc_error = 0;
|
||||
|
||||
void
|
||||
imlib_font_init(void)
|
||||
{
|
||||
static int initialised = 0;
|
||||
int error;
|
||||
|
||||
if (initialised)
|
||||
return;
|
||||
error = FT_Init_FreeType(&ft_lib);
|
||||
if (error)
|
||||
return;
|
||||
initialised = 1;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_ascent_get(ImlibFont * fn)
|
||||
{
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
val = (int)fn->ft.face->ascender;
|
||||
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct
|
||||
* val */
|
||||
ret =
|
||||
(val * fn->ft.face->size->metrics.y_scale) /
|
||||
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_descent_get(ImlibFont * fn)
|
||||
{
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
val = -(int)fn->ft.face->descender;
|
||||
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct
|
||||
* val */
|
||||
ret =
|
||||
(val * fn->ft.face->size->metrics.y_scale) /
|
||||
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_max_ascent_get(ImlibFont * fn)
|
||||
{
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
val = (int)fn->ft.face->bbox.yMax;
|
||||
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct
|
||||
* val */
|
||||
ret =
|
||||
(val * fn->ft.face->size->metrics.y_scale) /
|
||||
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_max_descent_get(ImlibFont * fn)
|
||||
{
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
val = (int)fn->ft.face->bbox.yMin;
|
||||
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct
|
||||
* val */
|
||||
ret =
|
||||
(val * fn->ft.face->size->metrics.y_scale) /
|
||||
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_get_line_advance(ImlibFont * fn)
|
||||
{
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
val = (int)fn->ft.face->height;
|
||||
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct
|
||||
* val */
|
||||
ret =
|
||||
(val * fn->ft.face->size->metrics.y_scale) /
|
||||
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_font_utf8_get_next(unsigned char *buf, int *iindex)
|
||||
{
|
||||
/* Reads UTF8 bytes from @buf, starting at *@index and returns the code
|
||||
* point of the next valid code point. @index is updated ready for the
|
||||
* next call.
|
||||
*
|
||||
* * Returns 0 to indicate an error (e.g. invalid UTF8) */
|
||||
|
||||
int index = *iindex, r;
|
||||
unsigned char d = buf[index++], d2, d3, d4;
|
||||
|
||||
if (!d)
|
||||
return 0;
|
||||
if (d < 0x80)
|
||||
{
|
||||
*iindex = index;
|
||||
return d;
|
||||
}
|
||||
if ((d & 0xe0) == 0xc0)
|
||||
{
|
||||
/* 2 byte */
|
||||
d2 = buf[index++];
|
||||
if ((d2 & 0xc0) != 0x80)
|
||||
return 0;
|
||||
r = d & 0x1f; /* copy lower 5 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f); /* copy lower 6 */
|
||||
}
|
||||
else if ((d & 0xf0) == 0xe0)
|
||||
{
|
||||
/* 3 byte */
|
||||
d2 = buf[index++];
|
||||
d3 = buf[index++];
|
||||
if ((d2 & 0xc0) != 0x80 || (d3 & 0xc0) != 0x80)
|
||||
return 0;
|
||||
r = d & 0x0f; /* copy lower 4 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d3 & 0x3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 4 byte */
|
||||
d2 = buf[index++];
|
||||
d3 = buf[index++];
|
||||
d4 = buf[index++];
|
||||
if ((d2 & 0xc0) != 0x80 || (d3 & 0xc0) != 0x80 || (d4 & 0xc0) != 0x80)
|
||||
return 0;
|
||||
r = d & 0x0f; /* copy lower 4 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d3 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d4 & 0x3f);
|
||||
|
||||
}
|
||||
if (r < 0xdfff && d > 0xd800)
|
||||
{
|
||||
/* ill-formed says Table 3.1B in the */
|
||||
/* Unicode 3.2 std */
|
||||
return 0;
|
||||
}
|
||||
*iindex = index;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* TODO put this somewhere else */
|
||||
|
||||
void *
|
||||
imlib_object_list_prepend(void *in_list, void *in_item)
|
||||
{
|
||||
Imlib_Object_List *new_l;
|
||||
Imlib_Object_List *list, *item;
|
||||
|
||||
list = in_list;
|
||||
item = in_item;
|
||||
new_l = item;
|
||||
new_l->prev = NULL;
|
||||
if (!list)
|
||||
{
|
||||
new_l->next = NULL;
|
||||
new_l->last = new_l;
|
||||
return new_l;
|
||||
}
|
||||
new_l->next = list;
|
||||
list->prev = new_l;
|
||||
new_l->last = list->last;
|
||||
list->last = NULL;
|
||||
return new_l;
|
||||
}
|
||||
|
||||
void *
|
||||
imlib_object_list_remove(void *in_list, void *in_item)
|
||||
{
|
||||
Imlib_Object_List *return_l;
|
||||
Imlib_Object_List *list, *item;
|
||||
|
||||
/* checkme */
|
||||
if (!in_list)
|
||||
return in_list;
|
||||
|
||||
list = in_list;
|
||||
item = in_item;
|
||||
if (!item)
|
||||
return list;
|
||||
if (item->next)
|
||||
item->next->prev = item->prev;
|
||||
if (item->prev)
|
||||
{
|
||||
item->prev->next = item->next;
|
||||
return_l = list;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_l = item->next;
|
||||
if (return_l)
|
||||
return_l->last = list->last;
|
||||
}
|
||||
if (item == list->last)
|
||||
list->last = item->prev;
|
||||
item->next = NULL;
|
||||
item->prev = NULL;
|
||||
return return_l;
|
||||
}
|
||||
|
||||
static int
|
||||
imlib_hash_gen(const char *key)
|
||||
{
|
||||
unsigned int hash_num = 0;
|
||||
const unsigned char *ptr;
|
||||
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
for (ptr = (unsigned char *)key; *ptr; ptr++)
|
||||
hash_num ^= (int)(*ptr);
|
||||
|
||||
hash_num &= 0xff;
|
||||
return (int)hash_num;
|
||||
}
|
||||
|
||||
Imlib_Hash *
|
||||
imlib_hash_add(Imlib_Hash * hash, const char *key, const void *data)
|
||||
{
|
||||
int hash_num;
|
||||
Imlib_Hash_El *el;
|
||||
|
||||
_imlib_hash_alloc_error = 0;
|
||||
if (!hash)
|
||||
{
|
||||
hash = calloc(1, sizeof(struct _Imlib_Hash));
|
||||
if (!hash)
|
||||
{
|
||||
_imlib_hash_alloc_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!(el = malloc(sizeof(struct _Imlib_Hash_El))))
|
||||
{
|
||||
if (hash->population <= 0)
|
||||
{
|
||||
free(hash);
|
||||
hash = NULL;
|
||||
}
|
||||
_imlib_hash_alloc_error = 1;
|
||||
return hash;
|
||||
};
|
||||
if (key)
|
||||
{
|
||||
el->key = strdup(key);
|
||||
if (!el->key)
|
||||
{
|
||||
free(el);
|
||||
_imlib_hash_alloc_error = 1;
|
||||
return hash;
|
||||
}
|
||||
hash_num = imlib_hash_gen(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
el->key = NULL;
|
||||
hash_num = 0;
|
||||
}
|
||||
el->data = (void *)data;
|
||||
|
||||
hash->buckets[hash_num] =
|
||||
imlib_object_list_prepend(hash->buckets[hash_num], el);
|
||||
|
||||
if (imlib_list_alloc_error())
|
||||
{
|
||||
_imlib_hash_alloc_error = 1;
|
||||
if (el->key)
|
||||
free(el->key);
|
||||
free(el);
|
||||
return hash;
|
||||
}
|
||||
hash->population++;
|
||||
return hash;
|
||||
}
|
||||
|
||||
void *
|
||||
imlib_hash_find(Imlib_Hash * hash, const char *key)
|
||||
{
|
||||
int hash_num;
|
||||
Imlib_Hash_El *el;
|
||||
Imlib_Object_List *l;
|
||||
|
||||
_imlib_hash_alloc_error = 0;
|
||||
if (!hash)
|
||||
return NULL;
|
||||
hash_num = imlib_hash_gen(key);
|
||||
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||
{
|
||||
el = (Imlib_Hash_El *) l;
|
||||
if (((el->key) && (key) && (!strcmp(el->key, key)))
|
||||
|| ((!el->key) && (!key)))
|
||||
{
|
||||
if (l != hash->buckets[hash_num])
|
||||
{
|
||||
/* FIXME: move to front of list without alloc */
|
||||
hash->buckets[hash_num] =
|
||||
imlib_object_list_remove(hash->buckets[hash_num], el);
|
||||
hash->buckets[hash_num] =
|
||||
imlib_object_list_prepend(hash->buckets[hash_num], el);
|
||||
if (imlib_list_alloc_error())
|
||||
{
|
||||
_imlib_hash_alloc_error = 1;
|
||||
return el->data;
|
||||
}
|
||||
}
|
||||
return el->data;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
imlib_hash_free(Imlib_Hash * hash)
|
||||
{
|
||||
int i, size;
|
||||
|
||||
if (!hash)
|
||||
return;
|
||||
size = imlib_hash_size(hash);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
while (hash->buckets[i])
|
||||
{
|
||||
Imlib_Hash_El *el;
|
||||
|
||||
el = (Imlib_Hash_El *) hash->buckets[i];
|
||||
if (el->key)
|
||||
free(el->key);
|
||||
hash->buckets[i] = imlib_object_list_remove(hash->buckets[i], el);
|
||||
free(el);
|
||||
}
|
||||
}
|
||||
free(hash);
|
||||
}
|
||||
|
||||
void
|
||||
imlib_hash_foreach(Imlib_Hash * hash, int (*func) (Imlib_Hash * hash,
|
||||
const char *key, void *data,
|
||||
void *fdata),
|
||||
const void *fdata)
|
||||
{
|
||||
int i, size;
|
||||
|
||||
if (!hash)
|
||||
return;
|
||||
size = imlib_hash_size(hash);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
Imlib_Object_List *l, *next_l;
|
||||
|
||||
for (l = hash->buckets[i]; l;)
|
||||
{
|
||||
Imlib_Hash_El *el;
|
||||
|
||||
next_l = l->next;
|
||||
el = (Imlib_Hash_El *) l;
|
||||
if (!func(hash, el->key, el->data, (void *)fdata))
|
||||
return;
|
||||
l = next_l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
imlib_hash_size(Imlib_Hash * hash)
|
||||
{
|
||||
if (!hash)
|
||||
return 0;
|
||||
return 256;
|
||||
}
|
||||
|
||||
int
|
||||
imlib_list_alloc_error(void)
|
||||
{
|
||||
return _imlib_list_alloc_error;
|
||||
}
|
313
src/font_query.c
313
src/font_query.c
|
@ -1,313 +0,0 @@
|
|||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include "font.h"
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "file.h"
|
||||
#include "updates.h"
|
||||
#include "rgbadraw.h"
|
||||
#include "rotate.h"
|
||||
|
||||
extern FT_Library ft_lib;
|
||||
|
||||
/* string extents */
|
||||
void
|
||||
imlib_font_query_size(ImlibFont * fn, const char *text, int *w, int *h)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int start_x, end_x;
|
||||
int chr;
|
||||
FT_UInt prev_index;
|
||||
|
||||
start_x = 0;
|
||||
end_x = 0;
|
||||
pen_x = 0;
|
||||
pen_y = 0;
|
||||
use_kerning = FT_HAS_KERNING(fn->ft.face);
|
||||
prev_index = 0;
|
||||
for (chr = 0; text[chr];)
|
||||
{
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl;
|
||||
|
||||
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0)
|
||||
break;
|
||||
index = FT_Get_Char_Index(fn->ft.face, gl);
|
||||
if ((use_kerning) && (prev_index) && (index))
|
||||
{
|
||||
FT_Vector delta;
|
||||
|
||||
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
|
||||
&delta);
|
||||
pen_x += delta.x << 2;
|
||||
}
|
||||
fg = imlib_font_cache_glyph_get(fn, index);
|
||||
if (!fg)
|
||||
continue;
|
||||
|
||||
chr_x = (pen_x >> 8) + fg->glyph_out->left;
|
||||
chr_y = (pen_y >> 8) + fg->glyph_out->top;
|
||||
chr_w = fg->glyph_out->bitmap.width;
|
||||
|
||||
if (!prev_index)
|
||||
start_x = chr_x;
|
||||
if ((chr_x + chr_w) > end_x)
|
||||
end_x = chr_x + chr_w;
|
||||
|
||||
pen_x += fg->glyph->advance.x >> 8;
|
||||
prev_index = index;
|
||||
}
|
||||
if (w)
|
||||
*w = (pen_x >> 8) - start_x;
|
||||
if (h)
|
||||
*h = imlib_font_max_ascent_get(fn) - imlib_font_max_descent_get(fn);
|
||||
}
|
||||
|
||||
/* text x inset */
|
||||
int
|
||||
imlib_font_query_inset(ImlibFont * fn, const char *text)
|
||||
{
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
int chr;
|
||||
int gl;
|
||||
|
||||
chr = 0;
|
||||
if (!text[0])
|
||||
return 0;
|
||||
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0)
|
||||
return 0;
|
||||
index = FT_Get_Char_Index(fn->ft.face, gl);
|
||||
fg = imlib_font_cache_glyph_get(fn, index);
|
||||
if (!fg)
|
||||
return 0;
|
||||
return -fg->glyph_out->left;
|
||||
}
|
||||
|
||||
/* h & v advance */
|
||||
void
|
||||
imlib_font_query_advance(ImlibFont * fn, const char *text, int *h_adv,
|
||||
int *v_adv)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int start_x;
|
||||
int chr;
|
||||
FT_UInt prev_index;
|
||||
|
||||
start_x = 0;
|
||||
pen_x = 0;
|
||||
pen_y = 0;
|
||||
use_kerning = FT_HAS_KERNING(fn->ft.face);
|
||||
prev_index = 0;
|
||||
for (chr = 0; text[chr];)
|
||||
{
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl;
|
||||
|
||||
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0)
|
||||
break;
|
||||
index = FT_Get_Char_Index(fn->ft.face, gl);
|
||||
if ((use_kerning) && (prev_index) && (index))
|
||||
{
|
||||
FT_Vector delta;
|
||||
|
||||
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
|
||||
&delta);
|
||||
pen_x += delta.x << 2;
|
||||
}
|
||||
fg = imlib_font_cache_glyph_get(fn, index);
|
||||
if (!fg)
|
||||
continue;
|
||||
|
||||
chr_x = (pen_x >> 8) + fg->glyph_out->left;
|
||||
chr_y = (pen_y >> 8) + fg->glyph_out->top;
|
||||
chr_w = fg->glyph_out->bitmap.width;
|
||||
|
||||
pen_x += fg->glyph->advance.x >> 8;
|
||||
prev_index = index;
|
||||
}
|
||||
if (v_adv)
|
||||
*v_adv = imlib_font_get_line_advance(fn);
|
||||
if (h_adv)
|
||||
*h_adv = (pen_x >> 8) - start_x;
|
||||
}
|
||||
|
||||
/* x y w h for char at char pos */
|
||||
int
|
||||
imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos,
|
||||
int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int prev_chr_end;
|
||||
int chr;
|
||||
int asc, desc;
|
||||
FT_UInt prev_index;
|
||||
|
||||
pen_x = 0;
|
||||
pen_y = 0;
|
||||
use_kerning = FT_HAS_KERNING(fn->ft.face);
|
||||
prev_index = 0;
|
||||
prev_chr_end = 0;
|
||||
asc = imlib_font_max_ascent_get(fn);
|
||||
desc = imlib_font_max_descent_get(fn);
|
||||
for (chr = 0; text[chr];)
|
||||
{
|
||||
int pchr;
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
FT_Vector delta;
|
||||
|
||||
pchr = chr;
|
||||
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0)
|
||||
break;
|
||||
index = FT_Get_Char_Index(fn->ft.face, gl);
|
||||
kern = 0;
|
||||
if ((use_kerning) && (prev_index) && (index))
|
||||
{
|
||||
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
|
||||
&delta);
|
||||
kern = delta.x << 2;
|
||||
pen_x += kern;
|
||||
}
|
||||
fg = imlib_font_cache_glyph_get(fn, index);
|
||||
if (!fg)
|
||||
continue;
|
||||
|
||||
if (kern < 0)
|
||||
kern = 0;
|
||||
chr_x = ((pen_x - kern) >> 8) + fg->glyph_out->left;
|
||||
chr_y = (pen_y >> 8) + fg->glyph_out->top;
|
||||
chr_w = fg->glyph_out->bitmap.width + (kern >> 8);
|
||||
if (text[chr])
|
||||
{
|
||||
int advw;
|
||||
|
||||
advw = ((fg->glyph->advance.x + (kern << 8)) >> 16);
|
||||
if (chr_w < advw)
|
||||
chr_w = advw;
|
||||
}
|
||||
if (chr_x > prev_chr_end)
|
||||
{
|
||||
chr_w += (chr_x - prev_chr_end);
|
||||
chr_x = prev_chr_end;
|
||||
}
|
||||
if (pchr == pos)
|
||||
{
|
||||
if (cx)
|
||||
*cx = chr_x;
|
||||
if (cy)
|
||||
*cy = -asc;
|
||||
if (cw)
|
||||
*cw = chr_w;
|
||||
if (ch)
|
||||
*ch = asc + desc;
|
||||
return 1;
|
||||
}
|
||||
prev_chr_end = chr_x + chr_w;
|
||||
pen_x += fg->glyph->advance.x >> 8;
|
||||
prev_index = index;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* char pos of text at xy pos */
|
||||
int
|
||||
imlib_font_query_text_at_pos(ImlibFont * fn, const char *text, int x, int y,
|
||||
int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int prev_chr_end;
|
||||
int chr;
|
||||
int asc, desc;
|
||||
FT_UInt prev_index;
|
||||
|
||||
pen_x = 0;
|
||||
pen_y = 0;
|
||||
use_kerning = FT_HAS_KERNING(fn->ft.face);
|
||||
prev_index = 0;
|
||||
prev_chr_end = 0;
|
||||
asc = imlib_font_max_ascent_get(fn);
|
||||
desc = imlib_font_max_descent_get(fn);
|
||||
for (chr = 0; text[chr];)
|
||||
{
|
||||
int pchr;
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
FT_Vector delta;
|
||||
|
||||
pchr = chr;
|
||||
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0)
|
||||
break;
|
||||
index = FT_Get_Char_Index(fn->ft.face, gl);
|
||||
kern = 0;
|
||||
if ((use_kerning) && (prev_index) && (index))
|
||||
{
|
||||
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
|
||||
&delta);
|
||||
kern = delta.x << 2;
|
||||
pen_x += kern;
|
||||
}
|
||||
fg = imlib_font_cache_glyph_get(fn, index);
|
||||
if (!fg)
|
||||
continue;
|
||||
|
||||
if (kern < 0)
|
||||
kern = 0;
|
||||
chr_x = ((pen_x - kern) >> 8) + fg->glyph_out->left;
|
||||
chr_y = (pen_y >> 8) + fg->glyph_out->top;
|
||||
chr_w = fg->glyph_out->bitmap.width + (kern >> 8);
|
||||
if (text[chr])
|
||||
{
|
||||
int advw;
|
||||
|
||||
advw = ((fg->glyph->advance.x + (kern << 8)) >> 16);
|
||||
if (chr_w < advw)
|
||||
chr_w = advw;
|
||||
}
|
||||
if (chr_x > prev_chr_end)
|
||||
{
|
||||
chr_w += (chr_x - prev_chr_end);
|
||||
chr_x = prev_chr_end;
|
||||
}
|
||||
if ((x >= chr_x) && (x <= (chr_x + chr_w)) && (y > -asc) && (y < desc))
|
||||
{
|
||||
if (cx)
|
||||
*cx = chr_x;
|
||||
if (cy)
|
||||
*cy = -asc;
|
||||
if (cw)
|
||||
*cw = chr_w;
|
||||
if (ch)
|
||||
*ch = asc + desc;
|
||||
return pchr;
|
||||
}
|
||||
prev_chr_end = chr_x + chr_w;
|
||||
pen_x += fg->glyph->advance.x >> 8;
|
||||
prev_index = index;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
#include "format.h"
|
|
@ -1,3 +0,0 @@
|
|||
#ifndef __FORMAT
|
||||
#define __FORMAT 1
|
||||
#endif
|
725
src/grab.c
725
src/grab.c
|
@ -1,725 +0,0 @@
|
|||
#include "common.h"
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
# include <X11/Xlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include "grab.h"
|
||||
|
||||
static char _x_err = 0;
|
||||
static DATA8 rtab[256], gtab[256], btab[256];
|
||||
|
||||
static void
|
||||
Tmp_HandleXError(Display * d, XErrorEvent * ev)
|
||||
{
|
||||
d = NULL;
|
||||
ev = NULL;
|
||||
_x_err = 1;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_GrabXImageToRGBA(DATA32 * data, int ox, int oy, int ow, int oh,
|
||||
Display * d, XImage * xim, XImage * mxim, Visual * v,
|
||||
int depth, int x, int y, int w, int h, char grab)
|
||||
{
|
||||
int inx, iny;
|
||||
DATA32 *src, *ptr;
|
||||
int pixel;
|
||||
int origx, origy;
|
||||
int bgr = 0;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (grab)
|
||||
XGrabServer(d); /* This may prevent the image to be changed under our feet */
|
||||
origx = x;
|
||||
origy = y;
|
||||
|
||||
if (v->blue_mask > v->red_mask)
|
||||
bgr = 1;
|
||||
|
||||
if (origx < 0)
|
||||
inx = -origx;
|
||||
else
|
||||
inx = ox;
|
||||
if (origy < 0)
|
||||
iny = -origy;
|
||||
else
|
||||
iny = oy;
|
||||
/* go thru the XImage and convert */
|
||||
if (xim->bits_per_pixel == 32)
|
||||
depth = 32;
|
||||
switch (depth)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
pixel = (btab[pixel & 0xff]) |
|
||||
(gtab[pixel & 0xff] << 8) |
|
||||
(rtab[pixel & 0xff] << 16);
|
||||
if (XGetPixel(mxim, x, y))
|
||||
pixel |= 0xff000000;
|
||||
*ptr++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = 0xff000000 |
|
||||
(btab[pixel & 0xff]) |
|
||||
(gtab[pixel & 0xff] << 8) |
|
||||
(rtab[pixel & 0xff] << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
#undef MP
|
||||
#undef RMSK
|
||||
#undef GMSK
|
||||
#undef BMSK
|
||||
#undef R1SH
|
||||
#undef G1SH
|
||||
#undef B1SH
|
||||
#undef R2SH
|
||||
#undef G2SH
|
||||
#undef B2SH
|
||||
#undef P1
|
||||
#undef P2
|
||||
#define MP(x, y) ((XGetPixel(mxim, (x), (y))) ? 0xff000000 : 0)
|
||||
#define RMSK 0xf80000
|
||||
#define GMSK 0x00fc00
|
||||
#define BMSK 0x0000f8
|
||||
#define R1SH(p) ((p) << 8)
|
||||
#define G1SH(p) ((p) << 5)
|
||||
#define B1SH(p) ((p) << 3)
|
||||
#define R2SH(p) ((p) >> 8)
|
||||
#define G2SH(p) ((p) >> 11)
|
||||
#define B2SH(p) ((p) >> 13)
|
||||
#define P1(p) (R1SH(p) & RMSK) | (G1SH(p) & GMSK) | (B1SH(p) & BMSK)
|
||||
#define P2(p) (R2SH(p) & RMSK) | (G2SH(p) & GMSK) | (B2SH(p) & BMSK)
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src = (DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < (w - 1); x += 2)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
#else
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
#endif
|
||||
src++;
|
||||
}
|
||||
if (x == (w - 1))
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = MP(x, y) | P1(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef MP
|
||||
#define MP(x, y) (0xff000000)
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src = (DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < (w - 1); x += 2)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
#else
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
#endif
|
||||
src++;
|
||||
}
|
||||
if (x == (w - 1))
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = MP(x, y) | P1(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
#undef MP
|
||||
#undef RMSK
|
||||
#undef GMSK
|
||||
#undef BMSK
|
||||
#undef R1SH
|
||||
#undef G1SH
|
||||
#undef B1SH
|
||||
#undef R2SH
|
||||
#undef G2SH
|
||||
#undef B2SH
|
||||
#undef P1
|
||||
#undef P2
|
||||
#define MP(x, y) ((XGetPixel(mxim, (x), (y))) ? 0xff000000 : 0)
|
||||
#define RMSK 0xf80000
|
||||
#define GMSK 0x00f800
|
||||
#define BMSK 0x0000f8
|
||||
#define R1SH(p) ((p) << 9)
|
||||
#define G1SH(p) ((p) << 6)
|
||||
#define B1SH(p) ((p) << 3)
|
||||
#define R2SH(p) ((p) >> 7)
|
||||
#define G2SH(p) ((p) >> 10)
|
||||
#define B2SH(p) ((p) >> 13)
|
||||
#define P1(p) (R1SH(p) & RMSK) | (G1SH(p) & GMSK) | (B1SH(p) & BMSK)
|
||||
#define P2(p) (R2SH(p) & RMSK) | (G2SH(p) & GMSK) | (B2SH(p) & BMSK)
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src = (DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < (w - 1); x += 2)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
#else
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
#endif
|
||||
src++;
|
||||
}
|
||||
if (x == (w - 1))
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = MP(x, y) | P1(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef MP
|
||||
#define MP(x, y) (0xff000000)
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src = (DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < (w - 1); x += 2)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
#else
|
||||
*ptr++ = MP(x, y) | P1(*src);
|
||||
*ptr++ = MP(x + 1, y) | P2(*src);
|
||||
#endif
|
||||
src++;
|
||||
}
|
||||
if (x == (w - 1))
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = MP(x, y) | P1(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
if (bgr)
|
||||
{
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
pixel = ((pixel << 16) & 0xff0000) |
|
||||
((pixel) & 0x00ff00) |
|
||||
((pixel >> 16) & 0x0000ff);
|
||||
if (XGetPixel(mxim, x, y))
|
||||
pixel |= 0xff000000;
|
||||
*ptr++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = 0xff000000 |
|
||||
((pixel << 16) & 0xff0000) |
|
||||
((pixel) & 0x00ff00) |
|
||||
((pixel >> 16) & 0x0000ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y) & 0x00ffffff;
|
||||
if (XGetPixel(mxim, x, y))
|
||||
pixel |= 0xff000000;
|
||||
*ptr++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = XGetPixel(xim, x, y);
|
||||
*ptr++ = 0xff000000 | (pixel & 0x00ffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (bgr)
|
||||
{
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src =
|
||||
(DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = ((*src << 16) & 0xff0000) |
|
||||
((*src) & 0x00ff00) |
|
||||
((*src >> 16) & 0x0000ff);
|
||||
if (XGetPixel(mxim, x, y))
|
||||
pixel |= 0xff000000;
|
||||
*ptr++ = pixel;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src =
|
||||
(DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr++ = 0xff000000 |
|
||||
((*src << 16) & 0xff0000) |
|
||||
((*src) & 0x00ff00) |
|
||||
((*src >> 16) & 0x0000ff);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mxim)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src =
|
||||
(DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
pixel = (*src) & 0x00ffffff;
|
||||
if (XGetPixel(mxim, x, y))
|
||||
pixel |= 0xff000000;
|
||||
*ptr++ = pixel;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
src =
|
||||
(DATA32 *) (xim->data + (xim->bytes_per_line * y));
|
||||
ptr = data + ((y + iny) * ow) + inx;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*ptr++ = 0xff000000 | ((*src) & 0x00ffffff);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (grab)
|
||||
XUngrabServer(d);
|
||||
}
|
||||
|
||||
char
|
||||
__imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int ow, int oh,
|
||||
Display * d, Drawable p, Pixmap m, Visual * v,
|
||||
Colormap cm, int depth, int x, int y,
|
||||
int w, int h, char domask, char grab)
|
||||
{
|
||||
XErrorHandler prev_erh = NULL;
|
||||
XWindowAttributes xatt, ratt;
|
||||
char is_pixmap = 0, created_mask = 0, is_shm = 0, is_mshm = 0;
|
||||
int i;
|
||||
int src_x, src_y, src_w, src_h, origw, origh;
|
||||
int width, height, clipx, clipy;
|
||||
XShmSegmentInfo shminfo, mshminfo;
|
||||
XImage *xim = NULL, *mxim = NULL;
|
||||
static signed char x_does_shm = -1;
|
||||
XColor cols[256];
|
||||
|
||||
/* FIXME: oh isnt used - i wonder if there's a bug looming... */
|
||||
oh = 0;
|
||||
origw = w;
|
||||
origh = h;
|
||||
if (grab)
|
||||
XGrabServer(d);
|
||||
XSync(d, False);
|
||||
prev_erh = XSetErrorHandler((XErrorHandler) Tmp_HandleXError);
|
||||
_x_err = 0;
|
||||
/* lets see if its a pixmap or not */
|
||||
XGetWindowAttributes(d, p, &xatt);
|
||||
XSync(d, False);
|
||||
if (_x_err)
|
||||
is_pixmap = 1;
|
||||
/* reset our error handler */
|
||||
XSetErrorHandler((XErrorHandler) prev_erh);
|
||||
if (is_pixmap)
|
||||
{
|
||||
Window dw;
|
||||
|
||||
XGetGeometry(d, p, &dw, &src_x, &src_y,
|
||||
(unsigned int *)&src_w, (unsigned int *)&src_h,
|
||||
(unsigned int *)&src_x, (unsigned int *)&xatt.depth);
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Window dw;
|
||||
|
||||
XGetWindowAttributes(d, xatt.root, &ratt);
|
||||
XTranslateCoordinates(d, p, xatt.root, 0, 0, &src_x, &src_y, &dw);
|
||||
src_w = xatt.width;
|
||||
src_h = xatt.height;
|
||||
if ((xatt.map_state != IsViewable) && (xatt.backing_store == NotUseful))
|
||||
{
|
||||
if (grab)
|
||||
XUngrabServer(d);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* clip to the drawable tree and screen */
|
||||
clipx = 0;
|
||||
clipy = 0;
|
||||
width = src_w - x;
|
||||
height = src_h - y;
|
||||
if (width > w)
|
||||
width = w;
|
||||
if (height > h)
|
||||
height = h;
|
||||
|
||||
if (!is_pixmap)
|
||||
{
|
||||
if ((src_x + x + width) > ratt.width)
|
||||
width = ratt.width - (src_x + x);
|
||||
if ((src_y + y + height) > ratt.height)
|
||||
height = ratt.height - (src_y + y);
|
||||
}
|
||||
if (x < 0)
|
||||
{
|
||||
clipx = -x;
|
||||
width += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
clipy = -y;
|
||||
height += y;
|
||||
y = 0;
|
||||
}
|
||||
if (!is_pixmap)
|
||||
{
|
||||
if ((src_x + x) < 0)
|
||||
{
|
||||
clipx -= (src_x + x);
|
||||
width += (src_x + x);
|
||||
x = -src_x;
|
||||
}
|
||||
if ((src_y + y) < 0)
|
||||
{
|
||||
clipy -= (src_y + y);
|
||||
height += (src_y + y);
|
||||
y = -src_y;
|
||||
}
|
||||
}
|
||||
if ((width <= 0) || (height <= 0))
|
||||
{
|
||||
if (grab)
|
||||
XUngrabServer(d);
|
||||
return 0;
|
||||
}
|
||||
w = width;
|
||||
h = height;
|
||||
if ((!is_pixmap) && (domask) && (!m))
|
||||
{
|
||||
int ord, rect_no = 0;
|
||||
XRectangle *r = NULL;
|
||||
|
||||
r = XShapeGetRectangles(d, p, ShapeBounding, &rect_no, &ord);
|
||||
if (r)
|
||||
{
|
||||
if (!((rect_no == 1) &&
|
||||
(r[0].x == 0) && (r[0].y == 0) &&
|
||||
(r[0].width == xatt.width) && (r[0].height == xatt.height)))
|
||||
{
|
||||
XGCValues gcv;
|
||||
GC gc;
|
||||
|
||||
created_mask = 1;
|
||||
m = XCreatePixmap(d, p, w, h, 1);
|
||||
gcv.foreground = 0;
|
||||
gc = XCreateGC(d, m, GCForeground, &gcv);
|
||||
XFillRectangle(d, m, gc, 0, 0, w, h);
|
||||
XSetForeground(d, gc, 1);
|
||||
for (i = 0; i < rect_no; i++)
|
||||
XFillRectangle(d, m, gc,
|
||||
r[i].x - x, r[i].y - y,
|
||||
r[i].width, r[i].height);
|
||||
XFreeGC(d, gc);
|
||||
}
|
||||
XFree(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create an Ximage (shared or not) */
|
||||
if (x_does_shm < 0)
|
||||
{
|
||||
if (XShmQueryExtension(d))
|
||||
x_does_shm = 1;
|
||||
else
|
||||
x_does_shm = 0;
|
||||
}
|
||||
|
||||
prev_erh = XSetErrorHandler((XErrorHandler) Tmp_HandleXError);
|
||||
|
||||
if (x_does_shm)
|
||||
{
|
||||
_x_err = 0;
|
||||
xim = XShmCreateImage(d, v, xatt.depth, ZPixmap, NULL, &shminfo, w, h);
|
||||
if (xim)
|
||||
{
|
||||
XSync(d, False);
|
||||
if (_x_err)
|
||||
{
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
else
|
||||
{
|
||||
shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line *
|
||||
xim->height, IPC_CREAT | 0666);
|
||||
if (shminfo.shmid < 0)
|
||||
{
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
else
|
||||
{
|
||||
shminfo.shmaddr = xim->data = shmat(shminfo.shmid, 0, 0);
|
||||
if (xim->data != (char *)-1)
|
||||
{
|
||||
shminfo.readOnly = False;
|
||||
XShmAttach(d, &shminfo);
|
||||
is_shm = 1;
|
||||
XShmGetImage(d, p, xim, x, y, 0xffffffff);
|
||||
XSync(d, False);
|
||||
if (_x_err)
|
||||
{
|
||||
shmdt(shminfo.shmaddr);
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
XDestroyImage(xim);
|
||||
is_shm = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_shm)
|
||||
xim = XGetImage(d, p, x, y, w, h, 0xffffffff, ZPixmap);
|
||||
|
||||
if ((m) && (domask))
|
||||
{
|
||||
_x_err = 0;
|
||||
if (x_does_shm)
|
||||
{
|
||||
mxim = XShmCreateImage(d, v, 1, ZPixmap, NULL, &mshminfo, w, h);
|
||||
if (mxim)
|
||||
{
|
||||
XSync(d, False);
|
||||
if (_x_err)
|
||||
{
|
||||
XDestroyImage(mxim);
|
||||
}
|
||||
else
|
||||
{
|
||||
mshminfo.shmid = shmget(IPC_PRIVATE,
|
||||
mxim->bytes_per_line *
|
||||
mxim->height, IPC_CREAT | 0666);
|
||||
if (mshminfo.shmid < 0)
|
||||
{
|
||||
XDestroyImage(mxim);
|
||||
}
|
||||
else
|
||||
{
|
||||
mshminfo.shmaddr = mxim->data =
|
||||
shmat(mshminfo.shmid, 0, 0);
|
||||
if (mxim->data != (char *)-1)
|
||||
{
|
||||
mshminfo.readOnly = False;
|
||||
XShmAttach(d, &mshminfo);
|
||||
is_mshm = 1;
|
||||
XShmGetImage(d, m, mxim, 0, 0, 0xffffffff);
|
||||
XSync(d, False);
|
||||
if (_x_err)
|
||||
{
|
||||
shmdt(mshminfo.shmaddr);
|
||||
shmctl(mshminfo.shmid, IPC_RMID, 0);
|
||||
XDestroyImage(mxim);
|
||||
is_mshm = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shmctl(mshminfo.shmid, IPC_RMID, 0);
|
||||
XDestroyImage(mxim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_mshm)
|
||||
mxim = XGetImage(d, m, 0, 0, w, h, 0xffffffff, ZPixmap);
|
||||
}
|
||||
|
||||
XSetErrorHandler((XErrorHandler) prev_erh);
|
||||
|
||||
if ((is_shm) || (is_mshm))
|
||||
{
|
||||
XSync(d, False);
|
||||
if (grab)
|
||||
XUngrabServer(d);
|
||||
XSync(d, False);
|
||||
}
|
||||
else if (grab)
|
||||
XUngrabServer(d);
|
||||
|
||||
if ((xatt.depth == 1) && (!cm) && (is_pixmap))
|
||||
{
|
||||
rtab[0] = 255;
|
||||
gtab[0] = 255;
|
||||
btab[0] = 255;
|
||||
rtab[1] = 0;
|
||||
gtab[1] = 0;
|
||||
btab[1] = 0;
|
||||
}
|
||||
else if (xatt.depth <= 8)
|
||||
{
|
||||
if ((!is_pixmap) && (!cm))
|
||||
{
|
||||
cm = xatt.colormap;
|
||||
if (cm == None)
|
||||
cm = ratt.colormap;
|
||||
}
|
||||
else
|
||||
cm = ratt.colormap;
|
||||
|
||||
for (i = 0; i < (1 << xatt.depth); i++)
|
||||
{
|
||||
cols[i].pixel = i;
|
||||
cols[i].flags = DoRed | DoGreen | DoBlue;
|
||||
}
|
||||
XQueryColors(d, cm, cols, 1 << xatt.depth);
|
||||
for (i = 0; i < (1 << xatt.depth); i++)
|
||||
{
|
||||
rtab[i] = cols[i].red >> 8;
|
||||
gtab[i] = cols[i].green >> 8;
|
||||
btab[i] = cols[i].blue >> 8;
|
||||
}
|
||||
}
|
||||
__imlib_GrabXImageToRGBA(data, ox + clipx, oy + clipy, ow, oh,
|
||||
d, xim, mxim, v, xatt.depth, x, y, w, h, 0);
|
||||
|
||||
/* destroy the Ximage */
|
||||
if (is_shm)
|
||||
{
|
||||
XSync(d, False);
|
||||
XShmDetach(d, &shminfo);
|
||||
shmdt(shminfo.shmaddr);
|
||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||
}
|
||||
if ((is_mshm) && (mxim))
|
||||
{
|
||||
XShmDetach(d, &mshminfo);
|
||||
shmdt(mshminfo.shmaddr);
|
||||
shmctl(mshminfo.shmid, IPC_RMID, 0);
|
||||
}
|
||||
XDestroyImage(xim);
|
||||
if (created_mask)
|
||||
XFreePixmap(d, m);
|
||||
if (mxim)
|
||||
XDestroyImage(mxim);
|
||||
return 1;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue