diff --git a/legacy/evas_generic_loaders/.arcconfig b/legacy/evas_generic_loaders/.arcconfig new file mode 100644 index 0000000000..7d7c8a684c --- /dev/null +++ b/legacy/evas_generic_loaders/.arcconfig @@ -0,0 +1,4 @@ +{ + "project_id" : "evas_generic_loaders", + "conduit_uri" : "https://phab.enlightenment.org/" +} diff --git a/legacy/evas_generic_loaders/.gitignore b/legacy/evas_generic_loaders/.gitignore new file mode 100644 index 0000000000..34b8e2cd89 --- /dev/null +++ b/legacy/evas_generic_loaders/.gitignore @@ -0,0 +1,43 @@ +*~ +*.o +*.swp +*.swo +ABOUT-NLS +INSTALL +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +compile +config.cache +config.cache-env +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +install-sh +ltmain.sh +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +missing +Makefile +Makefile.in +.deps +stamp-h1 +src/bin/gst/evas_image_loader.gst +src/bin/pdf/evas_image_loader.pdf +src/bin/ps/evas_image_loader.ps +src/bin/svg/evas_image_loader.svg +src/bin/xcf/evas_image_loader.xcf +src/bin/raw/evas_image_loader.raw +pkgbuild/PKGBUILD +pkgbuild/pkg +pkgbuild/src +pkgbuild/*.tar.xz diff --git a/legacy/evas_generic_loaders/AUTHORS b/legacy/evas_generic_loaders/AUTHORS new file mode 100644 index 0000000000..6dc53f580d --- /dev/null +++ b/legacy/evas_generic_loaders/AUTHORS @@ -0,0 +1,15 @@ +The Rasterman (Carsten Haitzler) +Christian Kreibich +Vincent Torri +Michael Bouchaud +Fanina "cippp" Cristian +Cedric BAIL +Jérémy Zurcher +Stefan Schmidt +Daniel Juyung Seo +Doug Newgard +Mike Blumenkrantz +Alex-P. Natsios +Jihoon Kim +Samuel F. Baggen +Sebastian Dransfeld diff --git a/legacy/evas_generic_loaders/COPYING b/legacy/evas_generic_loaders/COPYING new file mode 100644 index 0000000000..879517275d --- /dev/null +++ b/legacy/evas_generic_loaders/COPYING @@ -0,0 +1,356 @@ +Copyright notice for Evas generic loaders: + +Copyright (C) 2011-2014 Carsten Haitzler and various contributors (see AUTHORS) + +This library is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; version 2 of the License. + +This library is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +Below is a copy of the GNU General Public License that is distributed +along with this library. If you do not have a copy below, write to the Free +Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/legacy/evas_generic_loaders/ChangeLog b/legacy/evas_generic_loaders/ChangeLog new file mode 100644 index 0000000000..9d3b7f13d2 --- /dev/null +++ b/legacy/evas_generic_loaders/ChangeLog @@ -0,0 +1,44 @@ +2011-12-02 Carsten Haitzler (The Rasterman) + + 1.1.0 release + +2011-12-02 Carsten Haitzler (The Rasterman) + + * Add symlinks for *.dv, *.qt and *.rv video file formats + +2012-03-18 Carsten Haitzler (The Rasterman) + + * Fix distcheck with highly parallel builds + +2012-04-26 Carsten Haitzler (The Rasterman) + + 1.2.0 release + +2012-05-18 Cedric Bail + + * Make rsvg backend use the generic backend as it is our main + source of crash in e17. + +2012-05-06 Fanina Cristian + + * Add support for Poppler 0.20. + +2012-06-30 Carsten Haitzler (The Rasterman) + + * Add timeout (default 5 seconds) for gstreamer loader in case + gst hangs. + +2012-08-30 Carsten Haitzler (The Rasterman) + + 1.7.0 release + +2012-09-26 Carsten Haitzler (The Rasterman) + + * Add various alarm/signal based timeouts for all generic + loaders in case they get stuck + +OUT OF DATE NOTICE: +------------------- +With the start of the 1.9.x release cycle we now longer update the ChangeLog and rely on git log for +this functionality. We keep however a NEWS files for a high level overview of changes in a new +release which will be filled at the end of the release cycle. diff --git a/legacy/evas_generic_loaders/Makefile.am b/legacy/evas_generic_loaders/Makefile.am new file mode 100644 index 0000000000..96dec582ec --- /dev/null +++ b/legacy/evas_generic_loaders/Makefile.am @@ -0,0 +1,36 @@ +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = src + +MAINTAINERCLEANFILES = \ +Makefile.in \ +aclocal.m4 \ +compile \ +config.guess \ +config.h.in \ +config.h.in~ \ +config.sub \ +configure \ +depcomp \ +install-sh \ +ltmain.sh \ +missing \ +$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz \ +$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.bz2 \ +m4/libtool.m4 \ +m4/lt~obsolete.m4 \ +m4/ltoptions.m4 \ +m4/ltsugar.m4 \ +m4/ltversion.m4 + +EXTRA_DIST = \ +AUTHORS \ +COPYING \ +m4/ac_attribute.m4 \ +m4/ac_path_generic.m4 \ +README + +.PHONY: doc + +doc: + @echo "Empty doc target until we have real documentation." diff --git a/legacy/evas_generic_loaders/NEWS b/legacy/evas_generic_loaders/NEWS new file mode 100644 index 0000000000..3928651cf2 --- /dev/null +++ b/legacy/evas_generic_loaders/NEWS @@ -0,0 +1,107 @@ +=========================== +Evas Generic Loaders 1.17.0 +=========================== + +Changes since 1.16.0: +--------------------- + +No significant changes in this release. + +Changes since 1.15.0: +--------------------- + +Fixes: + + * generic loaders - fix load if process esits before stdout produced + +Changes since 1.14.0: +--------------------- + +No significant changes in this release. + +Changes since 1.13.0: +--------------------- + +Fixes: + + * pdf: Add support for changes with poppler >= 0.31 (T2184) + +Changes since 1.12.0: +--------------------- + + * No relevant changes. + +Changes since 1.11.0: +--------------------- + +Fixes: + + * Improve LO binary detection + * xcf: Make sure complete calculation is unsigned (CID63748, CID63749) + * raw: Make sure to keep the correct sign (CID63746, CID63747) + +Changes since Evas Generic Loaders 1.10.0: +------------------------------------------ + +Features: + + * Trying to port evas_generic_loaders to gstreamer1.0 + * Add in older gst 0.10 support in evas_generic_loaders + +Fixes: + + * gst1 support fixed now to do argb properly + * Remove autogen.sh from the dist tarball. + * fix gst video loader in generic to have key actually work + +Changes since Evas Generic Loaders 1.9.0: +----------------------------------------- + +Fixes: + + * license: update FSF address. (T1042) + +Changes since Evas Generic Loaders 1.8.0: +----------------------------------------- + +Improvements: + + * gst loader - support key as stream position in 1/1000th of a second + +Fixes: + + * bugfix: add a typefind to gstreamer plugin pipeline + previously, we would load any file and try to force it into video/x-raw-rgb, which was + (obviously) problematic for audio-only files. with a typefind added to the pipeline, only + files which can output to video/x-raw-rgb will be processed + * bugfix: unbreak gstreamer plugin by not using the n-video property which is only available in 1.0+ + +Changes since Evas Generic Loaders 1.7.0: +----------------------------------------- + +Improvements: + + * All generic loader binaries have built-in timeouts in case they + get stuck. + * Libreoffice support for thumbnailing office documents + +Changes since Evas Generic Loaders 1.2.0: +----------------------------------------- + +Additions: + + * Add a librsvg generic loader. + * Add support for poppler 0.20 + +Evas Generic Loaders 1.2.0 + +Changes since Evas Generic Loaders 1.1.0: +----------------------------------------- + +Additions: + + * symlinks for *.dv, *.qt and *.rv video file formats + +Fixes: + + * distcheck for parallel builds diff --git a/legacy/evas_generic_loaders/README b/legacy/evas_generic_loaders/README new file mode 100644 index 0000000000..2e0f816758 --- /dev/null +++ b/legacy/evas_generic_loaders/README @@ -0,0 +1,85 @@ +Evas generic loaders 1.11.0 +=========================== + +****************************************************************************** + FOR ANY ISSUES PLEASE EMAIL: + enlightenment-devel@lists.sourceforge.net +****************************************************************************** + +These are additional "generic" loaders for Evas that are stand-alone +executables that evas may run from its generic loader module. This +means that if they crash, the application loading the image does not +crash also. In addition the licensing of these binaries will not +affect the license of any application that uses Evas as this uses a +completely generic execution system that allows anything to be plugged +in as a loader. + + +REQUIREMENTS +------------ + +Required by default: + + * libc + * libm + * zlib + +Highly recommended: + + * gstreamer (1.x or 0.10) (ensure you have all the gstreamer codecs you need/want) + * poppler + * libraw + * libspectre + * librsvg + +Suggested: + + * libreoffice + + +COMPONENTS +---------- + +Generic loaders currently provided: + + * **XCF** (.xcf .xcf.gz) + + * **PDF** (using poppler) + * use -key option to specific what page to get and load options for size + Should we add mupdf ? + + * **PS** (using libspectre) + * use -key option to specific what page to get and load options for size + Should we use directly libgs ? + + * **RAW** (using libraw) + + * **SVG** (using librsvg) + + * **MPG/AVI/OGV/MOV/MKV/WMV** etc. (using gstreamer) + * Should we add libxine and vlc ? + + * **PPT/PPTX/DOC/DOCX/XLS** etc. + * Required PDF loader, and uses libreoffice binaries as slaves to + export PDFs to load + + +COMPILING AND INSTALLING +------------------------ + + ./configure + make + sudo make install + + +COMPILER FLAGS +-------------- + +You may want to change the install prefix for EFL with: + + --prefix=/path/to/prefix + +**NOTE:** + +You should put generic loaders in the same prefix as EFL or they will +not be found by EFL at runtime. diff --git a/legacy/evas_generic_loaders/TODO b/legacy/evas_generic_loaders/TODO new file mode 100644 index 0000000000..ce7ede1e90 --- /dev/null +++ b/legacy/evas_generic_loaders/TODO @@ -0,0 +1,5 @@ +Modules to add: +--------------- + + [ ] DVI + [ ] Djvu diff --git a/legacy/evas_generic_loaders/autogen.sh b/legacy/evas_generic_loaders/autogen.sh new file mode 100755 index 0000000000..00116eaf80 --- /dev/null +++ b/legacy/evas_generic_loaders/autogen.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +rm -rf autom4te.cache +rm -f aclocal.m4 ltmain.sh + +touch README +touch ABOUT-NLS + +echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || exit 1 +echo "Running autoheader..." ; autoheader || exit 1 +echo "Running autoconf..." ; autoconf || exit 1 +echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1 +echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1 + +W=0 + +rm -f config.cache-env.tmp +echo "OLD_PARM=\"$@\"" >> config.cache-env.tmp +echo "OLD_CFLAGS=\"$CFLAGS\"" >> config.cache-env.tmp +echo "OLD_PATH=\"$PATH\"" >> config.cache-env.tmp +echo "OLD_PKG_CONFIG_PATH=\"$PKG_CONFIG_PATH\"" >> config.cache-env.tmp +echo "OLD_LDFLAGS=\"$LDFLAGS\"" >> config.cache-env.tmp + +cmp config.cache-env.tmp config.cache-env >> /dev/null +if [ $? -ne 0 ]; then + W=1; +fi + +if [ $W -ne 0 ]; then + echo "Cleaning configure cache..."; + rm -f config.cache config.cache-env + mv config.cache-env.tmp config.cache-env +else + rm -f config.cache-env.tmp +fi + +if [ -z "$NOCONFIGURE" ]; then + ./configure -C "$@" +fi diff --git a/legacy/evas_generic_loaders/configure.ac b/legacy/evas_generic_loaders/configure.ac new file mode 100644 index 0000000000..50e2745e38 --- /dev/null +++ b/legacy/evas_generic_loaders/configure.ac @@ -0,0 +1,255 @@ +EFL_VERSION([1], [17], [99], [dev]) +AC_INIT([evas_generic_loaders], [efl_version], [enlightenment-devel@lists.sourceforge.net]) +AC_PREREQ([2.52]) +AC_CONFIG_SRCDIR([configure.ac]) +AC_CONFIG_MACRO_DIR([m4]) + +AC_CONFIG_HEADERS([config.h]) + +AM_INIT_AUTOMAKE([1.6 dist-xz]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +### Needed information + +AC_CANONICAL_BUILD +AC_CANONICAL_HOST + +### Checks for libraries +AC_PROG_CC +AC_PROG_CXX +PKG_PROG_PKG_CONFIG + +### Checks for libraries + +# Eina library +PKG_CHECK_MODULES(EINA, [eina >= 1.6.99]) + +AC_ARG_ENABLE([poppler], + [AC_HELP_STRING([--disable-poppler], [disable poppler support @<:@default==enabled@:>@])], + [want_poppler=$enableval], + [want_poppler="yes"]) + +if test "x${want_poppler}" = "xyes" ; then + PKG_CHECK_EXISTS([poppler >= 0.12 poppler < 0.20], + [ + poppler_pc="poppler >= 0.12 poppler < 0.20" + have_poppler="yes" + ], + [have_poppler="no"]) + + if test "x${have_poppler}" = "xno" ; then + PKG_CHECK_EXISTS([poppler >= 0.20 poppler < 0.31], + [ + poppler_pc="poppler >= 0.20 poppler < 0.31" + AC_DEFINE(HAVE_POPPLER_020, 1, [Have poppler 0.20]) + have_poppler="yes" + ], + [have_poppler="no"]) + fi + + if test "x${have_poppler}" = "xno" ; then + PKG_CHECK_EXISTS([poppler >= 0.31], + [ + poppler_pc="poppler >= 0.31" + AC_DEFINE(HAVE_POPPLER_031, 1, [Have poppler 0.31]) + have_poppler="yes" + ], + [have_poppler="no"]) + fi + + if test "x${have_poppler}" = "xyes" ; then + PKG_CHECK_MODULES([POPPLER], [${poppler_pc}], + [have_poppler="yes"], + [have_poppler="no"]) + fi + + if test "x${have_poppler}" = "xyes" ; then + AC_LANG(C++) + save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="${CPPFLAGS} ${POPPLER_CFLAGS}" + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="${CXXFLAGS} ${POPPLER_CFLAGS}" + AC_CHECK_HEADERS([GlobalParams.h], + [have_poppler="yes"], + [have_poppler="no"]) + CXXFLAGS=$save_CXXFLAGS + CPPFLAGS=$save_CPPFLAGS + AC_LANG(C) + fi +else + have_poppler="no" +fi + +AC_ARG_ENABLE([spectre], + [AC_HELP_STRING([--disable-spectre], [disable spectre support @<:@default==enabled@:>@])], + [want_spectre=$enableval], + [want_spectre="yes"]) + +if test "x$want_spectre" = "xyes" ; then + PKG_CHECK_MODULES([SPECTRE], [libspectre], [have_ps="yes"], [have_ps="no"]) +else + have_ps=no +fi + + +AC_ARG_ENABLE([libraw], + [AC_HELP_STRING([--disable-libraw], [disable libraw support @<:@default==enabled@:>@])], + [want_libraw=$enableval], + [want_libraw="yes"]) + +if test "x$want_libraw" = "xyes" ; then + PKG_CHECK_MODULES([LIBRAW], [libraw], [have_raw="yes"], [have_raw="no"]) +else + have_raw=no +fi + +AC_ARG_ENABLE([svg], + [AC_HELP_STRING([--disable-svg], [disable svg support @<:@default==enabled@:>@])], + [want_svg=$enableval], + [want_svg="yes"] +) + +have_svg_2_36="no" +if test "x$want_svg" = "xyes" ; then + PKG_CHECK_MODULES([SVG], [librsvg-2.0 >= 2.14.0 cairo >= 1.0.0], [have_svg="yes"], [have_svg="no"]) + PKG_CHECK_MODULES( + [SVG_2_36], [librsvg-2.0 >= 2.36.0 cairo >= 1.0.0], + [ + have_svg_2_36="yes" + AC_DEFINE(HAVE_SVG_2_36, 1, [Have librsvg >= 2.36]) + ], + [have_svg_2_36="no"]) +else + have_svg=no +fi + +want_gst1="yes" +AC_ARG_ENABLE([gstreamer1], + [AC_HELP_STRING([--disable-gstreamer1], [disable gstreamer1 support @<:@default==enabled@:>@])], + [want_gst1=$enableval], + [want_gst1="yes"]) + +GST_REQS=1.0 +GSTPLUG_REQS=1.0 +GST_MAJORMINOR=1.0 + +AC_ARG_ENABLE([gstreamer], + [AC_HELP_STRING([--disable-gstreamer], [disable gstreamer support @<:@default==enabled@:>@])], + [want_gstreamer=$enableval], + [want_gstreamer="yes"]) + +if test "x$want_gstreamer" = "xyes" ; then + have_gst="no"; + if test "x$want_gst1" = "xyes" ; then + PKG_CHECK_MODULES([GSTREAMER], + [gstreamer-1.0 >= 1.0 + gstreamer-plugins-base-1.0 >= 1.0 + ], + [have_gst="yes"; have_gst1="yes";], + [have_gst="no"; have_gst1="no";]) + fi + if test "x$have_gst" = "xno" ; then + PKG_CHECK_MODULES([GSTREAMER], + [gstreamer-0.10 >= 0.10.13 + gstreamer-plugins-base-0.10 >= 0.10.13 + ], + [have_gst="yes"; have_gst1="no";], + [have_gst="no"; have_gst1="no";]) + fi +else + have_gst=no +fi +AM_CONDITIONAL([HAVE_GST], [test "x${have_gst}" = "xyes"]) +AM_CONDITIONAL([HAVE_GST1], [test "x${have_gst1}" = "xyes"]) +AM_CONDITIONAL([HAVE_PDF], [test "x${have_poppler}" = "xyes"]) +AM_CONDITIONAL([HAVE_PS], [test "x${have_ps}" = "xyes"]) +AM_CONDITIONAL([HAVE_RAW], [test "x${have_raw}" = "xyes"]) +AM_CONDITIONAL([HAVE_SVG], [test "x${have_svg}" = "xyes"]) + +### Checks for header files + +AC_CHECK_HEADERS(netinet/in.h unistd.h) + +AC_CHECK_HEADER([zlib.h], + [dummy="yes"], + [AC_MSG_ERROR("Cannot find zlib.h. Make sure your CFLAGS environment variable contains include lines for the location of this file")]) + +SHM_OPEN_LIBS="" +AC_MSG_CHECKING([whether shm_open() is present]) +LIBS_save=${LIBS} +LIBS="${LIBS} -lrt" +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +#include + ]], + [[ +int fd; +fd = shm_open("/", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); +shm_unlink("/"); + ]])], + [ + have_shm_open="yes" + AC_DEFINE(HAVE_SHM_OPEN, 1, [Have shm_open() call]) + SHM_OPEN_LIBS="-lrt" + ], + [have_shm_open="no"]) +LIBS=${LIBS_save} +AC_MSG_RESULT([${have_shm_open}]) +AC_SUBST(SHM_OPEN_LIBS) + +### Checks for compiler characteristics +AM_PROG_CC_C_O +AC_C_INLINE +AC_C_BIGENDIAN +AC_C___ATTRIBUTE__ + +### Checks for library functions + +AC_CONFIG_FILES([ +Makefile +src/Makefile +src/bin/Makefile +src/bin/common/Makefile +src/bin/gst/Makefile +src/bin/pdf/Makefile +src/bin/ps/Makefile +src/bin/raw/Makefile +src/bin/xcf/Makefile +src/bin/svg/Makefile +pkgbuild/PKGBUILD +]) + +AC_OUTPUT + +##################################################################### +## Info + +echo +echo +echo +echo "------------------------------------------------------------------------" +echo "$PACKAGE_NAME $PACKAGE_VERSION" +echo "------------------------------------------------------------------------" +echo +echo +echo "Configuration Options Summary:" +echo +echo "Loaders:" +echo " XCF..................: yes" +echo " Gstreamer............: ${have_gst}" +echo " PDF..................: ${have_poppler}" +echo " PS...................: ${have_ps}" +echo " RAW..................: ${have_raw}" +echo " SVG..................: ${have_svg}" +echo +echo "Compilation............: make (or gmake)" +echo " CPPFLAGS.............: $CPPFLAGS" +echo " CFLAGS...............: $CFLAGS" +echo " LDFLAGS..............: $LDFLAGS" +echo +echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" +echo " prefix...............: $prefix" +echo diff --git a/legacy/evas_generic_loaders/m4/ac_attribute.m4 b/legacy/evas_generic_loaders/m4/ac_attribute.m4 new file mode 100644 index 0000000000..23479a92ac --- /dev/null +++ b/legacy/evas_generic_loaders/m4/ac_attribute.m4 @@ -0,0 +1,47 @@ +dnl Copyright (C) 2004-2008 Kim Woelders +dnl Copyright (C) 2008 Vincent Torri +dnl That code is public domain and can be freely used or copied. +dnl Originally snatched from somewhere... + +dnl Macro for checking if the compiler supports __attribute__ + +dnl Usage: AC_C___ATTRIBUTE__ +dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__ +dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is +dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused)) +dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is +dnl defined to nothing. + +AC_DEFUN([AC_C___ATTRIBUTE__], +[ + +AC_MSG_CHECKING([for __attribute__]) + +AC_CACHE_VAL([ac_cv___attribute__], + [AC_TRY_COMPILE( + [ +#include + +int func(int x); +int foo(int x __attribute__ ((unused))) +{ + exit(1); +} + ], + [], + [ac_cv___attribute__="yes"], + [ac_cv___attribute__="no"] + )]) + +AC_MSG_RESULT($ac_cv___attribute__) + +if test "x${ac_cv___attribute__}" = "xyes" ; then + AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__]) + AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused]) + else + AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused]) +fi + +]) + +dnl End of ac_attribute.m4 diff --git a/legacy/evas_generic_loaders/m4/ac_path_generic.m4 b/legacy/evas_generic_loaders/m4/ac_path_generic.m4 new file mode 100644 index 0000000000..d42724115f --- /dev/null +++ b/legacy/evas_generic_loaders/m4/ac_path_generic.m4 @@ -0,0 +1,137 @@ +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 + +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]) +]) diff --git a/legacy/evas_generic_loaders/m4/efl.m4 b/legacy/evas_generic_loaders/m4/efl.m4 new file mode 100644 index 0000000000..3598ce78fe --- /dev/null +++ b/legacy/evas_generic_loaders/m4/efl.m4 @@ -0,0 +1,449 @@ +dnl file to manage modules in efl + +dnl EFL_VERSION(major, minor, micro, release) +dnl This setup EFL version information and should be called BEFORE AC_INIT(). +dnl +dnl release parameter is 'dev' to use from SVN or libtool -release field. +dnl It may be empty if not dev (svn/live build) and no -release is to be used. +dnl +dnl Examples: +dnl EFL_VERSION(1, 7, 99, dev) +dnl EFL_VERSION(1, 7, 99, ver-1234) +dnl This will define couple of m4 symbols: +dnl v_maj = given major number (first parameter) +dnl v_min = given minor number (second parameter) +dnl v_mic = given micro number (third parameter) +dnl v_rev = if release, it's 0, otherwise it's dev_version. +dnl v_rel = if release, it's -release followed by fourth parameter, +dnl otherwise it's empty. (mostly for libtool) +dnl efl_version = if release, it's major.minor.micro, otherwise it's +dnl major.minor.micro.dev_version +dnl dev_version = development version (svn revision). +dnl def_build_profile = dev or release based on 'dev' release parameter. +AC_DEFUN([EFL_VERSION], +[dnl +m4_define([v_maj], [$1])dnl +m4_define([v_min], [$2])dnl +m4_define([v_mic], [$3])dnl +m4_define([dev_version], m4_esyscmd([(git rev-list --count HEAD 2>/dev/null || echo 0) | tr -d '\n']))dnl +m4_define([v_rev], m4_if($4, dev, [dev_version], [0]))dnl +m4_define([v_rel], [])dnl +m4_define([def_build_profile], m4_if($4, dev, [dev], [release]))dnl +m4_define([efl_version], m4_if($4, dev, [v_maj.v_min.v_mic.v_rev], [v_maj.v_min.v_mic]))dnl +dnl m4_define([efl_version], [v_maj.v_min.v_mic])dnl +]) + +dnl EFL_COLOR +dnl will check if terminal supports color and if color is wanted by user. +dnl +dnl Used Variables: +dnl WANT_COLOR: if no, forces no color output. +dnl TERM: used to check if color should be enabled. +dnl +dnl Defined Variables: +dnl COLOR_YES: to be used in positive/yes conditions +dnl COLOR_NO: to be used in negative/no conditions +dnl COLOR_OTHER: to be used to highlight some other condition +dnl COLOR_RESET: to reset color +dnl want_color: yes or no +AC_DEFUN([EFL_COLOR], +[dnl +case "$TERM" in + xterm|xterm-color|xterm-256color|Eterm|aterm|kterm|rxvt*|screen|gnome|interix) + want_color="${WANT_COLOR:-yes}" + ;; + *) + want_color="no" + ;; +esac + +### echo compatibility + +## the BSD echo does not have the -e option (it is the default behaviour) +echo_e= +if test "`echo -e x`" = "x"; then + echo_e=-e +fi +AC_SUBST([ECHO_E], [${echo_e}]) + +if test "${want_color}" = "yes"; then + COLOR_YES=`echo $echo_e "\033@<:@1;32m"` + COLOR_NO=`echo $echo_e "\033@<:@1;31m"` + COLOR_OTHER=`echo $echo_e "\033@<:@1;36m"` + COLOR_RESET=`echo $echo_e "\033@<:@0m"` +else + COLOR_YES="" + COLOR_NO="" + COLOR_OTHER="" + COLOR_RESET="" +fi +]) + +dnl EFL_INIT() +dnl Will AC_DEFINE() the following: +dnl VMAJ = v_maj +dnl VMIN = v_min +dnl VMIC = v_mic +dnl VREV = v_rev +dnl Will AC_SUBST() the following: +dnl VMAJ = v_maj +dnl VMIN = v_min +dnl VMIC = v_mic +dnl EFL_LTLIBRARY_FLAGS="-no-undefined -version-info ..." +dnl EFL_LTMODULE_FLAGS="-no-undefined -avoid-version" +dnl Will define the following m4: +dnl lt_cur = libtool 'current' field of libtool's -version-info +dnl lt_rev = libtool 'revision' field of libtool's -version-info +dnl lt_age = libtool 'age' field of libtool's -version-info +AC_DEFUN([EFL_INIT], +[dnl +AC_REQUIRE([EFL_COLOR])dnl +AC_DEFINE_UNQUOTED([VMAJ], [v_maj], [Major version])dnl +AC_DEFINE_UNQUOTED([VMIN], [v_min], [Minor version])dnl +AC_DEFINE_UNQUOTED([VMIC], [v_mic], [Micro version])dnl +AC_DEFINE_UNQUOTED([VREV], [v_rev], [Revison])dnl +VMAJ=v_maj +VMIN=v_min +VMIC=v_mic +AC_SUBST([VMAJ])dnl +AC_SUBST([VMIN])dnl +AC_SUBST([VMIC])dnl +dnl +dnl TODO: warning - lt_cur: +dnl the previous code assumed v_maj + v_min, but this will be a problem when +dnl we bump v_maj and reset v_min. 1 + 7 == 7 + 1, so if v_maj is bumped +dnl we multiply it by 100. +m4_define([lt_cur], m4_if(m4_cmp(v_maj, 1), 0, m4_eval(v_maj + v_min), m4_eval(v_maj * 100 + v_min)))dnl +m4_define([lt_rev], v_mic)dnl +m4_define([lt_age], v_min)dnl +dnl +EFL_LTLIBRARY_FLAGS="-no-undefined -version-info lt_cur:lt_rev:lt_age v_rel" +AC_SUBST(EFL_LTLIBRARY_FLAGS)dnl +EFL_LTMODULE_FLAGS="-no-undefined -avoid-version" +AC_SUBST([EFL_LTMODULE_FLAGS])dnl +AC_MSG_NOTICE([Initialized AC_PACKAGE_NAME (AC_PACKAGE_VERSION) development=dev_version v_rel]) +]) + +dnl EFL_EVAL_PKGS(EFL) +dnl does PKG_CHECK_MODULES() for given EFL +AC_DEFUN([EFL_EVAL_PKGS], +[dnl +m4_pushdef([DOWNEFL], m4_translit([$1], [-A-Z], [_a-z]))dnl +if test "x${requirements_pc_deps_[]m4_defn([DOWNEFL])}" != "x"; then + PKG_CHECK_MODULES([$1], [${requirements_pc_deps_[]m4_defn([DOWNEFL])}]) +fi +m4_popdef([DOWNEFL])dnl +]) + +dnl EFL_INTERNAL_DEPEND_PKG(EFL, OTHEREFL) +dnl Adds a pkg-config dependency on another EFL. +AC_DEFUN([EFL_INTERNAL_DEPEND_PKG], +[dnl +m4_pushdef([DOWNEFL], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([DOWNOTHER], m4_translit([$2], [-A-Z], [_a-z]))dnl +dnl TODO: we need to fix the package config names for 2.0 +dnl TODO: and make them uniform in scheme. +depname="$2" +libdirname="m4_defn([DOWNOTHER])" +libname="m4_defn([DOWNOTHER])" +case "m4_defn([DOWNOTHER])" in + ethumb_client) + depname="ethumb_client" + ;; +esac +requirements_pc_[]m4_defn([DOWNEFL])="${depname} >= ${PACKAGE_VERSION} ${requirements_pc_[][]m4_defn([DOWNEFL])}" +requirements_cflags_[]m4_defn([DOWNEFL])="-I\$(top_srcdir)/src/lib/${libdirname} -I\$(top_builddir)/src/lib/${libdirname} ${requirements_cflags_[][]m4_defn([DOWNEFL])}" +requirements_internal_libs_[]m4_defn([DOWNEFL])="lib/${libdirname}/lib${libname}.la ${requirements_internal_libs_[][]m4_defn([DOWNEFL])}" +requirements_internal_deps_libs_[]m4_defn([DOWNEFL])="${requirements_public_libs_[]m4_defn([DOWNOTHER])} ${requirements_internal_deps_libs_[][]m4_defn([DOWNEFL])}" +m4_popdef([DOWNOTHER])dnl +m4_popdef([DOWNEFL])dnl +]) + +dnl EFL_PLATFORM_DEPEND(EFL, PLATFORM) +dnl PLATFORM is one of: all, evil, escape, exotic +AC_DEFUN([EFL_PLATFORM_DEPEND], +[dnl +m4_pushdef([DOWNOTHER], m4_translit([$2], [-A-Z], [_a-z]))dnl +case "m4_defn([DOWNOTHER])" in + all) + if test "x${efl_lib_optional_evil}" = "xyes"; then + EFL_INTERNAL_DEPEND_PKG([$1], [evil]) + elif test "x${efl_lib_optional_escape}" = "xyes"; then + EFL_INTERNAL_DEPEND_PKG([$1], [escape]) + elif test "x${efl_lib_optional_exotic}" = "xyes"; then + EFL_INTERNAL_DEPEND_PKG([$1], [exotic]) + fi + ;; + *) + if test "x${efl_lib_optional_[]m4_defn([DOWNOTHER])}" = "xyes"; then + EFL_INTERNAL_DEPEND_PKG([$1], [$2]) + fi + ;; +esac +m4_popdef([DOWNOTHER])dnl +]) + +dnl EFL_CRYPTO_DEPEND(EFL) +dnl the given EFL will use/depend on system crypto settings +AC_DEFUN([EFL_CRYPTO_DEPEND], +[dnl +m4_pushdef([DOWNEFL], m4_translit([$1], [-A-Z], [_a-z]))dnl +requirements_pc_[]m4_defn([DOWNEFL])="${requirements_pc_crypto} ${requirements_pc_[][]m4_defn([DOWNEFL])}" +requirements_pc_deps_[]m4_defn([DOWNEFL])="${requirements_pc_deps_crypto} ${requirements_pc_deps_[][]m4_defn([DOWNEFL])}" +requirements_libs_[]m4_defn([DOWNEFL])="${requirements_libs_crypto} ${requirements_libs_[][]m4_defn([DOWNEFL])}" +requirements_cflags_[]m4_defn([DOWNEFL])="${requirements_cflags_crypto} ${requirements_cflags_[][]m4_defn([DOWNEFL])}" +m4_popdef([DOWNEFL])dnl +]) + +dnl EFL_DEPEND_PKG(EFL, NAME, PACKAGE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl Adds a pkg-config dependency to an efl, AC_DEFINE() HAVE_NAME, +dnl and inserts dependencies in proper variables +AC_DEFUN([EFL_DEPEND_PKG], +[dnl +m4_pushdef([UPEFL], m4_translit([$1], [-a-z], [_A-Z]))dnl +m4_pushdef([DOWNEFL], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([UPNAME], m4_translit([$2], [-a-z], [_A-Z]))dnl +m4_pushdef([DOWNNAME], m4_translit([$2], [-A-Z], [_a-z]))dnl + + have_[]m4_defn([DOWNNAME])="no" + + EFL_PKG_CHECK_STRICT([$3], [ + AC_DEFINE([HAVE_]m4_defn([UPNAME]), [1], [Have `]m4_defn([DOWNNAME])[' pkg-config installed.]) + requirements_pc_[]m4_defn([DOWNEFL])="$3 ${requirements_pc_[][]m4_defn([DOWNEFL])}" + requirements_pc_deps_[]m4_defn([DOWNEFL])="$3 ${requirements_pc_deps_[]m4_defn([DOWNEFL])}" + have_[]m4_defn([DOWNNAME])="yes" + + $4 + + ], [$5]) + +m4_popdef([DOWNNAME]) +m4_popdef([UPNAME]) +m4_popdef([DOWNEFL]) +m4_popdef([UPEFL]) +]) + +dnl EFL_OPTIONAL_DEPEND_PKG(EFL, VARIABLE, NAME, PACKAGE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +AC_DEFUN([EFL_OPTIONAL_DEPEND_PKG], +[dnl +m4_pushdef([DOWN], m4_translit([$3], [-A-Z], [_a-z]))dnl + + have_[]m4_defn([DOWN])="no" + if test "x$2" = "xyes"; then + EFL_DEPEND_PKG([$1], [$3], [$4], [$5], [$6]) + fi +m4_popdef([DOWN])dnl +]) + +dnl EFL_OPTIONAL_INTERNAL_DEPEND_PKG(EFL, VARIABLE, NAME) +AC_DEFUN([EFL_OPTIONAL_INTERNAL_DEPEND_PKG], +[dnl + if test "x$2" = "xyes"; then + EFL_INTERNAL_DEPEND_PKG([$1], [$3]) + fi +]) + +dnl EFL_ADD_LIBS(PKG, LIBS) +dnl Add libraries that the EFL library will depend on +dnl See EFL_DEPEND_PKG() for pkg-config version. +AC_DEFUN([EFL_ADD_LIBS], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +requirements_libs_[]m4_defn([DOWN])="${requirements_libs_[]m4_defn([DOWN])} $2" +m4_popdef([DOWN])dnl +]) + +dnl EFL_ADD_PUBLIC_LIBS(PKG, PUBLIC_LIBS) +dnl Add libraries that the EFL library will depend on when used. +dnl +dnl Unlike EFL_ADD_LIBS(), that is only used when generating PKG, +dnl this one is used when linking PKG to other libraries or applications. +dnl +dnl For instance if you use some other library in your header that user +dnl inclues. +AC_DEFUN([EFL_ADD_PUBLIC_LIBS], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +requirements_public_libs_[]m4_defn([DOWN])="${requirements_public_libs_[]m4_defn([DOWN])} $2" +m4_popdef([DOWN])dnl +]) + +dnl EFL_ADD_CFLAGS(PKG, CFLAGS) +dnl Add CFLAGS that the EFL library will use +dnl See EFL_DEPEND_PKG() for pkg-config version. +AC_DEFUN([EFL_ADD_CFLAGS], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +requirements_cflags_[]m4_defn([DOWN])="${requirements_cflags_[]m4_defn([DOWN])} $2" +m4_popdef([DOWN])dnl +]) + +dnl EFL_LIB_START(PKG) +dnl start the setup of an EFL library, defines variables and prints a notice +dnl +dnl Exports (AC_SUBST) +dnl PKG_CFLAGS: what to use for CFLAGS +dnl +dnl PKG_LDFLAGS: what to use for LDFLAGS +dnl +dnl PKG_LIBS: what to use in automake's _LIBADD or _LDADD. Includes +dnl everything else. +dnl +dnl PKG_INTERNAL_LIBS: all other EFL as lib/name/libname.la that this +dnl package depend. Used in automake's _DEPENDENCIES. +dnl +dnl USE_PKG_LIBS: what to use in automake's _LIBADD or _LDADD when using +dnl this PKG (PKG_LIBS + libpkg.la) +dnl +dnl USE_PKG_INTERNAL_LIBS: extends PKG_INTERNAL_LIBS with lib/pkg/libpkg.la +dnl +dnl requirements_pc_pkg: all pkg-config (pc) files used by this pkg, +dnl includes internal EFL (used in 'Requires.private' in pkg.pc) +dnl +dnl requirements_libs_pkg: external libraries this package needs when +dnl linking (used in 'Libs.private' in pkg.pc) +dnl +dnl requirements_public_libs_pkg: external libraries other packages need +dnl when using this (used in 'Libs' in pkg.pc) +dnl +dnl requirements_cflags_pkg: what to use for CFLAGS (same as PKG_CFLAGS). +dnl +dnl Variables: +dnl requirements_pc_deps_pkg: external pkg-config (pc) files used by this +dnl pkg (used in EFL_EVAL_PKGS()) +dnl +dnl requirements_internal_libs_pkg: all other EFL as lib/name/libname.la +dnl that this package depend. +dnl +dnl requirements_internal_deps_libs_pkg: external libraries that are public +dnl dependencies (due internal libs). +dnl +AC_DEFUN([EFL_LIB_START], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl + +requirements_internal_libs_[]m4_defn([DOWN])="" +requirements_internal_deps_libs_[]m4_defn([DOWN])="" +requirements_libs_[]m4_defn([DOWN])="" +requirements_public_libs_[]m4_defn([DOWN])="" +requirements_cflags_[]m4_defn([DOWN])="" +requirements_pc_[]m4_defn([DOWN])="" +requirements_pc_deps_[]m4_defn([DOWN])="" + +m4_defn([UP])_LIBS="${m4_defn([UP])_LIBS}" +m4_defn([UP])_INTERNAL_LIBS="${m4_defn([UP])_INTERNAL_LIBS}" +USE_[]m4_defn([UP])_LIBS="${USE_[]m4_defn([UP])_LIBS}" +USE_[]m4_defn([UP])_INTERNAL_LIBS="${USE_[]m4_defn([UP])_INTERNAL_LIBS}" +m4_defn([UP])_LDFLAGS="${m4_defn([UP])_LDFLAGS}" +m4_defn([UP])_CFLAGS="${m4_defn([UP])_CFLAGS}" + +AC_SUBST([requirements_libs_]m4_defn([DOWN]))dnl +AC_SUBST([requirements_public_libs_]m4_defn([DOWN]))dnl +AC_SUBST([requirements_cflags_]m4_defn([DOWN]))dnl +AC_SUBST([requirements_pc_]m4_defn([DOWN]))dnl +AC_SUBST(m4_defn([UP])[_LIBS])dnl +AC_SUBST(m4_defn([UP])[_INTERNAL_LIBS])dnl +AC_SUBST([USE_]m4_defn([UP])[_LIBS])dnl +AC_SUBST([USE_]m4_defn([UP])[_INTERNAL_LIBS])dnl +AC_SUBST(m4_defn([UP])[_LDFLAGS])dnl +AC_SUBST(m4_defn([UP])[_CFLAGS])dnl +AC_MSG_NOTICE([Start $1 checks])dnl +m4_popdef([UP])dnl +m4_popdef([DOWN])dnl +]) + +dnl EFL_LIB_END(PKG) +dnl finishes the setup of an EFL library +AC_DEFUN([EFL_LIB_END], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl + +libdirname="m4_defn([DOWN])" +libname="m4_defn([DOWN])" + +m4_defn([UP])_LDFLAGS="${EFLALL_COV_LDFLAGS} ${EFLALL_LDFLAGS} ${m4_defn([UP])_LDFLAGS}" +m4_defn([UP])_LIBS=" ${m4_defn([UP])_LDFLAGS} ${EFLALL_COV_LIBS} ${EFLALL_LIBS} ${m4_defn([UP])_LIBS} ${requirements_internal_libs_[]m4_defn([DOWN])} ${requirements_internal_deps_libs_[]m4_defn([DOWN])} ${requirements_public_libs_[]m4_defn([DOWN])} ${requirements_libs_[]m4_defn([DOWN])} ${requirements_libs_eflall} " +m4_defn([UP])_INTERNAL_LIBS="${m4_defn([UP])_INTERNAL_LIBS} ${requirements_internal_libs_[]m4_defn([DOWN])}" +USE_[]m4_defn([UP])_LIBS="${m4_defn([UP])_LIBS} lib/${libdirname}/lib${libname}.la" +USE_[]m4_defn([UP])_INTERNAL_LIBS="${m4_defn([UP])_INTERNAL_LIBS} lib/${libdirname}/lib${libname}.la" +m4_defn([UP])_CFLAGS="${EFLALL_COV_CFLAGS} ${EFLALL_CFLAGS} ${m4_defn([UP])_CFLAGS} -I\$(top_srcdir)/src/lib/${libdirname} -I\$(top_builddir)/src/lib/${libdirname} -I\$(top_srcdir)/src/bindings/${libdirname} -I\$(top_builddir)/src/bindings/${libdirname} ${requirements_cflags_[]m4_defn([DOWN])} ${requirements_cflags_eflall} -DEFL_[]m4_defn([UP])_BUILD=1" +requirements_pc_[]m4_defn([DOWN])="${requirements_pc_[]m4_defn([DOWN])} ${requirements_pc_eflall}" +requirements_pc_deps_[]m4_defn([DOWN])="${requirements_pc_deps_[]m4_defn([DOWN])} ${requirements_pc_deps_eflall}" + +AC_MSG_NOTICE([Finished $1 checks])dnl +m4_popdef([UP])dnl +m4_popdef([DOWN])dnl +]) + +dnl EFL_LIB_START_OPTIONAL(PKG, TEST) +dnl test if library should be build and then EFL_LIB_START() +dnl must call EFL_LIB_END_OPTIONAL() to close it. +AC_DEFUN([EFL_LIB_START_OPTIONAL], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl + +if $2; then + efl_lib_optional_[]m4_defn([DOWN])="yes" +else + efl_lib_optional_[]m4_defn([DOWN])="no" + AC_MSG_NOTICE([Skipping $1 checks (disabled)]) +fi + +if test "$efl_lib_optional_[]m4_defn([DOWN])" = "yes"; then + EFL_LIB_START([$1]) + AC_DEFINE([HAVE_]m4_defn([UP]), [1], [optional EFL $1 is enabled]) +dnl closed at EFL_LIB_END_OPTIONAL() +m4_popdef([UP])dnl +m4_popdef([DOWN])dnl +]) + +dnl EFL_LIB_END_OPTIONAL(PKG) +dnl closes block started by EFL_LIB_START_OPTIONAL() and then +dnl defines AM_CONDITIONAL([HAVE_PKG]) and AC_DEFINE([HAVE_PKG]) +AC_DEFUN([EFL_LIB_END_OPTIONAL], +[dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl + +dnl close if started at EFL_LIB_START_OPTIONAL() + EFL_LIB_END([$1]) +fi + +AM_CONDITIONAL([HAVE_]m4_defn([UP]), [test "$efl_lib_optional_[]m4_defn([DOWN])" = "yes"])dnl +m4_popdef([UP])dnl +m4_popdef([DOWN])dnl +]) + +dnl EFL_ADD_FEATURE(PKG, NAME, [VALUE]) +dnl if VALUE is not specified, will use ${have_name} instead. +dnl +dnl Defined Variables: +dnl features_pkg +AC_DEFUN([EFL_ADD_FEATURE], +[dnl +m4_pushdef([DOWNPKG], m4_translit([$1], [-A-Z], [_a-z]))dnl +m4_pushdef([DOWNNAME], m4_translit([$2], [-A-Z], [_a-z]))dnl + +value="m4_if($3, , [${have_]m4_defn([DOWNNAME])[:-${want_]m4_defn([DOWNNAME])[}}], [$3])" +case "${value}" in + yes) + tmp="${COLOR_YES}+$2${COLOR_RESET}" + ;; + no) + tmp="${COLOR_NO}-$2${COLOR_RESET}" + ;; + *) + tmp="${COLOR_OTHER}$2=${value}${COLOR_RESET}" + ;; +esac +if test -z "${features_[]m4_defn([DOWNPKG])}"; then + features_[]m4_defn([DOWNPKG])="${tmp}" +else + features_[]m4_defn([DOWNPKG])="${features_[]m4_defn([DOWNPKG])} ${tmp}" +fi +m4_popdef([DOWNNAME])dnl +m4_popdef([DOWNPKG])dnl +]) diff --git a/legacy/evas_generic_loaders/pkgbuild/PKGBUILD.in b/legacy/evas_generic_loaders/pkgbuild/PKGBUILD.in new file mode 100644 index 0000000000..7aaebf4962 --- /dev/null +++ b/legacy/evas_generic_loaders/pkgbuild/PKGBUILD.in @@ -0,0 +1,36 @@ +# Maintainer: Enlightenment Developers +pkgname=evas_generic_loaders +pkgver=@VERSION@ +pkgrel=1 +pkgdesc="Evas external binary executable loaders - GIT development snapshot" +arch=('i686' 'x86_64' 'arm') +url="http://www.enlightenment.org" +license=('GPL2') +depends=('efl' 'poppler' 'libraw' 'libspectre' 'librsvg' 'gstreamer0.10-base-plugins' + 'gstreamer0.10-good-plugins' 'gstreamer0.10-bad-plugins' + 'gstreamer0.10-ugly-plugins' 'gstreamer0.10-ffmpeg') +options=('!libtool' 'debug') +build() { + cd "../.." + export CFLAGS="$CFLAGS -fvisibility=hidden -fomit-frame-pointer" + make clean distclean + ./configure --prefix=/usr + make +} + +#check() { +# cd "../.." +# make -k check +#} + +package() { + cd "../.." + make -j1 DESTDIR="$pkgdir/" install + install -Dm644 README "$pkgdir/usr/share/$pkgname/README" + install -Dm644 NEWS "$pkgdir/usr/share/$pkgname/NEWS" + install -Dm644 ChangeLog "$pkgdir/usr/share/$pkgname/ChangeLog" + install -Dm644 AUTHORS "$pkgdir/usr/share/$pkgname/AUTHORS" + install -d "$pkgdir/usr/share/licenses/$pkgname" + sed -n '1,/PARTICULAR PURPOSE/p' COPYING > "$pkgdir/usr/share/licenses/$pkgname/COPYING" + ln -s "../licenses/$pkgname/COPYING" "$pkgdir/usr/share/$pkgname/COPYING" +} diff --git a/legacy/evas_generic_loaders/src/Makefile.am b/legacy/evas_generic_loaders/src/Makefile.am new file mode 100644 index 0000000000..1c5d6ee106 --- /dev/null +++ b/legacy/evas_generic_loaders/src/Makefile.am @@ -0,0 +1,3 @@ +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = bin diff --git a/legacy/evas_generic_loaders/src/bin/Makefile.am b/legacy/evas_generic_loaders/src/bin/Makefile.am new file mode 100644 index 0000000000..040ae49f79 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/Makefile.am @@ -0,0 +1,24 @@ +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = common \ +xcf + +if HAVE_GST +SUBDIRS += gst +endif + +if HAVE_PDF +SUBDIRS += pdf +endif + +if HAVE_PS +SUBDIRS += ps +endif + +if HAVE_RAW +SUBDIRS += raw +endif + +if HAVE_SVG +SUBDIRS += svg +endif diff --git a/legacy/evas_generic_loaders/src/bin/common/Makefile.am b/legacy/evas_generic_loaders/src/bin/common/Makefile.am new file mode 100644 index 0000000000..59035f0389 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/common/Makefile.am @@ -0,0 +1,3 @@ +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = shmfile.c shmfile.h timeout.c timeout.h diff --git a/legacy/evas_generic_loaders/src/bin/common/shmfile.c b/legacy/evas_generic_loaders/src/bin/common/shmfile.c new file mode 100644 index 0000000000..538a3149a7 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/common/shmfile.c @@ -0,0 +1,87 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int shm_fd = -1; +static int shm_size = 0; +void *shm_addr = NULL; +char *shmfile = NULL; + +void +shm_alloc(unsigned long dsize) +{ +#ifdef HAVE_SHM_OPEN + if (!shmfile) shmfile = malloc(1024); + if (!shmfile) goto failed; + shmfile[0] = 0; + srand(time(NULL)); + do + { + snprintf(shmfile, 1024, "/evas-loader.%i.%i", + (int)getpid(), (int)rand()); + shm_fd = shm_open(shmfile, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + } + while (shm_fd < 0); + + if (ftruncate(shm_fd, dsize) < 0) + { + close(shm_fd); + shm_unlink(shmfile); + shm_fd = -1; + goto failed; + } + shm_addr = mmap(NULL, dsize, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (shm_addr == MAP_FAILED) + { + close(shm_fd); + shm_unlink(shmfile); + shm_fd = -1; + goto failed; + } + shm_size = dsize; + return; +failed: +#endif + shm_addr = malloc(dsize); +} + +void +shm_free(void) +{ +#ifdef HAVE_SHM_OPEN + if (shm_fd >= 0) + { + munmap(shm_addr, shm_size); + close(shm_fd); + shm_fd = -1; + shm_addr = NULL; + if (shmfile) free(shmfile); + shmfile = NULL; + return; + } +#endif + free(shm_addr); + shm_addr = NULL; + shm_fd = -1; +} + +#ifdef __cplusplus +} +#endif diff --git a/legacy/evas_generic_loaders/src/bin/common/shmfile.h b/legacy/evas_generic_loaders/src/bin/common/shmfile.h new file mode 100644 index 0000000000..f70a8fd157 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/common/shmfile.h @@ -0,0 +1,20 @@ +#ifndef SHMFILE_H +#define SHMFILE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int shm_fd; +extern int shm_size; +extern void *shm_addr; +extern char *shmfile; + +void shm_alloc (unsigned long dsize); +void shm_free (void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/legacy/evas_generic_loaders/src/bin/common/timeout.c b/legacy/evas_generic_loaders/src/bin/common/timeout.c new file mode 100644 index 0000000000..6d52aa9609 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/common/timeout.c @@ -0,0 +1,16 @@ +#include +#include + +static void +_timeout(int val) +{ + _exit(-1); + if (val) return; +} + +void +timeout_init(int seconds) +{ + signal(SIGALRM, _timeout); + alarm(seconds); +} diff --git a/legacy/evas_generic_loaders/src/bin/common/timeout.h b/legacy/evas_generic_loaders/src/bin/common/timeout.h new file mode 100644 index 0000000000..8725627e06 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/common/timeout.h @@ -0,0 +1,14 @@ +#ifndef TIMEOUT_H +#define TIMEOUT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +void timeout_init(int seconds); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/legacy/evas_generic_loaders/src/bin/gst/Makefile.am b/legacy/evas_generic_loaders/src/bin/gst/Makefile.am new file mode 100644 index 0000000000..955c623f07 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/gst/Makefile.am @@ -0,0 +1,91 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src \ +-I$(top_srcdir)/src/bin \ +-I$(top_srcdir)/src/bin/common \ +-I$(top_srcdir)/src/bin/gst \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EINA_CFLAGS@ \ +@GSTREAMER_CFLAGS@ + +bin_PROGRAMS = evas_image_loader.gst +bindir = $(libdir)/evas/utils + +if HAVE_GST1 + +evas_image_loader_gst_SOURCES = \ +main.c \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c + +else + +evas_image_loader_gst_SOURCES = \ +main_0_10.c \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c + +endif + +evas_image_loader_gst_CFLAGS = +evas_image_loader_gst_LDADD = @GSTREAMER_LIBS@ @EINA_LIBS@ @SHM_OPEN_LIBS@ +evas_image_loader_gst_LDFLAGS = + +## good list of extensions: +## http://www.fileinfo.com/filetypes/video +## should check which ones gst does support and make sure they are here +install-exec-hook: + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.264 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3g2 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gp + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gp2 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gpp + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gpp2 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3p2 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.asf + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.avi + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.bdm + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.bdmv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.clpi + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.cpi + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.dv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.fla + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.flv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m1v + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m2t + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m2v + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m4v + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mkv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mov + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mp2 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mp2ts + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mp4 + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpe + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpeg + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpg + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpl + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpls + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mts + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mxf + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nut + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nuv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ogg + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ogm + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ogv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.qt + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rm + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmj + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmm + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rms + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmx + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmvb + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rv + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.swf + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ts + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.webm + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.weba + ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.wmv diff --git a/legacy/evas_generic_loaders/src/bin/gst/main.c b/legacy/evas_generic_loaders/src/bin/gst/main.c new file mode 100644 index 0000000000..d9e6fa786c --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/gst/main.c @@ -0,0 +1,292 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include + +#include + +#include "shmfile.h" +#include "timeout.h" + +#define DATA32 unsigned int + +//#define GST_DBG + +#ifdef GST_DBG +#define D(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define D(fmt, args...) +#endif + +#ifdef WORDS_BIGENDIAN +# define CAPS "video/x-raw,format=ARGB" +#else +# define CAPS "video/x-raw,format=BGRA" +#endif + +static GstElement *pipeline = NULL; +static GstElement *sink = NULL; +static gint64 duration = -1; + +int width = 0; +int height = 0; +void *data = NULL; + + +static Eina_Bool +_gst_init(const char *filename) +{ + GstPad *pad; + GstCaps *caps; + GstStructure *structure; + gchar *descr; + gchar *uri; + GError *error = NULL; + GstFormat format; + GstStateChangeReturn ret; +// int vidstr = 0; + + if (!filename || !*filename) + return EINA_FALSE; + + if (!gst_init_check(NULL, NULL, &error)) + return EINA_FALSE; + + if ((*filename == '/') || (*filename == '~')) + { + uri = g_filename_to_uri(filename, NULL, NULL); + if (!uri) + { + D("could not create new uri from %s", filename); + goto unref_pipeline; + } + } + else + uri = strdup(filename); + + D("Setting file %s\n", uri); + + descr = g_strdup_printf("uridecodebin uri=%s ! typefind ! videoconvert ! " + " appsink name=sink caps=\"" CAPS "\"", uri); + pipeline = gst_parse_launch(descr, &error); + free(uri); + + if (error != NULL) + { + D("could not construct pipeline: %s\n", error->message); + g_error_free (error); + goto gst_shutdown; + } +/* needs gst 1.0+ + * also only works on playbin objects!!! this is a uridecodebin! + g_object_get(G_OBJECT(pipeline), + "n-video", &vidstr, + NULL); + if (vidstr <= 0) + { + D("no video stream\n"); + goto gst_shutdown; + } +*/ + sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); + + ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); + switch (ret) + { + case GST_STATE_CHANGE_FAILURE: + D("failed to play the file\n"); + goto unref_pipeline; + case GST_STATE_CHANGE_NO_PREROLL: + D("live sources not supported yet\n"); + goto unref_pipeline; + default: + break; + } + + ret = gst_element_get_state((pipeline), NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret == GST_STATE_CHANGE_FAILURE) + { + D("could not complete pause\n"); + goto unref_pipeline; + } + + format = GST_FORMAT_TIME; + gst_element_query_duration (pipeline, format, &duration); + if (duration == -1) + { + fprintf(stderr, "duration fetch err\n"); + D("could not retrieve the duration, set it to 1s\n"); + duration = 1 * GST_SECOND; + } + + pad = gst_element_get_static_pad(sink, "sink"); + if (!pad) + { + D("could not retrieve the sink pad\n"); + goto unref_pipeline; + } + + caps = gst_pad_get_current_caps(pad); + if (!caps) + goto unref_pad; + + structure = gst_caps_get_structure(caps, 0); + + if (!gst_structure_get_int(structure, "width", &width)) + goto unref_caps; + if (!gst_structure_get_int(structure, "height", &height)) + goto unref_caps; + + gst_caps_unref(caps); + gst_object_unref(pad); + + return EINA_TRUE; + + unref_caps: + gst_caps_unref(caps); + unref_pad: + gst_object_unref(pad); + unref_pipeline: + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref(pipeline); + gst_shutdown: + gst_deinit(); + + return EINA_FALSE; +} + +static void +_gst_shutdown() +{ + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref(pipeline); + gst_deinit(); +} + +static void +_gst_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED, double pos) +{ + GstBuffer *buffer; + GstMapInfo info; + GstSample *sample; + + D("load image\n"); + if (pos >= 0.0) + gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, + pos); + else + gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, + duration / 2); + g_signal_emit_by_name(sink, "pull-preroll", &sample, NULL); + + shm_alloc(width * height * sizeof(DATA32)); + if (!shm_addr) return; + data = shm_addr; + + buffer = gst_sample_get_buffer (sample); + gst_buffer_map (buffer, &info, GST_MAP_READ); + D("load image: %p %d\n", info.data, info.size); + + memcpy(data, info.data, info.size); + + gst_buffer_unmap(buffer, &info); +} + +int +main(int argc, char **argv) +{ + char *file, *p; + int i, numonly; + int size_w = 0, size_h = 0; + int head_only = 0; + long long pos = -1.0; + + if (argc < 2) return -1; + // file is ALWAYS first arg, other options come after + file = argv[1]; + for (i = 2; i < argc; i++) + { + if (!strcmp(argv[i], "-head")) + // asked to only load header, not body/data + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { + i++; + numonly = 1; + for (p = argv[i]; *p; p++) + { + if ((*p < '0') || (*p > '9')) + { + numonly = 0; + break; + } + } + if (numonly) pos = atoll(argv[i]) * 1000000; + i++; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { // not used by ps loader + i++; + // int scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { + i++; + } + else if (!strcmp(argv[i], "-opt-size")) + { // not used by ps loader + i++; + size_w = atoi(argv[i]); + i++; + size_h = atoi(argv[i]); + } + } + + timeout_init(10); + + D("_gst_init_file\n"); + + if (!_gst_init(file)) + return -1; + D("_gst_init done\n"); + + if ((pos >= 0) && (pos > duration)) return -1; + + if (!head_only) + { + _gst_load_image(size_w, size_h, pos); + } + + D("size...: %ix%i\n", width, height); + D("alpha..: 0\n"); + + printf("size %i %i\n", width, height); + printf("alpha 0\n"); + + if (!head_only) + { + if (shm_fd >= 0) + { + printf("shmfile %s\n", shmfile); + } + else + { + // could also to "tmpfile %s\n" like shmfile but just + // a mmaped tmp file on the system + printf("data\n"); + fwrite(data, width * height * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + else + printf("done\n"); + + _gst_shutdown(); + fflush(stdout); + return 0; +} diff --git a/legacy/evas_generic_loaders/src/bin/gst/main_0_10.c b/legacy/evas_generic_loaders/src/bin/gst/main_0_10.c new file mode 100644 index 0000000000..3e0c02b823 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/gst/main_0_10.c @@ -0,0 +1,278 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include + +#include + +#include "shmfile.h" +#include "timeout.h" + +#define DATA32 unsigned int + +//#define GST_DBG + +#ifdef GST_DBG +#define D(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define D(fmt, args...) +#endif + +#define CAPS "video/x-raw-rgb,bpp=(int)32,depth=(int)32,endianness=(int)4321,red_mask=(int)0x0000ff00, green_mask=(int)0x00ff0000, blue_mask=(int)0xff000000" + +static GstElement *pipeline = NULL; +static GstElement *sink = NULL; +static gint64 duration = -1; + +int width = 0; +int height = 0; +void *data = NULL; + + +static Eina_Bool +_gst_init(const char *filename) +{ + GstPad *pad; + GstCaps *caps; + GstStructure *structure; + gchar *descr; + gchar *uri; + GError *error = NULL; + GstFormat format; + GstStateChangeReturn ret; +// int vidstr = 0; + + if (!filename || !*filename) + return EINA_FALSE; + + if (!gst_init_check(NULL, NULL, &error)) + return EINA_FALSE; + + if ((*filename == '/') || (*filename == '~')) + { + uri = g_filename_to_uri(filename, NULL, NULL); + if (!uri) + { + D("could not create new uri from %s", filename); + goto unref_pipeline; + } + } + else + uri = strdup(filename); + + D("Setting file %s\n", uri); + + descr = g_strdup_printf("uridecodebin uri=%s ! typefind ! ffmpegcolorspace ! " + " appsink name=sink caps=\"" CAPS "\"", uri); + pipeline = gst_parse_launch(descr, &error); + free(uri); + + if (error != NULL) + { + D("could not construct pipeline: %s\n", error->message); + g_error_free (error); + goto gst_shutdown; + } +/* needs gst 1.0+ + * also only works on playbin objects!!! this is a uridecodebin! + g_object_get(G_OBJECT(pipeline), + "n-video", &vidstr, + NULL); + if (vidstr <= 0) + { + D("no video stream\n"); + goto gst_shutdown; + } +*/ + sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); + + ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); + switch (ret) + { + case GST_STATE_CHANGE_FAILURE: + D("failed to play the file\n"); + goto unref_pipeline; + case GST_STATE_CHANGE_NO_PREROLL: + D("live sources not supported yet\n"); + goto unref_pipeline; + default: + break; + } + + ret = gst_element_get_state((pipeline), NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret == GST_STATE_CHANGE_FAILURE) + { + D("could not complete pause\n"); + goto unref_pipeline; + } + + format = GST_FORMAT_TIME; + gst_element_query_duration (pipeline, &format, &duration); + if (duration == -1) + { + D("could not retrieve the duration, set it to 1s\n"); + duration = 1 * GST_SECOND; + } + + pad = gst_element_get_static_pad(sink, "sink"); + if (!pad) + { + D("could not retrieve the sink pad\n"); + goto unref_pipeline; + } + + caps = gst_pad_get_negotiated_caps(pad); + if (!caps) + goto unref_pad; + + structure = gst_caps_get_structure(caps, 0); + + if (!gst_structure_get_int(structure, "width", &width)) + goto unref_caps; + if (!gst_structure_get_int(structure, "height", &height)) + goto unref_caps; + + gst_caps_unref(caps); + gst_object_unref(pad); + + return EINA_TRUE; + + unref_caps: + gst_caps_unref(caps); + unref_pad: + gst_object_unref(pad); + unref_pipeline: + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref(pipeline); + gst_shutdown: + gst_deinit(); + + return EINA_FALSE; +} + +static void +_gst_shutdown() +{ + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref(pipeline); + gst_deinit(); +} + +static void +_gst_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED, double pos) +{ + GstBuffer *buffer; + + D("load image\n"); + if (pos >= 0.0) + gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, + pos * 1000000000.0); + else + gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, + duration / 2); + g_signal_emit_by_name(sink, "pull-preroll", &buffer, NULL); + D("load image : %p %d\n", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); + + shm_alloc(width * height * sizeof(DATA32)); + if (!shm_addr) return; + data = shm_addr; + + memcpy(data, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); +} + +int +main(int argc, char **argv) +{ + char *file, *p; + int i, numonly; + int size_w = 0, size_h = 0; + int head_only = 0; + long long pos = -1.0; + + if (argc < 2) return -1; + // file is ALWAYS first arg, other options come after + file = argv[1]; + for (i = 2; i < argc; i++) + { + if (!strcmp(argv[i], "-head")) + // asked to only load header, not body/data + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { + i++; + numonly = 1; + for (p = argv[i]; *p; p++) + { + if ((!*p < '0') || (*p > 9)) + { + numonly = 0; + break; + } + } + if (numonly) pos = (double)(atoll(argv[i])) / 1000.0; + i++; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { // not used by ps loader + i++; + // int scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { + i++; + } + else if (!strcmp(argv[i], "-opt-size")) + { // not used by ps loader + i++; + size_w = atoi(argv[i]); + i++; + size_h = atoi(argv[i]); + } + } + + timeout_init(10); + + D("_gst_init_file\n"); + + if (!_gst_init(file)) + return -1; + D("_gst_init done\n"); + + if (!head_only) + { + _gst_load_image(size_w, size_h, pos); + } + + D("size...: %ix%i\n", width, height); + D("alpha..: 0\n"); + + printf("size %i %i\n", width, height); + printf("alpha 0\n"); + + if (!head_only) + { + if (shm_fd >= 0) + { + printf("shmfile %s\n", shmfile); + } + else + { + // could also to "tmpfile %s\n" like shmfile but just + // a mmaped tmp file on the system + printf("data\n"); + fwrite(data, width * height * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + else + printf("done\n"); + + _gst_shutdown(); + fflush(stdout); + return 0; +} diff --git a/legacy/evas_generic_loaders/src/bin/pdf/Makefile.am b/legacy/evas_generic_loaders/src/bin/pdf/Makefile.am new file mode 100644 index 0000000000..d57c9a0a16 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/pdf/Makefile.am @@ -0,0 +1,49 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src \ +-I$(top_srcdir)/src/bin \ +-I$(top_srcdir)/src/bin/common \ +-I$(top_srcdir)/src/bin/pdf \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EINA_CFLAGS@ \ +@POPPLER_CFLAGS@ + +EXTRA_DIST = evas_generic_pdf_loader.libreoffice + +bin_SCRIPTS = evas_generic_pdf_loader.libreoffice +bin_PROGRAMS = evas_image_loader.pdf +bindir = $(libdir)/evas/utils + +evas_image_loader_pdf_SOURCES = \ +main.cpp \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c +evas_image_loader_pdf_CFLAGS = +evas_image_loader_pdf_LDADD = @POPPLER_LIBS@ @EINA_LIBS@ @SHM_OPEN_LIBS@ +evas_image_loader_pdf_LDFLAGS = + +install-exec-hook: + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ppt + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.pptx + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.odp + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xls + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xlsx + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ods + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.doc + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.docx + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.odt + ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rtf + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.ppt + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.pptx + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.odp + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.xls + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.xlsx + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.ods + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.doc + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.docx + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.odt + ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.rtf diff --git a/legacy/evas_generic_loaders/src/bin/pdf/evas_generic_pdf_loader.libreoffice b/legacy/evas_generic_loaders/src/bin/pdf/evas_generic_pdf_loader.libreoffice new file mode 100755 index 0000000000..b36e11e322 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/pdf/evas_generic_pdf_loader.libreoffice @@ -0,0 +1,8 @@ +#!/bin/sh +LOBIN=soffice +if [ -x /usr/lib/libreoffice/program/soffice.bin ]; then + LOBIN=/usr/lib/libreoffice/program/soffice.bin +elif [ -x /usr/lib64/libreoffice/program/soffice.bin ]; then + LOBIN=/usr/lib64/libreoffice/program/soffice.bin +fi +$LOBIN --headless --convert-to pdf --outdir "$2" "$1" diff --git a/legacy/evas_generic_loaders/src/bin/pdf/main.cpp b/legacy/evas_generic_loaders/src/bin/pdf/main.cpp new file mode 100644 index 0000000000..6b1de13ce0 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/pdf/main.cpp @@ -0,0 +1,353 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "shmfile.h" +#include "timeout.h" + +#define DATA32 unsigned int + +//#define PDF_DBG + +#ifdef PDF_DBG +#define D(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define D(fmt, args...) +#endif + + +PDFDoc *pdfdoc; +bool locked = false; + +::Page *page; +int width = 0, height = 0; +int crop_width = 0, crop_height = 0; +void *data = NULL; +double dpi = -1.0; + +#define DEF_DPI 72.0 + +Eina_Bool poppler_init(const char *file, int page_nbr, int size_w, int size_h) +{ + Object obj; + double w, h, cw, ch; + int rot; + + if (!file || !*file) + return EINA_FALSE; + + if (page_nbr < 0) + return EINA_FALSE; + + if (!(globalParams = new GlobalParams())) + return EINA_FALSE; + + if (!eina_init()) + goto del_global_param; + +#ifndef HAVE_POPPLER_031 + if (globalParams->getAntialias()) + globalParams->setAntialias((char *)"yes"); + if (globalParams->getVectorAntialias()) + globalParams->setVectorAntialias((char *)"yes"); +#endif + + pdfdoc = new PDFDoc(new GooString(file), NULL); + if (!pdfdoc) + goto del_global_param; + + if (!pdfdoc->isOk() || (pdfdoc->getErrorCode() == errEncrypted)) + goto del_pdfdoc; + + if (page_nbr >= pdfdoc->getNumPages()) + goto del_pdfdoc; + + /* load the page */ + + page = pdfdoc->getCatalog()->getPage(page_nbr + 1); + if (!page || !page->isOk()) + goto del_pdfdoc; + + w = page->getMediaWidth(); + h = page->getMediaHeight(); + cw = page->getCropWidth(); + ch = page->getCropHeight(); + rot = page->getRotate(); + if (cw > w) cw = w; + if (ch > h) ch = h; + if ((rot == 90) || (rot == 270)) + { + double t; + // swap width & height + t = w; w = h; h = t; + // swap crop width & height + t = cw; cw = ch; ch = t; + } + + if ((size_w > 0) || (size_h > 0)) + { + double w2 = cw, h2 = ch; + + w2 = size_w; + h2 = (size_w * ch) / cw; + if (h2 > size_h) + { + h2 = size_h; + w2 = (size_h * cw) / ch; + } + D("XXXXXXXXXXXXXXXXXXXXx %3.3fx%3.3f\n", w2, h2); + if (w2 > h2) dpi = (w2 * DEF_DPI) / cw; + else dpi = (h2 * DEF_DPI) / ch; + } + + if (dpi > 0.0) + { + cw = (cw * dpi) / DEF_DPI; + ch = (ch * dpi) / DEF_DPI; + w = (w * dpi) / DEF_DPI; + h = (h * dpi) / DEF_DPI; + } + width = w; + height = h; + crop_width = cw; + crop_height = ch; + + return EINA_TRUE; + + del_pdfdoc: + delete pdfdoc; + del_global_param: + delete globalParams; + + return EINA_FALSE; +} + +void poppler_shutdown() +{ + delete pdfdoc; + eina_shutdown(); + delete globalParams; +} + +void poppler_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED) +{ + SplashOutputDev *output_dev; + SplashColor white; + SplashColorPtr color_ptr; + DATA32 *src, *dst; + int y; + + white[0] = 255; + white[1] = 255; + white[2] = 255; + white[3] = 255; + + output_dev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, white); + if (!output_dev) + return; + +#if defined(HAVE_POPPLER_020) || defined(HAVE_POPPLER_031) + output_dev->startDoc(pdfdoc); +#else + output_dev->startDoc(pdfdoc->getXRef()); +#endif + + if (dpi <= 0.0) dpi = DEF_DPI; + +#ifdef HAVE_POPPLER_031 + output_dev->setFontAntialias(EINA_TRUE); + output_dev->setVectorAntialias(EINA_TRUE); +#endif + +#if defined(HAVE_POPPLER_020) || defined(HAVE_POPPLER_031) + page->displaySlice(output_dev, dpi, dpi, + 0, false, false, + 0, 0, width, height, + false, NULL, NULL); +#else + page->displaySlice(output_dev, dpi, dpi, + 0, false, false, + 0, 0, width, height, + false, pdfdoc->getCatalog()); +#endif + color_ptr = output_dev->getBitmap()->getDataPtr(); + + shm_alloc(crop_width * crop_height * sizeof(DATA32)); + if (!shm_addr) goto del_outpput_dev; + data = shm_addr; + src = (DATA32 *)color_ptr; + dst = (DATA32 *)data; + for (y = 0; y < crop_height; y++) + { + memcpy(dst, src, crop_width * sizeof(DATA32)); + src += width; + dst += crop_width; + } + + del_outpput_dev: + delete output_dev; +} + +int +main(int argc, char **argv) +{ + Eina_Tmpstr *tmpdir = NULL; + Eina_Tmpstr *generated = NULL; + char *extension; + char *dir; + char *file; + int i; + int size_w = 0, size_h = 0; + int head_only = 0; + int page_num = 0; + + if (argc < 2) return -1; + // file is ALWAYS first arg, other options come after + file = argv[1]; + for (i = 2; i < argc; i++) + { + if (!strcmp(argv[i], "-head")) + // asked to only load header, not body/data + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { + i++; + page_num = atoi(argv[i]); + i++; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { // not used by pdf loader + i++; + // int scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { + i++; + dpi = ((double)atoi(argv[i])) / 1000.0; // dpi is an int multiplied by 1000 (so 72dpi is 72000) + i++; + } + else if (!strcmp(argv[i], "-opt-size")) + { // not used by pdf loader + i++; + size_w = atoi(argv[i]); + i++; + size_h = atoi(argv[i]); + } + } + + D("dpi....: %f\n", dpi); + D("page...: %d\n", page_num); + + // This is a funny hack to call an external tool to generate a pdf that will then be processed by poppler + extension = strrchr(file, '.'); + dir = dirname(argv[0]); + if (extension && dir && strcmp(extension, ".pdf")) + { + if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir)) + { + Eina_Strbuf *tmp; + FILE *cmd; + + tmp = eina_strbuf_new(); + eina_strbuf_append_printf(tmp, "%s/evas_generic_pdf_loader.%s '%s' %s", dir, extension + 1, file, tmpdir); + + cmd = popen(eina_strbuf_string_get(tmp), "r"); + D("running preprocessing process '%s'...\n", eina_strbuf_string_get(tmp)); + eina_strbuf_reset(tmp); + + if (cmd) + { + struct stat st; + const char *filename; + char buf[1024]; + + while (fgets(buf, sizeof (buf), cmd)) + ; + pclose(cmd); + + filename = basename(file); + generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension)); + + eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated); + + eina_tmpstr_del(generated); + generated = NULL; + + if (stat(eina_strbuf_string_get(tmp), &st) == 0) + { + generated = eina_tmpstr_add_length(eina_strbuf_string_get(tmp), + eina_strbuf_length_get(tmp)); + file = (char*) generated; + } + } + + D("generated file: '%s'\n", generated); + eina_strbuf_free(tmp); + } + } + + // Let's force a timeout if things go wrong + timeout_init(10); + + // Now process the pdf (or the generated pdf) + D("poppler_file_init\n"); + if (!poppler_init(file, page_num, size_w, size_h)) + return -1; + D("poppler_file_init done\n"); + + D("dpi2...: %f\n", dpi); + if (!head_only) + { + poppler_load_image(size_w, size_h); + } + + D("size...: %ix%i\n", width, height); + D("crop...: %ix%i\n", crop_width, crop_height); + D("alpha..: 1\n"); + + printf("size %i %i\n", crop_width, crop_height); + printf("alpha 0\n"); + + if (!head_only) + { + if (shm_fd >= 0) printf("shmfile %s\n", shmfile); + else + { + // could also to "tmpfile %s\n" like shmfile but just + // a mmaped tmp file on the system + printf("data\n"); + fwrite(data, crop_width * crop_height * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + else + printf("done\n"); + + poppler_shutdown(); + + if (tmpdir) + { + if (generated) unlink(generated); + rmdir(tmpdir); + + eina_tmpstr_del(tmpdir); + eina_tmpstr_del(generated); + } + fflush(stdout); + return 0; +} diff --git a/legacy/evas_generic_loaders/src/bin/ps/Makefile.am b/legacy/evas_generic_loaders/src/bin/ps/Makefile.am new file mode 100644 index 0000000000..eb62cc62a4 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/ps/Makefile.am @@ -0,0 +1,24 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src \ +-I$(top_srcdir)/src/bin \ +-I$(top_srcdir)/src/bin/common \ +-I$(top_srcdir)/src/bin/ps \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EINA_CFLAGS@ \ +@SPECTRE_CFLAGS@ + +bin_PROGRAMS = evas_image_loader.ps +bindir = $(libdir)/evas/utils + +evas_image_loader_ps_SOURCES = \ +main.c \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c +evas_image_loader_ps_CFLAGS = +evas_image_loader_ps_LDADD = @SPECTRE_LIBS@ @EINA_LIBS@ @SHM_OPEN_LIBS@ +evas_image_loader_ps_LDFLAGS = diff --git a/legacy/evas_generic_loaders/src/bin/ps/main.c b/legacy/evas_generic_loaders/src/bin/ps/main.c new file mode 100644 index 0000000000..48e8a4b6f6 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/ps/main.c @@ -0,0 +1,289 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include + +#include + +#include "shmfile.h" +#include "timeout.h" + +#define DATA32 unsigned int + +#define PS_DBG + +#ifdef PS_DBG +#define D(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define D(fmt, args...) +#endif + + +static SpectreDocument *psdoc; +static int page_count; + +static SpectrePage *page; + +static int width = 0; +static int height = 0; +static void *data = NULL; +static double dpi = -1.0; + +#define DEF_DPI 72.0 + +static Eina_Bool +_spectre_init(const char *file, int page_nbr, int size_w, int size_h) +{ + double w, h; + int ww, hh; + SpectreOrientation rot; + SpectreStatus status; + + if (!file || !*file) + return EINA_FALSE; + + if (page_nbr < 0) + return EINA_FALSE; + + if (!eina_init()) + return EINA_FALSE; + + psdoc = spectre_document_new(); + if (!psdoc) + goto shutdown_eina; + + spectre_document_load(psdoc, file); + status = spectre_document_status (psdoc); + if (status != SPECTRE_STATUS_SUCCESS) + { + D("[ps] %s\n", spectre_status_to_string(status)); + goto free_psdoc; + } + + page_count = spectre_document_get_n_pages(psdoc); + status = spectre_document_status(psdoc); + if (status != SPECTRE_STATUS_SUCCESS) + { + D("[eps] %s\n", spectre_status_to_string (status)); + goto free_psdoc; + } + + if (page_nbr >= page_count) + goto free_psdoc; + + /* load the page */ + + page = spectre_document_get_page(psdoc, page_nbr); + status = spectre_document_status(psdoc); + if (status != SPECTRE_STATUS_SUCCESS) + { + D("[eps] %s\n", spectre_status_to_string (status)); + goto free_page; + } + + spectre_page_get_size(page, &ww, &hh); + w = ww; + h = hh; + rot = spectre_page_get_orientation(page); + + if ((rot == SPECTRE_ORIENTATION_LANDSCAPE) || (rot == SPECTRE_ORIENTATION_REVERSE_LANDSCAPE)) + { + double t; + // swap width & height + t = w; w = h; h = t; + } + + if ((size_w > 0) || (size_h > 0)) + { + double w2 = w, h2 = h; + + w2 = size_w; + h2 = (size_w * h) / w; + if (h2 > size_h) + { + h2 = size_h; + w2 = (size_h * w) / h; + } + D("XXXXXXXXXXXXXXXXXXXXx %3.3fx%3.3f\n", w2, h2); + if (w2 > h2) dpi = (w2 * DEF_DPI) / w; + else dpi = (h2 * DEF_DPI) / h; + } + + if (dpi > 0.0) + { + w = (w * dpi) / DEF_DPI; + h = (h * dpi) / DEF_DPI; + } + width = w; + height = h; + + return EINA_TRUE; + + free_page: + spectre_page_free(page); + free_psdoc: + spectre_document_free(psdoc); + shutdown_eina: + eina_shutdown(); + + return EINA_FALSE; +} + +static void +_spectre_shutdown() +{ + spectre_page_free(page); + spectre_document_free(psdoc); + eina_shutdown(); +} + +static void +_pixcopy(DATA32 *dst, unsigned char *src, int size) +{ + DATA32 *d; + unsigned char *s, *e; + + d = dst; + s = src; + e = s + size; + while (s < e) + { + d[0] = + 0xff000000 | + (s[2] << 16) | + (s[1] << 8 ) | + (s[0] ); + d++; + s += 4; + } +} + +static void +_spectre_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED) +{ + SpectreRenderContext *rc; + unsigned char *psdata; + int stride; + unsigned char *src; + DATA32 *dst; + int yy; + SpectreStatus status; + + rc = spectre_render_context_new(); + if (!rc) + return; + + spectre_page_render(page, rc, &psdata, &stride); + spectre_render_context_set_page_size (rc, width, height); + status = spectre_page_status(page); + if (status != SPECTRE_STATUS_SUCCESS) + { + D("[eps] %s\n", spectre_status_to_string (status)); + return; + } + + shm_alloc(width * height * sizeof(DATA32)); + if (!shm_addr) return; + data = shm_addr; + + if (stride == 4 * width) + _pixcopy(data, psdata, height * stride); + else + { + src = psdata; + dst = (DATA32 *)data; + for (yy = 0; yy < height; src += stride, dst += width, ++yy) + _pixcopy (dst, src, width * 4); + } + + spectre_render_context_free(rc); +} + +int +main(int argc, char **argv) +{ + char *file; + int i; + int size_w = 0, size_h = 0; + int head_only = 0; + int page_nbr = 0; + + if (argc < 2) return -1; + // file is ALWAYS first arg, other options come after + file = argv[1]; + for (i = 2; i < argc; i++) + { + if (!strcmp(argv[i], "-head")) + // asked to only load header, not body/data + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { + i++; + page_nbr = atoi(argv[i]); + i++; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { // not used by ps loader + i++; + // int scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { + i++; + dpi = ((double)atoi(argv[i])) / 1000.0; // dpi is an int multiplied by 1000 (so 72dpi is 72000) + i++; + } + else if (!strcmp(argv[i], "-opt-size")) + { // not used by ps loader + i++; + size_w = atoi(argv[i]); + i++; + size_h = atoi(argv[i]); + } + } + + D("_spectre_init_file\n"); + D("dpi....: %f\n", dpi); + D("page...: %d\n", page_nbr); + + timeout_init(10); + + if (!_spectre_init(file, page_nbr, size_w, size_h)) + return -1; + D("_spectre_init done\n"); + + D("dpi2...: %f\n", dpi); + if (!head_only) + { + _spectre_load_image(size_w, size_h); + } + + D("size...: %ix%i\n", width, height); + D("alpha..: 0\n"); + + printf("size %i %i\n", width, height); + printf("alpha 0\n"); + + if (!head_only) + { + if (shm_fd >= 0) printf("shmfile %s\n", shmfile); + else + { + // could also to "tmpfile %s\n" like shmfile but just + // a mmaped tmp file on the system + printf("data\n"); + fwrite(data, width * height * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + else + printf("done\n"); + + _spectre_shutdown(); + fflush(stdout); + return 0; +} diff --git a/legacy/evas_generic_loaders/src/bin/raw/Makefile.am b/legacy/evas_generic_loaders/src/bin/raw/Makefile.am new file mode 100644 index 0000000000..90d90055b8 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/raw/Makefile.am @@ -0,0 +1,44 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src \ +-I$(top_srcdir)/src/bin \ +-I$(top_srcdir)/src/bin/common \ +-I$(top_srcdir)/src/bin/raw \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EINA_CFLAGS@ + +bin_PROGRAMS = evas_image_loader.raw +bindir = $(libdir)/evas/utils + +evas_image_loader_raw_SOURCES = \ +main.c \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c +evas_image_loader_raw_CFLAGS = @LIBRAW_CFLAGS@ +evas_image_loader_raw_LDADD = @SHM_OPEN_LIBS@ @LIBRAW_LIBS@ -lm +evas_image_loader_raw_LDFLAGS = + +install-exec-hook: + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.arw + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.cr2 + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.crw + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.dcr + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.dng + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.k25 + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.kdc + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.erf + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mrw + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nef + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nrf + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nrw + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.orf + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rw2 + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.pef + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.raf + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.sr2 + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.srf + ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.x3f diff --git a/legacy/evas_generic_loaders/src/bin/raw/main.c b/legacy/evas_generic_loaders/src/bin/raw/main.c new file mode 100644 index 0000000000..ac9f810048 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/raw/main.c @@ -0,0 +1,242 @@ +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "shmfile.h" +#include "timeout.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include + + +#define DATA32 unsigned int +#define DATA8 unsigned char + +#define ARGB_JOIN(a,r,g,b) \ + (((a) << 24) + ((r) << 16) + ((g) << 8) + (b)) + +//#define RAW_DBG 1 + +#ifdef RAW_DBG +#define D(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define D(fmt, args...) +#endif + +static int fd = -1; +static size_t seg_size = 0; +static unsigned char *seg = MAP_FAILED; +static libraw_data_t *raw_data = NULL; +static void *data = NULL; +static int width = 0; +static int height = 0; + +static int +_raw_init(const char *file) +{ + struct stat ss; + fd = open(file, O_RDONLY); + if (fd < 0) return EINA_FALSE; + + if (stat(file, &ss)) goto close_file; + seg_size = ss.st_size; + seg = mmap(NULL, seg_size, PROT_READ, MAP_SHARED, fd, 0); + if (seg == MAP_FAILED) goto close_file; + + D("raw_init\n"); + raw_data = libraw_init(0); + raw_data->params.half_size = 0; + raw_data->params.user_qual = 2; + + D("raw_open_buffer\n"); + if (libraw_open_buffer(raw_data, seg, seg_size) != LIBRAW_SUCCESS) + return EINA_FALSE; + return EINA_TRUE; + +close_file: + close(fd); + return EINA_FALSE; +} + +static void +_raw_shutdown() +{ + D("raw_shutdown\n"); + if (raw_data) + libraw_close(raw_data); + if (seg != MAP_FAILED) munmap(seg, seg_size); + close(fd); +} + +static int +read_raw_header() +{ + int ret; + + D("raw_open_buffer\n"); + if ((ret = libraw_open_buffer(raw_data, seg, seg_size)) != LIBRAW_SUCCESS) + return 0; + + D("raw_adjust_size\n"); + if ((ret = libraw_adjust_sizes_info_only(raw_data)) != LIBRAW_SUCCESS) + { + if (LIBRAW_FATAL_ERROR(ret)) + return 0; + } + + if ((raw_data->sizes.width < 1) || (raw_data->sizes.height < 1)) + return 0; + + width = raw_data->sizes.iwidth; + height = raw_data->sizes.iheight; + + return 1; + +} + + +static int +read_raw_data() +{ + int ret; + unsigned int count; + libraw_processed_image_t *image = NULL; + DATA8 *bufptr; + DATA32 *dataptr; + + + D("raw_open_unpack\n"); + if ((ret = libraw_unpack(raw_data)) != LIBRAW_SUCCESS) + return 0; + + D("raw_dcraw_process\n"); + if ((ret = libraw_dcraw_process(raw_data)) != LIBRAW_SUCCESS) + { + if (LIBRAW_FATAL_ERROR(ret)) + return 0;; + } + + D("raw_make_mem_image\n"); + image = libraw_dcraw_make_mem_image(raw_data, &ret); + if (image) + { + if ((image->width < 1) || (image->height < 1)) + goto clean_image; + width = image->width; + height = image->height; + if (image->type != LIBRAW_IMAGE_BITMAP) + goto clean_image; + if (image->colors != 3) + goto clean_image; +#define SWAP(a, b) { a ^= b; a = (b ^=a); } + if ((image->bits == 16) && (htons(0x55aa) != 0x55aa)) + for (count = 0; count < image->data_size; count +=2) + SWAP(image->data[count], image->data[count + 1]); +#undef SWAP + shm_alloc((unsigned int)(image->width * image->height) * (sizeof(DATA32))); + if (!shm_addr) + goto clean_image; + data = shm_addr; + memset(shm_addr, 0, (unsigned int)(image->width * image->height) * (sizeof(DATA32))); + dataptr = data; + bufptr = image->data; + for (count = (unsigned int)(image->width * image->height); count > 0; --count) + { + *dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[1], bufptr[2]); + dataptr++; + bufptr += 3; + } + + free(image); + } + return 1; + +clean_image: + free(image); + return 0; +} + + +int main(int argc, char **argv) +{ + char *file; + int i; + int head_only = 0; + + if (argc < 2) return -1; + file = argv[1]; + + for (i = 2; i < argc; ++i) + { + if (!strcmp(argv[i], "-head")) + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { // not used by raw loader + i++; + // const char *key = argv[i]; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { // not used by raw loader + i++; + // int scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { // not used by raw loader + i++; + // double dpi = ((double)atoi(argv[i])) / 1000.0; + } + else if (!strcmp(argv[i], "-opt-size")) + { // not used by raw loader + i++; + // int size_w = atoi(argv[i]); + i++; + // int size_h = atoi(argv[i]); + } + } + + timeout_init(4); + + if (!_raw_init(file)) return -1; + if (head_only != 0) + { + if (read_raw_header()) + { + printf("size %d %d\n", width, height); + printf("alpha 1\n"); + } + printf("done\n"); + } + else + { + if (read_raw_data()) + { + printf("size %d %d\n", width, height); + printf("alpha 1\n"); + if (shm_fd >= 0) printf("shmfile %s\n", shmfile); + else + { + printf("data\n"); + fwrite(data, (unsigned int)(width * height) * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + } + _raw_shutdown(); + fflush(stdout); + return 0; + +} + diff --git a/legacy/evas_generic_loaders/src/bin/svg/Makefile.am b/legacy/evas_generic_loaders/src/bin/svg/Makefile.am new file mode 100644 index 0000000000..e5d85a7de4 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/svg/Makefile.am @@ -0,0 +1,28 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src \ +-I$(top_srcdir)/src/bin \ +-I$(top_srcdir)/src/bin/common \ +-I$(top_srcdir)/src/bin/svg \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EINA_CFLAGS@ + +bin_PROGRAMS = evas_image_loader.svg +bindir = $(libdir)/evas/utils + +evas_image_loader_svg_SOURCES = \ +main.c \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c +evas_image_loader_svg_CFLAGS = @SVG_CFLAGS@ +evas_image_loader_svg_LDADD = @SVG_LIBS@ @SHM_OPEN_LIBS@ -lm +evas_image_loader_svg_LDFLAGS = + + +install-exec-hook: + ln -sf evas_image_loader.svg $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.svgz + ln -sf evas_image_loader.svg $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.svg.gz diff --git a/legacy/evas_generic_loaders/src/bin/svg/main.c b/legacy/evas_generic_loaders/src/bin/svg/main.c new file mode 100644 index 0000000000..5fc7912e87 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/svg/main.c @@ -0,0 +1,230 @@ +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include "shmfile.h" +#include "timeout.h" + +#include + +#include +#ifndef LIBRSVG_CHECK_VERSION +# include +#endif +#if LIBRSVG_CHECK_VERSION(2,36,2) +#else +# include +#endif + +#define DATA32 unsigned int + +static RsvgHandle *rsvg = NULL; +static int width = 0; +static int height = 0; +static RsvgDimensionData dim; + +static inline Eina_Bool evas_image_load_file_is_svg(const char *file) +{ + int i, len = strlen(file); + Eina_Bool is_gz = EINA_FALSE; + + for (i = len - 1; i > 0; i--) + { + if (file[i] == '.') + { + if (is_gz) + break; + else if (strcasecmp(file + i + 1, "gz") == 0) + is_gz = EINA_TRUE; + else + break; + } + } + + if (i < 1) return EINA_FALSE; + i++; + if (i >= len) return EINA_FALSE; + if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE; + i += 3; + if (is_gz) + { + if (file[i] == '.') return EINA_TRUE; + else return EINA_FALSE; + } + else + { + if (file[i] == '\0') return EINA_TRUE; + else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE; + else return EINA_FALSE; + } +} + +static int +_svg_init(const char *file) +{ +#ifdef HAVE_SVG_2_36 +# if !defined(GLIB_VERSION_2_36) + g_type_init(); +# endif +#else + rsvg_init(); +#endif + + if (!evas_image_load_file_is_svg(file)) return 0; + + rsvg = rsvg_handle_new_from_file(file, NULL); + + return 1; +} + +static void +_svg_shutdown(void) +{ + if (rsvg) + { + rsvg_handle_close(rsvg, NULL); + g_object_unref(rsvg); + } + // Maybe it's not crashing anymore, let's try it. +#ifndef HAVE_SVG_2_36 + rsvg_term(); +#endif +} + +static int +read_svg_header(int scale_down, double dpi, int size_w, int size_h) +{ + rsvg_handle_set_dpi(rsvg, 75.0); + rsvg_handle_get_dimensions(rsvg, &dim); + width = dim.width; + height = dim.height; + + if ((width < 1) || (height < 1)) return 0; + + if (scale_down > 1) + { + width /= scale_down; + height /= scale_down; + } + else if (dpi > 0.0) + { + width = (width * dpi) / 75; + height = (height * dpi) / 75; + } + else if (size_w > 0 && size_h > 0) + { + int w, h; + + w = size_w; + h = (size_w * height) / width; + if (h > size_h) + { + h = size_h; + w = (size_h * width) / height; + } + width = w; + height = h; + } + if (width < 1) width = 1; + if (height < 1) height = 1; + + return 1; +} + +static int +read_svg_data(void) +{ + cairo_surface_t *surface; + cairo_t *cr; + + shm_alloc(width * height * (sizeof(DATA32))); + if (!shm_addr) return 0; + + memset(shm_addr, 0, width * height * sizeof (DATA32)); + surface = cairo_image_surface_create_for_data((unsigned char *)shm_addr, CAIRO_FORMAT_ARGB32, + width, height, width * sizeof(DATA32));; + if (!surface) return 0; + + cr = cairo_create(surface); + if (!cr) return 0; + + cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex); + rsvg_handle_render_cairo(rsvg, cr); + cairo_surface_destroy(surface); + cairo_destroy(cr); + + return 1; +} + +int main(int argc, char **argv) +{ + char *file; + int i; + int head_only = 0; + int scale_down = 0; + double dpi = 0.0; + int size_w = 0, size_h = 0; + + if (argc < 2) return -1; + file = argv[1]; + + for (i = 2; i < argc; ++i) + { + if (!strcmp(argv[i], "-head")) + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { // not used by svg loader + i++; + // const char *key = argv[i]; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { + i++; + scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { + i++; + dpi = ((double)atoi(argv[i])) / 1000.0; + } + else if (!strcmp(argv[i], "-opt-size")) + { + i++; + size_w = atoi(argv[i]); + i++; + size_h = atoi(argv[i]); + } + } + + timeout_init(5); + + if (!_svg_init(file)) return -1; + if (!read_svg_header(scale_down, dpi, size_w, size_h)) return -1; + + if (head_only != 0) + { + printf("size %d %d\n", width, height); + printf("alpha 1\n"); + printf("done\n"); + } + else + { + if (read_svg_data()) + { + printf("size %d %d\n", width, height); + printf("alpha 1\n"); + if (shm_fd >= 0) printf("shmfile %s\n", shmfile); + else + { + printf("data\n"); + fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + } + _svg_shutdown(); + fflush(stdout); + return 0; + +} + diff --git a/legacy/evas_generic_loaders/src/bin/xcf/Makefile.am b/legacy/evas_generic_loaders/src/bin/xcf/Makefile.am new file mode 100644 index 0000000000..041e8b31d2 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/xcf/Makefile.am @@ -0,0 +1,26 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src \ +-I$(top_srcdir)/src/bin \ +-I$(top_srcdir)/src/bin/common \ +-I$(top_srcdir)/src/bin/xcf \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EINA_CFLAGS@ + +bin_PROGRAMS = evas_image_loader.xcf +bindir = $(libdir)/evas/utils + +evas_image_loader_xcf_SOURCES = \ +main.c pixelfuncs.c common.h \ +$(top_srcdir)/src/bin/common/shmfile.c \ +$(top_srcdir)/src/bin/common/timeout.c +evas_image_loader_xcf_CFLAGS = @EINA_CFLAGS@ +evas_image_loader_xcf_LDADD = @EINA_LIBS@ -lz -lm @SHM_OPEN_LIBS@ +evas_image_loader_xcf_LDFLAGS = + +install-exec-hook: + ln -sf evas_image_loader.xcf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xcf.gz diff --git a/legacy/evas_generic_loaders/src/bin/xcf/common.h b/legacy/evas_generic_loaders/src/bin/xcf/common.h new file mode 100644 index 0000000000..5abaab8677 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/xcf/common.h @@ -0,0 +1,51 @@ +#ifndef __COMMON +#define __COMMON 1 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DATABIG unsigned long long +#define DATA64 unsigned long long +#define DATA32 unsigned int +#define DATA16 unsigned short +#define DATA8 unsigned char + +#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 + +//#define XCF_DBG 1 + +#ifdef XCF_DBG +#define D(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define D(fmt, args...) +#endif + +#endif diff --git a/legacy/evas_generic_loaders/src/bin/xcf/main.c b/legacy/evas_generic_loaders/src/bin/xcf/main.c new file mode 100644 index 0000000000..373823bf32 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/xcf/main.c @@ -0,0 +1,1731 @@ +/* + + -----------------------------[ XCF Loader ]----------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ------------------------------------------------------------------------ + + There's a quick overview of the XCF file structure in Gimp's source + tree, in docs/xcf.doc. However it's brief, so here's a more verbose + overview based on my understanding of XCF. All image characteristics + are defined in "properties". In the data stream properties are defined + through a 4 bit index number (see enum below), followed by a 4 byte + length. The property data directly follows this information. A list of + properties ends when PROP_END is encountered. There is a properties + block at the beginning of the file, as well as at the beginning of each + layer and channel. Layers and channels are read at offsets in the file, + the list of layers (resp. channels) is exhausted when the next offset + read in is zero. + + The actual image data is stored in tiles, which are by default 64x64 in + size, likely with smaller ones on the right and bottom edges. + + The position of the tiles on the image is left->right, row by row. The + actual DATA8* data is contained in a "level" which is contained in a + "hierarchy". I've not really understood the purpose of the hierarchy, as + it seems to always contain only one level anyway. + + Layer masks are stored as channels (basically grayscale layers with a + single color definition. For the purpose of this loader I replaced the + concept of a channel with a layer, since it doesn't really matter. + + Ok, hope this helps with understanding XCF. -- cK. + +*/ +#include "common.h" +#include "shmfile.h" +#include "timeout.h" + +#define FREE(X) { free(X); X = NULL; } + +#define TILE_WIDTH 64 +#define TILE_HEIGHT 64 + +/* --------------------------------------------------------------------------- typedefs ------------ */ + +typedef struct _Layer Layer; +typedef struct _Tile Tile; + +/* ------------------------------------------------------------------------------ enums ------------ */ + + +/* These are all the properties that a layer or channel can have. + Only some of them are actually used. */ +typedef enum +{ + PROP_END = 0, + PROP_COLORMAP = 1, + PROP_ACTIVE_LAYER = 2, + PROP_ACTIVE_CHANNEL = 3, + PROP_SELECTION = 4, + PROP_FLOATING_SELECTION = 5, + PROP_OPACITY = 6, + PROP_MODE = 7, + PROP_VISIBLE = 8, + PROP_LINKED = 9, + PROP_PRESERVE_TRANSPARENCY = 10, + PROP_APPLY_MASK = 11, + PROP_EDIT_MASK = 12, + PROP_SHOW_MASK = 13, + PROP_SHOW_MASKED = 14, + PROP_OFFSETS = 15, + PROP_COLOR = 16, + PROP_COMPRESSION = 17, + PROP_GUIDES = 18, + PROP_RESOLUTION = 19, + PROP_TATTOO = 20, + PROP_PARASITES = 21, + PROP_UNIT = 22, + PROP_PATHS = 23, + PROP_USER_UNIT = 24 +} +PropType; + +/* The tiles can be stored in an encrypted fashion, defined as follows: */ +typedef enum +{ + COMPRESS_NONE = 0, + COMPRESS_RLE = 1, + COMPRESS_ZLIB = 2, + COMPRESS_FRACTAL = 3 /* Unused. */ +} CompressionType; + +/* Layer modes (*SIGH*) */ +typedef enum +{ + NORMAL_MODE, + DISSOLVE_MODE, + BEHIND_MODE, + MULTIPLY_MODE, + SCREEN_MODE, + OVERLAY_MODE, + DIFFERENCE_MODE, + ADDITION_MODE, + SUBTRACT_MODE, + DARKEN_ONLY_MODE, + LIGHTEN_ONLY_MODE, + HUE_MODE, + SATURATION_MODE, + COLOR_MODE, + VALUE_MODE, + DIVIDE_MODE, + ERASE_MODE, /*< skip >*/ + REPLACE_MODE, /*< skip >*/ + ANTI_ERASE_MODE /*< skip >*/ +} +LayerModeEffects; + +/* Base image types */ +typedef enum +{ + RGB, + GRAY, + INDEXED +} GimpImageBaseType; + +/* Image types */ +typedef enum +{ + RGB_GIMAGE, + RGBA_GIMAGE, + GRAY_GIMAGE, + GRAYA_GIMAGE, + INDEXED_GIMAGE, + INDEXEDA_GIMAGE +} GimpImageType; + +/* ---------------------------------------------------------------------------- structs ------------ */ + +/* Ok, this is what's left of Gimp's layer abstraction. I kicked out + all the stuff that's unnecessary and added the necessary stuff + from the Gimp drawable superclass. This one also serves as a + Channel, e.g. for use as a layer mask. + --cK. +*/ +struct _Layer +{ + int visible; /* controls visibility */ + int width, height; /* size of drawable */ + int bpp; /* depth */ + int offset_x, offset_y; /* offset of layer in image */ + + int ID; /* provides a unique ID */ + GimpImageType type; /* type of drawable */ + char has_alpha; /* drawable has alpha */ + + int preserve_trans; /* preserve transparency */ + + Layer *mask; /* possible layer mask */ + + int opacity; /* layer opacity */ + LayerModeEffects mode; /* layer combination mode */ + + + /* XCF stores the actual image data as tiles. A Layer is covered with + tiles, the tiles on the right and bottom will (usually) be a bit + smaller. num_rows and num_cols gives the number of tile rows and + columns. + */ + + Tile* tiles; /* tiles for drawable data */ + int num_rows; + int num_cols; + + /* After the tiles are read in, they're serialized int an array + of DATA8's, that will always contain 4 bpp data. Not optimal, + I know, but makes life easier + */ + + DATA8* data; + + /* Layers are stored as a linked list. */ + struct _Layer* next; + struct _Layer* prev; +}; + + +/* The tile structure: +*/ +struct _Tile +{ + unsigned char bpp; /* the bytes per pixel (1, 2, 3 or 4) */ + unsigned short ewidth; /* the effective width of the tile */ + unsigned short eheight; /* the effective height of the tile */ + + /* a tile's effective width and height may be smaller + * (but not larger) than TILE_WIDTH and TILE_HEIGHT. + * This is to handle edge tiles of a drawable. + */ + + DATA8 *data; +}; + + +/* This struct simply contains everything that didn't fit elsewhere, + based on GimpImage :) +*/ +struct _GimpImage +{ + void *file; + char *filename; + long cp; + int compression; /* file compression mode */ + int file_version; + + int width, height; /* width and height attributes */ + GimpImageBaseType base_type; /* base gimp_image type */ + + DATA32 floating_sel_offset; + + DATA8* cmap; /* colormap--for indexed */ + int num_cols; /* number of colors in map */ + + /* If a layer number was passed to the loader, it goes here: */ + int single_layer_index; + + /* Tadaa -- the final image data. Layers get pasted + onto this one, bottom-up. + */ + DATA8* data; + + Layer* layers; + Layer* last_layer; + Layer* floating_sel; +} +_image; + +/* ------------------------------------------------------------------------- prototypes ------------ */ + +typedef struct _File File; +typedef struct _Chunk Chunk; + +#define FBUF 1 +#define CHUNK_SIZE (32 * 1024) + +struct _Chunk +{ + int size; + unsigned char data[CHUNK_SIZE]; +}; + +struct _File +{ + int fd; + gzFile fp; + long pos, size; + int chunk_num; + Chunk **chunk; +}; + +static File * +f_open(const char *file) +{ + File *f; + + f = calloc(1, sizeof(File)); + if (!f) return NULL; + f->fd = open(file, O_RDONLY); + if (f->fd < 0) + { + D("open of %s failed\n", file); + free(f); + return NULL; + } + f->fp = gzdopen(f->fd, "r"); + if (!f->fp) + { + D("gzdopen of %i failed\n", f->fd); + close(f->fd); + free(f); + return NULL; + } + return f; +} + +static void +f_close(File *f) +{ + // FIXME: free chunks + gzclose(f->fp); + free(f); +} + +#ifdef FBUF +static void +_f_read_pos(File *f, long pos, long bytes) +{ + long i, cnum; + Chunk **cks; + + if (f->size > 0) return; + cnum = ((pos + bytes) / CHUNK_SIZE) + 1; + if (f->chunk_num >= cnum) return; + D("FFFF: go up to %li + %li, chunks %li\n", pos, bytes, cnum); + cks = realloc(f->chunk, sizeof(Chunk *) * cnum); + if (!cks) return; + f->chunk = cks; + for (i = f->chunk_num; i < cnum; i++) + { + if (f->size != 0) + { + f->chunk[i] = NULL; + continue; + } + f->chunk[i] = malloc(sizeof(Chunk)); + if (f->chunk[i]) + { + f->chunk[i]->size = gzread(f->fp, f->chunk[i]->data, CHUNK_SIZE); + D("FFFF: go %i\n", f->chunk[i]->size); + if (f->chunk[i]->size < CHUNK_SIZE) + { + f->size = (i * CHUNK_SIZE) + f->chunk[i]->size; + } + } + } + f->chunk_num = cnum; +} +#endif + +static long +f_read(File *f, unsigned char *dest, long bytes) +{ +#ifdef FBUF + long done = 0, off = 0; + int c; + unsigned char *p; + _f_read_pos(f, f->pos, bytes); + + c = f->pos / CHUNK_SIZE; + off = f->pos - (c * CHUNK_SIZE); + p = dest; + while ((done < bytes) && (c < f->chunk_num)) + { + long amount = bytes - done; + + if (!f->chunk[c]) break; + if (amount > (f->chunk[c]->size - off)) + amount = (f->chunk[c]->size - off); + if (amount < 1) return 0; + memcpy(p, f->chunk[c]->data + off, amount); + p += amount; + off = 0; + done += amount; + c++; + } + f->pos += done; + return done; +#else + long done = gzread(f->fp, dest, bytes); + f->pos += done; + return done; +#endif +} + +static void +f_seek(File *f, long pos) +{ +#ifdef FBUF + if (f->size > 0) + { + if (pos >= f->size) pos = f->size -1; + } +#endif + if (f->pos == pos) return; + f->pos = pos; +#ifdef FBUF + _f_read_pos(f, f->pos, 1); +#else + gzseek(f->fp, f->pos, SEEK_SET); +#endif +} + + +/* stuff that was adapted from xcf.c */ + +static void xcf_seek_pos(int pos); +static int xcf_read_int32(void *fp, DATA32 *data, int count); +static int xcf_read_int8(void *fp, DATA8 *data, int count); +static int xcf_read_string(void *fp, char **data, int count); +static char xcf_load_prop(PropType *prop_type, DATA32 *prop_size); +static void xcf_load_image(void); +static char xcf_load_image_props(void); + +static Layer* xcf_load_channel(void); +static char xcf_load_channel_props(Layer *layer); +static Layer* xcf_load_layer(void); +static char xcf_load_layer_props(Layer *layer); +static char xcf_load_hierarchy(Tile** tiles, int *num_rows, int *num_cols, int *bpp); +static char xcf_load_level(Tile** tiles, int hierarchy_width, int hierarchy_height, int bpp, int* num_rows, int *num_cols); +static char xcf_load_tile(Tile *tile); +static char xcf_load_tile_rle(Tile *tile, int data_length); + +/* new stuff :) */ + +static Tile* allocate_tiles(int width, int height, int bpp, int* num_rows, int* num_cols); +static void free_tiles(Tile* tiles, int num_tiles); +static void init_tile(Tile* tile, int width, int height, int bpp); +static Layer* new_layer(int width, int height, GimpImageType type, int opacity, LayerModeEffects mode); +static void free_layer(Layer* layer); +static void add_layer_to_image(Layer* layer); +static void read_tiles_into_data(Tile* tiles, int num_cols, int width, int height, int bpp, DATA8** data, int use_cmap); +static void apply_layer_mask(Layer* layer); +static void set_layer_opacity(Layer* layer); +static void flatten_image(void); + +static char xcf_file_init(char* filename); +static void xcf_cleanup(void); + +/* Stuff for layer merging: */ +extern void combine_pixels_normal (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_add (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_sub (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_diff (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_darken (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_lighten (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_mult (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_div (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_screen (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_overlay (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_hue (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_sat (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_val (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_col (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); +extern void combine_pixels_diss (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y); + +/* ---------------------------------------------------------------------------- globals ------------ */ + +/* This makes using the Gimp sources easier */ +static struct _GimpImage * image = &_image; + +/* ------------------------------------------------------------------------------- code ------------ */ + +static void +xcf_seek_pos(int pos) +{ + if (image->cp != pos) + { + image->cp = pos; + f_seek(image->file, image->cp); + } +} + +static int +xcf_read_int32(void *fp, + DATA32 *data, + int count) +{ + int total; + + total = count; + if (count > 0) + { + xcf_read_int8(fp, (DATA8*) data, count * 4); + while (count--) + { + *data = (DATA32)ntohl(*data); + data++; + } + } + return total * 4; +} + +static int +xcf_read_int8(void *fp, + DATA8 *data, + int count) +{ + int total; + int bytes; + + total = count; + while (count > 0) + { + bytes = f_read(fp, data, count); + if (bytes <= 0) /* something bad happened */ + break; + count -= bytes; + data += bytes; + } + return total; +} + +static int +xcf_read_string(void *fp, + char **data, + int count) +{ + DATA32 tmp; + int total; + int i; + + total = 0; + for (i = 0; i < count; i++) + { + total += xcf_read_int32(fp, &tmp, 1); + if (tmp > 0) + { + data[i] = malloc(sizeof(DATA8) * tmp); + if (data[i]) total += xcf_read_int8(fp, (DATA8 *)data[i], tmp); + } + else + data[i] = NULL; + } + return total; +} + + +static char +xcf_load_prop(PropType *prop_type, + DATA32 *prop_size) +{ + image->cp += xcf_read_int32(image->file, (DATA32 *)prop_type, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)prop_size, 1); + return 1; +} + + +static char +xcf_load_image_props(void) +{ + PropType prop_type; + DATA32 prop_size; + + while (1) + { + if (!xcf_load_prop (&prop_type, &prop_size)) return 0; + switch (prop_type) + { + case PROP_END: + { + D("Finished reading image properties.\n"); + return 1; + } + case PROP_COLORMAP: + { + if (image->file_version == 0) + { + int i; + fprintf (stderr, + "XCF warning: version 0 of XCF file format\n" + "did not save indexed colormaps correctly.\n" + "Substituting grayscale map.\n"); + image->cp += xcf_read_int32(image->file, (DATA32 *)&image->num_cols, 1); + image->cmap = malloc(sizeof(DATA8) * image->num_cols * 3); + if (!image->cmap) return 0; + xcf_seek_pos (image->cp + image->num_cols); + for (i = 0; i < image->num_cols; i++) + { + image->cmap[(i * 3) + 0] = i; + image->cmap[(i * 3) + 1] = i; + image->cmap[(i * 3) + 2] = i; + } + } + else + { + D("Loading colormap.\n"); + image->cp += xcf_read_int32(image->file, (DATA32 *)&image->num_cols, 1); + image->cmap = malloc(sizeof(DATA8) * image->num_cols * 3); + if (!image->cmap) return 0; + image->cp += xcf_read_int8(image->file, (DATA8 *)image->cmap, image->num_cols * 3); + } + } + break; + case PROP_COMPRESSION: + { + char compression; + + image->cp += xcf_read_int8(image->file, (DATA8 *)&compression, 1); + + if ((compression != COMPRESS_NONE) && + (compression != COMPRESS_RLE) && + (compression != COMPRESS_ZLIB) && + (compression != COMPRESS_FRACTAL)) + { + fprintf (stderr, "unknown xcf compression type: %d\n", (int) compression); + return 0; + } + + D("Image compression type: %i\n", compression); + + image->compression = compression; + } + break; + /* I threw out all of the following: --cK */ + case PROP_TATTOO: + case PROP_PARASITES: + case PROP_UNIT: + case PROP_PATHS: + case PROP_USER_UNIT: + case PROP_GUIDES: + case PROP_RESOLUTION: + default: + { + DATA8 buf[16]; + int amount; + + D("Skipping unexpected/unknown image property: %d\n", prop_type); + + while (prop_size > 0) + { + amount = (16 < prop_size ? 16 : prop_size); + image->cp += xcf_read_int8(image->file, buf, amount); + prop_size -= amount; + } + } + break; + } + } + return 0; +} + + +static void +xcf_load_image(void) +{ + Layer *layer; + DATA32 saved_pos; + DATA32 offset; + int num_successful_elements = 0; + + /* read the image properties */ + if (!xcf_load_image_props()) goto hard_error; + + while (1) + { + /* read in the offset of the next layer */ + image->cp += xcf_read_int32(image->file, &offset, 1); + /* if the offset is 0 then we are at the end + * of the layer list. */ + if (offset == 0) break; + /* save the current position as it is where the + * next layer offset is stored. */ + saved_pos = image->cp; + /* seek to the layer offset */ + xcf_seek_pos(offset); + /* read in the layer */ + layer = xcf_load_layer(); + if (!layer) goto error; + num_successful_elements++; + /* add the layer to the image if it's visible */ + if (layer->visible) add_layer_to_image(layer); + else free_layer(layer); + /* restore the saved position so we'll be ready to + * read the next offset. */ + xcf_seek_pos (saved_pos); + } + /* If we were a Gimp we would now load the user-defined channels here ... */ + /* Flat-o-rama now :) */ + flatten_image(); + return; +error: + if (num_successful_elements == 0) goto hard_error; + fprintf(stderr, "XCF: This file is corrupt! I have loaded as much\nof it as I can, but it is incomplete.\n"); + return; +hard_error: + fprintf(stderr, "XCF: This file is corrupt! I could not even\nsalvage any partial image data from it.\n"); + return; +} + +static char +xcf_load_layer_props(Layer *layer) +{ + PropType prop_type; + DATA32 prop_size; + + while (1) + { + if (!xcf_load_prop(&prop_type, &prop_size)) return 0; + switch (prop_type) + { + case PROP_END: + { + D("Finished reading layer properties.\n"); + return 1; + } + case PROP_FLOATING_SELECTION: + D("Loading floating selection.\n"); + image->floating_sel = layer; + image->cp += xcf_read_int32(image->file, (DATA32 *)&image->floating_sel_offset, 1); + break; + case PROP_OPACITY: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->opacity, 1); + break; + case PROP_VISIBLE: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->visible, 1); + break; + case PROP_PRESERVE_TRANSPARENCY: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->preserve_trans, 1); + break; + case PROP_OFFSETS: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->offset_x, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->offset_y, 1); + break; + case PROP_MODE: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->mode, 1); + break; + + /* I threw out all of the following: --cK */ + case PROP_LINKED: + case PROP_ACTIVE_LAYER: + case PROP_TATTOO: + case PROP_APPLY_MASK: + case PROP_EDIT_MASK: + case PROP_SHOW_MASK: + case PROP_PARASITES: + default: + { + DATA8 buf[16]; + int amount; + + D("Skipping unexpected/unknown/unneeded channel property: %d\n", prop_type); + while (prop_size > 0) + { + amount = (16 < prop_size ? 16 : prop_size); + image->cp += xcf_read_int8 (image->file, buf, amount); + prop_size -= amount; + } + } + break; + } + } + + return 0; +} + + +static Layer * +xcf_load_layer(void) +{ + Layer *layer; + Layer *layer_mask; + DATA32 hierarchy_offset; + DATA32 layer_mask_offset; + int width; + int height; + int type; + char *name; + + D("Loading one layer ...\n"); + /* read in the layer width, height and type */ + image->cp += xcf_read_int32(image->file, (DATA32 *)&width, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&height, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&type, 1); + image->cp += xcf_read_string(image->file, &name, 1); + /* ugly, I know */ + FREE(name); + + /* create a new layer */ + layer = new_layer(width, height, type, 255, NORMAL_MODE); + if (!layer) return NULL; + + /* read in the layer properties */ + if (!xcf_load_layer_props(layer)) goto error; + + D("Loading opacity: %i \n", layer->opacity); + if (!layer->visible) return layer; + + /* read the hierarchy and layer mask offsets */ + image->cp += xcf_read_int32(image->file, &hierarchy_offset, 1); + image->cp += xcf_read_int32(image->file, &layer_mask_offset, 1); + /* read in the hierarchy */ + xcf_seek_pos(hierarchy_offset); + if (!xcf_load_hierarchy(&(layer->tiles), &(layer->num_rows), + &(layer->num_cols), &(layer->bpp))) + goto error; + + /* read in the layer mask */ + if (layer_mask_offset != 0) + { + D("Loading layer mask.\n"); + xcf_seek_pos(layer_mask_offset); + + layer_mask = xcf_load_channel(); + if (!layer_mask) goto error; + + /* set the offsets of the layer_mask */ + layer_mask->offset_x = layer->offset_x; + layer_mask->offset_y = layer->offset_y; + layer->mask = layer_mask; + } + read_tiles_into_data(layer->tiles, layer->num_cols, + layer->width, layer->height, + layer->bpp, &(layer->data), + 1); + free_tiles(layer->tiles, layer->num_rows * layer->num_cols); + layer->tiles = NULL; + set_layer_opacity(layer); + if (layer->mask) apply_layer_mask(layer); + + return layer; + +error: + free_layer(layer); + return NULL; +} + + +static void +read_tiles_into_data(Tile *tiles, int num_cols, int width, + int height, int bpp, DATA8 **data_p, int use_cmap) +{ + int tile_x, tile_y, x, y, offset_x, offset_y; + DATA8 *data; + DATA8 *ptr; + DATA8 *ptr2; + Tile *t; + int warned = 0; + + if (tiles) + { + if (*data_p) FREE(*data_p); + + /* Always allocate the data as 4 bytes per pixel */ + data = (*data_p) = malloc(sizeof(DATA32) * width * height); + if (!data) return; + + ptr = data; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + tile_x = x / TILE_WIDTH; + tile_y = y / TILE_HEIGHT; + offset_x = x % TILE_WIDTH; + offset_y = y % TILE_HEIGHT; + + t = &tiles[(tile_y * num_cols) + tile_x]; + ptr2 = &(t->data[(offset_y * t->ewidth * bpp) + + (offset_x * bpp)]); + switch (bpp) + { + case 1: + { + /* use colormap if the image has one */ + if (image->cmap && use_cmap) + { + R_VAL(ptr) = image->cmap[(*(ptr2) * 3)]; + G_VAL(ptr) = image->cmap[(*(ptr2) * 3) + 1]; + B_VAL(ptr) = image->cmap[(*(ptr2) * 3) + 2]; + A_VAL(ptr) = 255; + } + /* else use colors themselves */ + else + { + R_VAL(ptr) = *(ptr2); + G_VAL(ptr) = *(ptr2); + B_VAL(ptr) = *(ptr2); + A_VAL(ptr) = 255; + } + break; + } + case 2: + { + /* use colormap if the image has one */ + if (image->cmap && use_cmap) + { + R_VAL(ptr) = image->cmap[(*(ptr2) * 3)]; + G_VAL(ptr) = image->cmap[(*(ptr2) * 3) + 1]; + B_VAL(ptr) = image->cmap[(*(ptr2) * 3) + 2]; + A_VAL(ptr) = *(ptr2 + 1); + } + /* else use colors themselves */ + else if (warned == 0) + { + warned++; + fprintf (stderr, "There's nothing to see here. 2 bpp without colormap not implemented yet.\n"); + } + break; + } + case 3: + { + if (image->cmap) + { + if (warned == 0) + { + warned++; + fprintf (stderr, "There's nothing to see here. 3 bpp with colormap not implemented yet.\n"); + } + } + else + { + R_VAL(ptr) = *(ptr2); + G_VAL(ptr) = *(ptr2 + 1); + B_VAL(ptr) = *(ptr2 + 2); + A_VAL(ptr) = 255; + } + break; + } + default: + { + R_VAL(ptr) = *(ptr2); + G_VAL(ptr) = *(ptr2 + 1); + B_VAL(ptr) = *(ptr2 + 2); + A_VAL(ptr) = *(ptr2 + 3); + break; + } + } + ptr += 4; + } + } + } +} + +static Layer * +xcf_load_channel(void) +{ + Layer *layer; + DATA32 hierarchy_offset; + int width; + int height; + char *name; + + D("Loading channel ...\n"); + /* read in the layer width, height and name */ + image->cp += xcf_read_int32(image->file, (DATA32 *)&width, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&height, 1); + image->cp += xcf_read_string(image->file, &name, 1); + + /* Yeah, still ugly :) */ + FREE(name); + + /* create a new channel */ + layer = new_layer(width, height, GRAY_GIMAGE, 255, NORMAL_MODE); + if (!layer) return NULL; + /* read in the channel properties */ + if (!xcf_load_channel_props(layer)) goto error; + /* read the hierarchy and layer mask offsets */ + image->cp += xcf_read_int32(image->file, &hierarchy_offset, 1); + /* read in the hierarchy */ + xcf_seek_pos(hierarchy_offset); + if (!xcf_load_hierarchy(&(layer->tiles), &(layer->num_rows), &(layer->num_cols), &(layer->bpp))) + goto error; + read_tiles_into_data(layer->tiles, layer->num_cols, layer->width, + layer->height, layer->bpp, &(layer->data), 0); + free_tiles(layer->tiles, layer->num_rows * layer->num_cols); + layer->tiles = NULL; + + D("Channel loaded successfully.\n"); + return layer; + +error: + free_layer(layer); + return NULL; +} + +static char +xcf_load_channel_props(Layer *layer) +{ + PropType prop_type; + DATA32 prop_size; + + while (1) + { + if (!xcf_load_prop(&prop_type, &prop_size)) return 0; + + switch (prop_type) + { + case PROP_END: + { + D("Finished loading channel props.\n"); + return 1; + } + case PROP_OPACITY: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->opacity, 1); + break; + case PROP_VISIBLE: + image->cp += xcf_read_int32(image->file, (DATA32 *)&layer->visible, 1); + break; + case PROP_ACTIVE_CHANNEL: + case PROP_SHOW_MASKED: + case PROP_SELECTION: + case PROP_COLOR: + case PROP_TATTOO: + case PROP_PARASITES: + default: + { + DATA8 buf[16]; + int amount; + + D("Skipping unexpected/unknown/unneeded channel property: %d\n", prop_type); + + while (prop_size > 0) + { + amount = (16 < prop_size ? 16 : prop_size); + image->cp += xcf_read_int8(image->file, buf, amount); + prop_size -= amount; + } + } + break; + } + } + return 0; +} + +static char +xcf_load_hierarchy(Tile **tiles, int *num_rows, int *num_cols, int *bpp) +{ + DATA32 saved_pos; + DATA32 offset; + DATA32 junk; + int width; + int height; + + image->cp += xcf_read_int32(image->file, (DATA32 *)&width, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&height, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)bpp, 1); + image->cp += xcf_read_int32(image->file, &offset, 1); /* top level */ + + D("Loading hierarchy: width %i, height %i, bpp %i\n", width, height, *bpp); + + /* discard offsets for layers below first, if any. */ + do + { + image->cp += xcf_read_int32(image->file, &junk, 1); + } + while (junk != 0); + /* save the current position as it is where the + * next level offset is stored. */ + saved_pos = image->cp; + /* seek to the level offset */ + xcf_seek_pos(offset); + /* read in the level */ + if (!xcf_load_level(tiles, width, height, *bpp, num_rows, num_cols)) + return 0; + /* restore the saved position so we'll be ready to + * read the next offset. */ + xcf_seek_pos (saved_pos); + D("Loaded hierarchy successfully.\n"); + return 1; +} + +static char +xcf_load_level(Tile **tiles_p, int hierarchy_width, int hierarchy_height, + int bpp, int *num_rows, int *num_cols) +{ + DATA32 saved_pos; + DATA32 offset, offset2; + int ntiles; + int width; + int height; + int i; + int fail; + Tile *tiles; + Tile *current_tile; + + image->cp += xcf_read_int32(image->file, (DATA32*) &width, 1); + image->cp += xcf_read_int32(image->file, (DATA32*) &height, 1); + + if ((width != hierarchy_width) || (height != hierarchy_height)) return 0; + + D("Loading level of size %ix%i.\n", width, height); + (*tiles_p) = allocate_tiles(width, height, bpp, num_rows, num_cols); + tiles = (*tiles_p); + + image->cp += xcf_read_int32(image->file, &offset, 1); + if (offset == 0) return 1; + + ntiles = (*num_rows) * (*num_cols); + for (i = 0; i < ntiles; i++) + { + current_tile = &(tiles[i]); + fail = 0; + + if (offset == 0) + { + D("Not enough tiles found in level\n"); + return 0; + } + + /* save the current position as it is where the + * next tile offset is stored. + */ + saved_pos = image->cp; + + /* read in the offset of the next tile so we can calculate the amount + of data needed for this tile*/ + image->cp += xcf_read_int32(image->file, &offset2, 1); + + /* if the offset is 0 then we need to read in the maximum possible + allowing for negative compression */ + if (offset2 == 0) + offset2 = offset + (TILE_WIDTH * TILE_WIDTH * 4 * 1.5); + /* 1.5 is probably more than we need to allow */ + + /* seek to the tile offset */ + xcf_seek_pos(offset); + + /* read in the current_tile */ + switch (image->compression) + { + case COMPRESS_NONE: + if (!xcf_load_tile(current_tile)) fail = 1; + break; + case COMPRESS_RLE: + if (!xcf_load_tile_rle(current_tile, offset2 - offset)) fail = 1; + break; + case COMPRESS_ZLIB: + fprintf (stderr, "xcf: zlib compression unimplemented\n"); + fail = 1; + break; + case COMPRESS_FRACTAL: + fprintf (stderr, "xcf: fractal compression unimplemented\n"); + fail = 1; + break; + } + + if (fail) + { + D("Couldn't load tiles.\n"); + free_tiles(tiles, (*num_rows) * (*num_cols)); + return 0; + } + /* restore the saved position so we'll be ready to + * read the next offset. + */ + xcf_seek_pos(saved_pos); + /* read in the offset of the next tile */ + image->cp += xcf_read_int32(image->file, &offset, 1); + } + + if (offset != 0) + { + D("encountered garbage after reading level: %d\n", offset); + return 0; + } + + D("Loaded level successfully.\n"); + return 1; +} + +static char +xcf_load_tile(Tile *tile) +{ + image->cp += xcf_read_int8(image->file, tile->data, + tile->ewidth * tile->eheight * tile->bpp); + return 1; +} + +static char +xcf_load_tile_rle(Tile *tile, + int data_length) +{ + DATA8 *data; + DATA8 val; + int size; + int count; + int length; + int bpp; + int i, j; + int nmemb_read_successfully; + DATA8 *xcfdata, *xcfodata, *xcfdatalimit; + + data = tile->data; + bpp = tile->bpp; + + /*printf ("Reading encrypted tile %ix%ix%i, data_length %i\n", tile->ewidth, tile->eheight, tile->bpp, data_length);*/ + + xcfdata = xcfodata = malloc(sizeof(DATA8) * data_length); + if (!xcfdata) return 0; + + /* we have to use fread instead of xcf_read_* because we may be + reading past the end of the file here */ + nmemb_read_successfully = f_read(image->file, xcfdata, data_length); + image->cp += nmemb_read_successfully; + + xcfdatalimit = &xcfodata[nmemb_read_successfully - 1]; + + for (i = 0; i < bpp; i++) + { + data = (tile->data) + i; + size = tile->ewidth * tile->eheight; + count = 0; + + while (size > 0) + { + if (xcfdata > xcfdatalimit) goto bogus_rle; + + val = *xcfdata++; + + length = val; + if (length >= 128) + { + length = 255 - (length - 1); + if (length == 128) + { + if (xcfdata >= xcfdatalimit) goto bogus_rle; + + length = (*xcfdata << 8) + xcfdata[1]; + xcfdata += 2; + } + + count += length; + size -= length; + + if (size < 0) goto bogus_rle; + if (&xcfdata[length-1] > xcfdatalimit) goto bogus_rle; + + while (length-- > 0) + { + *data = *xcfdata++; + data += bpp; + } + } + else + { + length += 1; + if (length == 128) + { + if (xcfdata >= xcfdatalimit) goto bogus_rle; + + length = (*xcfdata << 8) + xcfdata[1]; + xcfdata += 2; + } + + count += length; + size -= length; + + if (size < 0) goto bogus_rle; + if (xcfdata > xcfdatalimit) goto bogus_rle; + + val = *xcfdata++; + + for (j = 0; j < length; j++) + { + *data = val; + data += bpp; + } + } + } + } + FREE(xcfodata); + return 1; + +bogus_rle: + fprintf(stderr, "WHOOOOOP -- bogus rle? Highly unlikely, blame cK for this one :) \n"); + if (xcfodata) FREE(xcfodata); + return 0; +} + +static Layer * +new_layer(int width, int height, GimpImageType type, int opacity, LayerModeEffects mode) +{ + Layer *layer; + + layer = calloc(1, sizeof(Layer)); + if (!layer) + { + D("Couldn't allocate layer.\n"); + return NULL; + } + + layer->width = width; + layer->height = height; + layer->type = type; + layer->opacity = opacity; + layer->mode = mode; + layer->tiles = NULL; + layer->next = NULL; + layer->mask = NULL; + return layer; +} + +static void +free_layer(Layer *layer) +{ + if (layer) + { + if (layer->tiles) + free_tiles(layer->tiles, layer->num_rows * layer->num_cols); + if (layer->mask) free_layer(layer->mask); + if (layer->data) FREE(layer->data); + FREE(layer); + } +} + +static Tile * +allocate_tiles(int width, int height, int bpp, int* num_rows, int* num_cols) +{ + Tile* tiles; + int i, j, k, right_tile, bottom_tile; + int tile_width, tile_height; + + (*num_rows) = (height + TILE_HEIGHT - 1) / TILE_HEIGHT; + (*num_cols) = (width + TILE_WIDTH - 1) / TILE_WIDTH; + + tiles = malloc(sizeof(Tile) * (*num_rows) * (*num_cols)); + if (!tiles) + { + D("Couldn't allocate tiles.\n"); + return NULL; + } + + right_tile = width - (((*num_cols) - 1) * TILE_WIDTH); + bottom_tile = height - (((*num_rows) - 1) * TILE_HEIGHT); + + for (i = 0, k = 0; i < (*num_rows); i++) + { + for (j = 0; j < (*num_cols); j++, k++) + { + tile_width = ((j == (*num_cols) - 1) ? right_tile : TILE_WIDTH); + tile_height = ((i == (*num_rows) - 1) ? bottom_tile : TILE_HEIGHT); + init_tile(&(tiles[k]), tile_width, tile_height, bpp); + } + } + D("Allocated %ix%i tiles.\n", (*num_cols), (*num_rows)); + return tiles; +} + +static void +init_tile(Tile *tile, int width, int height, int bpp) +{ + if (tile) + { + tile->bpp = bpp; + tile->ewidth = width; + tile->eheight = height; + tile->data = malloc(sizeof(DATA8) * width * height * bpp); + if (!tile->data) + { + D("Couldn't allocate tile.\n"); + } + } +} + +static void +free_tiles(Tile *tiles, int num_tiles) +{ + int i; + + for (i = 0; i < num_tiles; i++) + { + if (tiles[i].data) FREE(tiles[i].data); + } + FREE(tiles); +} + +static void +add_layer_to_image(Layer *layer) +{ + if (layer) + { + if (image->last_layer) + { + image->last_layer->next = layer; + layer->prev = image->last_layer; + } + else + { + image->layers = layer; + layer->prev = NULL; + } + layer->next = NULL; + image->last_layer = layer; + } +} + +static void +set_layer_opacity(Layer *layer) +{ + int i; + DATA8* ptr; + + if (layer) + { + if (layer->opacity != 255) + { + for (i = 0, ptr = layer->data; i < layer->width * layer->height; i++, ptr += 4) + { + *(ptr + 3) = (*(ptr + 3) * layer->opacity) >> 8; + } + } + } +} + +static void +apply_layer_mask(Layer *layer) +{ + DATA8* ptr1; + DATA8* ptr2; + int i, tmp; + + D("Applying layer mask.\n"); + if (layer) + { + if (layer->mask) + { + ptr1 = layer->data; + ptr2 = layer->mask->data; + for (i = 0; i < layer->width * layer->height; i++) + { + tmp = (*(ptr1 + 3) * *(ptr2)) / 256; + if (tmp > 255) tmp = 255; + *(ptr1 + 3) = (DATA8)tmp; + ptr1 += 4; + ptr2 += 4; + } + } + } +} + +static void +flatten_image(void) +{ + Layer* l = image->last_layer; + Layer* lp; + int layer_index; + + shm_alloc(image->width * image->height * sizeof(DATA32)); + if (!shm_addr) return; + image->data = shm_addr; + memset(image->data, 0, image->width * image->height * sizeof(DATA32)); + + layer_index = 0; + + while (l) + { + /* Ok, paste each layer on top of the image, using the mode's merging type. + We're moving upward through the layer stack. + --cK. + */ + if ((image->single_layer_index < 0) || + (layer_index == image->single_layer_index)) + { + // FIXME: not all modes are implemented right + // xcf's may not render right :) + switch (l->mode) + { + case MULTIPLY_MODE: + D("MULTIPLY\n"); + combine_pixels_mult(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case DIVIDE_MODE: + D("DIVIDE\n"); + combine_pixels_div(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case SCREEN_MODE: + D("SCREEN\n"); + combine_pixels_screen(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case OVERLAY_MODE: + D("OVERLAY\n"); + combine_pixels_overlay(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case DIFFERENCE_MODE: + D("DIFF\n"); + combine_pixels_diff(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case ADDITION_MODE: + D("ADD\n"); + combine_pixels_add(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case SUBTRACT_MODE: + D("SUB\n"); + combine_pixels_sub(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case DARKEN_ONLY_MODE: + D("DARKEN\n"); + combine_pixels_darken(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case LIGHTEN_ONLY_MODE: + D("LIGHTEN\n"); + combine_pixels_lighten(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case HUE_MODE: + D("HUE\n"); + combine_pixels_hue(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case SATURATION_MODE: + D("SATURATION\n"); + combine_pixels_sat(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case VALUE_MODE: + D("VALUE\n"); + combine_pixels_val(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case COLOR_MODE: + D("COLOR\n"); + combine_pixels_col(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + case DISSOLVE_MODE: + D("DISSOLVE\n"); + combine_pixels_diss(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + /* None of the following is actually valid for layer blending, fall through: */ + case BEHIND_MODE: + case REPLACE_MODE: + case ERASE_MODE: + case ANTI_ERASE_MODE: + D("EEEEEK -- this mode shouldn't be here\n"); + /* Fall through */ + + case NORMAL_MODE: + D("NORMAL\n"); + combine_pixels_normal(l->data, l->width, l->height, + image->data, image->width, image->height, + l->offset_x, l->offset_y); + break; + + default: + D("Unknown layer mode: %i. Skipping.\n", l->mode); + } + } + + lp = l->prev; + /* free the layer now, since it's not needed anymore */ + free_layer(l); + + l = lp; + layer_index++; + } + + /* We've used up all the layers now, so set them to NULL in the image: */ + image->layers = NULL; + image->last_layer = NULL; +} + +static char +xcf_file_init(char *filename) +{ + char success = 1; + char id[14]; + int width; + int height; + int image_type; + + image->single_layer_index = -1; + image->file = f_open(filename); + D("image->file = %p\n", image->file); + if (!image->file) return 0; + + image->filename = filename; + image->layers = NULL; + image->last_layer = NULL; + image->cmap = NULL; + image->num_cols = 0; + image->data = NULL; + + image->cp = 0; + + image->cp += xcf_read_int8(image->file, (DATA8 *)id, 14); + if (strncmp(id, "gimp xcf ", 9)) + { + success = 0; + f_close(image->file); + } + else if (!strcmp(id + 9, "file")) + { + image->file_version = 0; + } + else if (id[9] == 'v') + { + image->file_version = atoi(id + 10); + } + else + { + success = 0; + f_close(image->file); + } + + if (success) + { + image->cp += xcf_read_int32(image->file, (DATA32 *)&width, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&height, 1); + image->cp += xcf_read_int32(image->file, (DATA32 *)&image_type, 1); + + image->width = width; + image->height = height; + image->base_type = image_type; + + D("Loading %ix%i image.\n", width, height); + } + + return success; +} + +static void +xcf_cleanup(void) +{ + Layer *l, *lp; + + if (image->file) f_close(image->file); + for (l = image->last_layer; l; l = lp) + { + lp = l->prev; + free_layer(l); + } + if (image->cmap) FREE(image->cmap); +} + +static void +premul_image(void) +{ + DATA32 *p, *end; + + end = (DATA32 *)image->data + (image->width * image->height); + for (p = (DATA32 *)image->data; p < end; p++) + { + unsigned int r, g, b, a; + + a = A_VAL(p); + r = (R_VAL(p) * a) / 255; + R_VAL(p) = r; + g = (G_VAL(p) * a) / 255; + G_VAL(p) = g; + b = (B_VAL(p) * a) / 255; + B_VAL(p) = b; + } +} + +int +main(int argc, char **argv) +{ + char *file; + int w, h, i; + int head_only = 0; + + if (argc < 2) return -1; + // file is ALWAYS first arg, other options come after + file = argv[1]; + for (i = 2; i < argc; i++) + { + if (!strcmp(argv[i], "-head")) + // asked to only load header, not body/data + head_only = 1; + else if (!strcmp(argv[i], "-key")) + { // not used by xcf loader + i++; + // const char *key = argv[i]; + } + else if (!strcmp(argv[i], "-opt-scale-down-by")) + { // not used by xcf loader + i++; + // int scale_down = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-opt-dpi")) + { // not used by xcf loader + i++; + // double dpi = ((double)atoi(argv[i])) / 1000.0; + } + else if (!strcmp(argv[i], "-opt-size")) + { // not used by xcf loader + i++; + // int size_w = atoi(argv[i]); + i++; + // int size_h = atoi(argv[i]); + } + } + + timeout_init(8); + + D("xcf_file_init\n"); + if (!xcf_file_init(file)) return -1; + + D("size %i %i\n", image->width, image->height); + if (!head_only) + { + xcf_load_image(); + premul_image(); + } + w = image->width; + h = image->height; + printf("size %i %i\n", w, h); + printf("alpha 1\n"); + if (!head_only) + { + if (shm_fd >= 0) printf("shmfile %s\n", shmfile); + else + { + // could also to "tmpfile %s\n" like shmfile but just + // a mmaped tmp file on the system + printf("data\n"); + fwrite(image->data, w * h * sizeof(DATA32), 1, stdout); + } + shm_free(); + } + else + printf("done\n"); + xcf_cleanup(); + fflush(stdout); + return 0; +} diff --git a/legacy/evas_generic_loaders/src/bin/xcf/pixelfuncs.c b/legacy/evas_generic_loaders/src/bin/xcf/pixelfuncs.c new file mode 100644 index 0000000000..67d66d8129 --- /dev/null +++ b/legacy/evas_generic_loaders/src/bin/xcf/pixelfuncs.c @@ -0,0 +1,759 @@ +/* + + -----------------------------[ XCF Loader ]----------------------------- + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "common.h" + +#define RS R_VAL(src + s_idx) +#define GS G_VAL(src + s_idx) +#define BS B_VAL(src + s_idx) +#define AS A_VAL(src + s_idx) +#define RD R_VAL(dest + d_idx) +#define GD G_VAL(dest + d_idx) +#define BD B_VAL(dest + d_idx) +#define AD A_VAL(dest + d_idx) + +#define EPS 0.00001 +#define PI 3.141592654 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8)) +#define LINEAR(x,y,w) ((w*y + x)*4) + +static void +rgb_to_hls (DATA8 *red, DATA8 *green, DATA8 *blue) +{ + int r, g, b; + double h, l, s; + int min, max; + int delta; + + r = *red; + g = *green; + b = *blue; + + if (r > g) + { + max = MAX (r, b); + min = MIN (g, b); + } + else + { + max = MAX (g, b); + min = MIN (r, b); + } + + l = (max + min) / 2.0; + + if (max == min) + { + s = 0.0; + h = 0.0; + } + else + { + delta = (max - min); + + if (l < 128) + s = 255 * (double) delta / (double) (max + min); + else + s = 255 * (double) delta / (double) (511 - max - min); + + if (r == max) + h = (g - b) / (double) delta; + else if (g == max) + h = 2 + (b - r) / (double) delta; + else + h = 4 + (r - g) / (double) delta; + + h = h * 42.5; + + if (h < 0) + h += 255; + else if (h > 255) + h -= 255; + } + + *red = h; + *green = l; + *blue = s; +} + + +static DATA8 +gimp_hls_value (double n1, double n2, double hue) +{ + double value; + + if (hue > 255) + hue -= 255; + else if (hue < 0) + hue += 255; + if (hue < 42.5) + value = n1 + (n2 - n1) * (hue / 42.5); + else if (hue < 127.5) + value = n2; + else if (hue < 170) + value = n1 + (n2 - n1) * ((170 - hue) / 42.5); + else + value = n1; + + return (DATA8) (value * 255); +} + + +static void +hls_to_rgb (DATA8 *hue, DATA8 *lightness, DATA8 *saturation) +{ + double h, l, s; + double m1, m2; + + h = *hue; + l = *lightness; + s = *saturation; + + if (s == 0) + { + /* achromatic case */ + *hue = l; + *lightness = l; + *saturation = l; + } + else + { + if (l < 128) + m2 = (l * (255 + s)) / 65025.0; + else + m2 = (l + s - (l * s) / 255.0) / 255.0; + + m1 = (l / 127.5) - m2; + + /* chromatic case */ + *hue = gimp_hls_value (m1, m2, h + 85); + *lightness = gimp_hls_value (m1, m2, h); + *saturation = gimp_hls_value (m1, m2, h - 85); + } +} + + +static void +rgb_to_hsv (DATA8 *red, DATA8 *green, DATA8 *blue) +{ + int r, g, b; + double h, s, v; + int min, max; + int delta; + + h = 0.0; + + r = *red; + g = *green; + b = *blue; + + if (r > g) + { + max = MAX (r, b); + min = MIN (g, b); + } + else + { + max = MAX (g, b); + min = MIN (r, b); + } + + v = max; + + if (max != 0) + s = ((max - min) * 255) / (double) max; + else + s = 0; + + if (s == 0) + h = 0; + else + { + delta = max - min; + if (r == max) + h = (g - b) / (double) delta; + else if (g == max) + h = 2 + (b - r) / (double) delta; + else if (b == max) + h = 4 + (r - g) / (double) delta; + h *= 42.5; + + if (h < 0) + h += 255; + if (h > 255) + h -= 255; + } + + *red = h; + *green = s; + *blue = v; +} + +static void +hsv_to_rgb (DATA8 *hue, DATA8 *saturation, DATA8 *value) +{ + double h, s, v; + double f, p, q, t; + + if (*saturation == 0) + { + *hue = *value; + *saturation = *value; + /* *value = *value; */ + } + else + { + h = *hue * 6.0 / 255.0; + s = *saturation / 255.0; + v = *value / 255.0; + + f = h - (int) h; + p = v * (1.0 - s); + q = v * (1.0 - (s * f)); + t = v * (1.0 - (s * (1.0 - f))); + + switch ((int) h) + { + case 0: + *hue = v * 255; + *saturation = t * 255; + *value = p * 255; + break; + + case 1: + *hue = q * 255; + *saturation = v * 255; + *value = p * 255; + break; + + case 2: + *hue = p * 255; + *saturation = v * 255; + *value = t * 255; + break; + + case 3: + *hue = p * 255; + *saturation = q * 255; + *value = v * 255; + break; + + case 4: + *hue = t * 255; + *saturation = p * 255; + *value = v * 255; + break; + + case 5: + *hue = v * 255; + *saturation = p * 255; + *value = q * 255; + break; + } + } +} + +/* translate negative destinations */ +static +void _clip(int * src_tl_x, int * src_tl_y, + int * src_br_x, int * src_br_y, + int * dest_x, int * dest_y, + int dest_w, int dest_h) +{ + if (*dest_x + *src_br_x >= dest_w) + { *src_br_x -= (*dest_x + *src_br_x) - dest_w; } + + if (*dest_y + *src_br_y >= dest_h) + { *src_br_y -= (*dest_y + *src_br_y) - dest_h; } + + if (*dest_x < 0) + { + *src_tl_x = -(*dest_x); + *dest_x = 0; + } + if (*dest_y < 0) + { + *src_tl_y = -(*dest_y); + *dest_y = 0; + } +} + +// FIXME: make sure layer alpha is used/applied in all cases +void +combine_pixels_normal (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + int b; + unsigned char src_alpha; + unsigned char new_alpha; + float ratio, compl_ratio; + unsigned long tmp; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + src_alpha = AS; + + if (src_alpha != 0) + { + if (src_alpha == 255) + new_alpha = src_alpha; + else + new_alpha = AD + INT_MULT((255u - AD), src_alpha, tmp); + + b = 3; + if (new_alpha != 0) + { + ratio = (float) src_alpha / new_alpha; + compl_ratio = 1.0 - ratio; + + do + { + b--; + dest[d_idx + b] = + (unsigned char) (src[s_idx + b] * ratio + dest[d_idx + b] * compl_ratio + EPS); + } + while (b); + } + + AD = new_alpha; + } + } +} + + +void +combine_pixels_add (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + int tmp, tmp2; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + tmp2 = INT_MULT(AS, RS, tmp); + tmp = RD + tmp2; + RD = (tmp > 255 ? 255 : tmp); + + tmp2 = INT_MULT(AS, GS, tmp); + tmp = GD + tmp2; + GD = (tmp > 255 ? 255 : tmp); + + tmp2 = INT_MULT(AS, BS, tmp); + tmp = BD + tmp2; + BD = (tmp > 255 ? 255 : tmp); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_sub (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + int tmp, tmp2; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + tmp2 = INT_MULT(AS, RS, tmp); + tmp = RD - tmp2; + RD = (tmp < 0 ? 0 : tmp); + + tmp2 = INT_MULT(AS, GS, tmp); + tmp = GD - tmp2; + GD = (tmp < 0 ? 0 : tmp); + + tmp2 = INT_MULT(AS, BS, tmp); + tmp = BD - tmp2; + BD = (tmp < 0 ? 0 : tmp); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_diff (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + int tmp, tmp2; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + tmp2 = INT_MULT(AS, RS, tmp); + tmp = RD - tmp2; + RD = (tmp < 0 ? -tmp : tmp); + + tmp2 = INT_MULT(AS, GS, tmp); + tmp = GD - tmp2; + GD = (tmp < 0 ? -tmp : tmp); + + tmp2 = INT_MULT(AS, BS, tmp); + tmp = BD - tmp2; + BD = (tmp < 0 ? -tmp : tmp); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_darken (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + RD = MIN(RD, RS); + GD = MIN(GD, GS); + BD = MIN(BD, BS); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_lighten (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + RD = MAX(RD, RS); + GD = MAX(GD, GS); + BD = MAX(BD, BS); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_mult (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + int tmp, tmp2, tmp3; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + tmp2 = INT_MULT(RS, AS, tmp); + tmp2 = INT_MULT(RD, tmp2, tmp); + tmp3 = INT_MULT(RD, (255 - AS), tmp); + RD = (tmp2 + tmp3); + + tmp2 = INT_MULT(GS, AS, tmp); + tmp2 = INT_MULT(GD, tmp2, tmp); + tmp3 = INT_MULT(GD, (255 - AS), tmp); + GD = (tmp2 + tmp3); + + tmp2 = INT_MULT(BS, AS, tmp); + tmp2 = INT_MULT(BD, tmp2, tmp); + tmp3 = INT_MULT(BD, (255 - AS), tmp); + BD = (tmp2 + tmp3); + +// AS = MIN(AS, AD); + } + +// combine_pixels_normal(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y); +} + + +void +combine_pixels_div (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + RS = MIN(255, ((float)RD / (RS + 1)) * 256); + GS = MIN(255, ((float)GD / (GS + 1)) * 256); + BS = MIN(255, ((float)BD / (BS + 1)) * 256); + +// AS = MIN(AD, AS); + } + + combine_pixels_normal(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y); +} + + +void +combine_pixels_screen (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + RD = 255 - (((255 - RD) * (255 - RS)) >> 8); + GD = 255 - (((255 - GD) * (255 - GS)) >> 8); + BD = 255 - (((255 - BD) * (255 - BS)) >> 8); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_overlay (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + int tmp_screen, tmp_mult; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + tmp_screen = 255 - (((255 - RD) * (255 - RS)) >> 8); + tmp_mult = (RD * RS) >> 8; + RD = (RD * tmp_screen + (255 - RD) * tmp_mult) >> 8; + + tmp_screen = 255 - (((255 - GD) * (255 - GS)) >> 8); + tmp_mult = (GD * GS) >> 8; + GD = (GD * tmp_screen + (255 - GD) * tmp_mult) >> 8; + + tmp_screen = 255 - (((255 - BD) * (255 - BS)) >> 8); + tmp_mult = (BD * BS) >> 8; + BD = (BD * tmp_screen + (255 - BD) * tmp_mult) >> 8; + +// AD = MIN(AD, AS); + } +} + + +static void +combine_pixels_hsv (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y, int mode) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + rgb_to_hsv(&RS, &GS, &BS); + rgb_to_hsv(&RD, &GD, &BD); + + switch (mode) + { + case 0: /* hue mode */ + RD = RS; + break; + case 1: /* saturation mode */ + GD = GS; + break; + case 2: /* value mode */ + BD = BS; + break; + default: + break; + } + + hsv_to_rgb(&RD, &GD, &BD); +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_hue (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 0); +} + + +void +combine_pixels_sat (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 1); +} + + +void +combine_pixels_val (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 2); +} + + +void +combine_pixels_col (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + rgb_to_hls(&RS, &GS, &BS); + rgb_to_hls(&RD, &GD, &BD); + RD = RS; + BD = BS; + hls_to_rgb(&RD, &GD, &BD); + +// AD = MIN(AD, AS); + } +} + + +void +combine_pixels_diss (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y) +{ + int x, y, s_idx, d_idx; + int src_tl_x = 0, src_tl_y = 0; + int src_br_x = src_w, src_br_y = src_h; + + srand(12345); + + _clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h); + + for (y = src_tl_y; y < src_br_y; y++) + for (x = src_tl_x; x < src_br_x; x++) + { + d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w); + s_idx = LINEAR(x, y, src_w); + + if ((rand() % 255) < AS) + { + int b; + unsigned char src_alpha; + unsigned char new_alpha; + float ratio, compl_ratio; + unsigned long tmp; + + src_alpha = AS; + + if (src_alpha != 0) + { + if (src_alpha == 255) + new_alpha = src_alpha; + else + new_alpha = AD + INT_MULT((255u - AD), src_alpha, tmp); + + b = 3; + if (new_alpha != 0) + { + ratio = (float) src_alpha / new_alpha; + compl_ratio = 1.0 - ratio; + + do + { + b--; + dest[d_idx + b] = + (unsigned char) (src[s_idx + b] * ratio + dest[d_idx + b] * compl_ratio + EPS); + } + while (b); + } + + AD = new_alpha; + } + } + } +}