mirror of
https://github.com/gryf/wmaker.git
synced 2026-02-02 22:25:48 +01:00
Initial revision
This commit is contained in:
0
wrlib/AUTHORS
Normal file
0
wrlib/AUTHORS
Normal file
481
wrlib/COPYING
Normal file
481
wrlib/COPYING
Normal file
@@ -0,0 +1,481 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, 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 library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, 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 companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
7
wrlib/ChangeLog
Normal file
7
wrlib/ChangeLog
Normal file
@@ -0,0 +1,7 @@
|
||||
- added RMakeCenteredImage()
|
||||
|
||||
- Added code to draw pixels and lines. Both writing absolute values, or
|
||||
offseting existing pixels with delta values are supported.
|
||||
- Remade the beveling code to be simpler, using the RAlterLine() functions.
|
||||
- Fixed some pixels in the bevels.
|
||||
- Changed RAlter* functions to more generic ROperate*
|
||||
5
wrlib/INSTALL
Normal file
5
wrlib/INSTALL
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
56
wrlib/Makefile.am
Normal file
56
wrlib/Makefile.am
Normal file
@@ -0,0 +1,56 @@
|
||||
## automake input file for wrlib
|
||||
|
||||
AUTOMAKE_OPTIONS = no-dependencies
|
||||
|
||||
lib_LIBRARIES = libwraster.a
|
||||
|
||||
noinst_PROGRAMS = test testgrad testdraw view
|
||||
|
||||
EXTRA_DIST = test.png tile.xpm ballot_box.xpm ballot_box.tiff
|
||||
|
||||
include_HEADERS = wraster.h
|
||||
|
||||
libwraster_a_SOURCES = \
|
||||
raster.c \
|
||||
draw.c \
|
||||
color.c \
|
||||
load.c \
|
||||
gradient.c \
|
||||
xpixmap.c \
|
||||
convert.c \
|
||||
context.c \
|
||||
misc.c \
|
||||
scale.c \
|
||||
convolve.c \
|
||||
nxpm.c \
|
||||
xpm.c \
|
||||
xutil.c \
|
||||
ppm.c \
|
||||
png.c \
|
||||
jpeg.c \
|
||||
tiff.c \
|
||||
gif.c
|
||||
|
||||
|
||||
INCLUDES = @DFLAGS@ @XCFLAGS@ @GFXFLAGS@ @XSHM@
|
||||
|
||||
view_SOURCES= view.c
|
||||
|
||||
view_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
test_SOURCES = test.c
|
||||
|
||||
test_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
testgrad_SOURCES = testgrad.c
|
||||
|
||||
testgrad_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
testdraw_SOURCES = testdraw.c
|
||||
|
||||
testdraw_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
|
||||
libwraster_a_LIBADD = @ALLOCA@
|
||||
|
||||
|
||||
406
wrlib/Makefile.in
Normal file
406
wrlib/Makefile.in
Normal file
@@ -0,0 +1,406 @@
|
||||
# Makefile.in generated automatically by automake 1.3 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DISTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
CC = @CC@
|
||||
CPP_PATH = @CPP_PATH@
|
||||
DFLAGS = @DFLAGS@
|
||||
GFXFLAGS = @GFXFLAGS@
|
||||
GFXLIBS = @GFXLIBS@
|
||||
I18N = @I18N@
|
||||
I18N_MB = @I18N_MB@
|
||||
ICONEXT = @ICONEXT@
|
||||
INTLIBS = @INTLIBS@
|
||||
LIBPL_INC_PATH = @LIBPL_INC_PATH@
|
||||
LIBPL_LIBS = @LIBPL_LIBS@
|
||||
LN_S = @LN_S@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MOFILES = @MOFILES@
|
||||
NLSDIR = @NLSDIR@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
REDUCE_APPICONS = @REDUCE_APPICONS@
|
||||
SHAPE = @SHAPE@
|
||||
SOUND = @SOUND@
|
||||
VERSION = @VERSION@
|
||||
WPMOFILES = @WPMOFILES@
|
||||
XCFLAGS = @XCFLAGS@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
XLFLAGS = @XLFLAGS@
|
||||
XLIBS = @XLIBS@
|
||||
XSHM = @XSHM@
|
||||
X_EXTRA_LIBS = @X_EXTRA_LIBS@
|
||||
X_LOCALE = @X_LOCALE@
|
||||
pixmapdir = @pixmapdir@
|
||||
wprefsdir = @wprefsdir@
|
||||
|
||||
AUTOMAKE_OPTIONS = no-dependencies
|
||||
|
||||
lib_LIBRARIES = libwraster.a
|
||||
|
||||
noinst_PROGRAMS = test testgrad testdraw view
|
||||
|
||||
EXTRA_DIST = test.png tile.xpm ballot_box.xpm ballot_box.tiff
|
||||
|
||||
include_HEADERS = wraster.h
|
||||
|
||||
libwraster_a_SOURCES = \
|
||||
raster.c \
|
||||
draw.c \
|
||||
color.c \
|
||||
load.c \
|
||||
gradient.c \
|
||||
xpixmap.c \
|
||||
convert.c \
|
||||
context.c \
|
||||
misc.c \
|
||||
scale.c \
|
||||
convolve.c \
|
||||
nxpm.c \
|
||||
xpm.c \
|
||||
xutil.c \
|
||||
ppm.c \
|
||||
png.c \
|
||||
jpeg.c \
|
||||
tiff.c \
|
||||
gif.c
|
||||
|
||||
INCLUDES = @DFLAGS@ @XCFLAGS@ @GFXFLAGS@ @XSHM@
|
||||
|
||||
view_SOURCES= view.c
|
||||
|
||||
view_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
test_SOURCES = test.c
|
||||
|
||||
test_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
testgrad_SOURCES = testgrad.c
|
||||
|
||||
testgrad_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
testdraw_SOURCES = testdraw.c
|
||||
|
||||
testdraw_LDADD = -L. -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm
|
||||
|
||||
libwraster_a_LIBADD = @ALLOCA@
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../src/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LIBRARIES = $(lib_LIBRARIES)
|
||||
|
||||
|
||||
DEFS = @DEFS@ -I. -I$(srcdir) -I../src
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
X_CFLAGS = @X_CFLAGS@
|
||||
X_LIBS = @X_LIBS@
|
||||
X_PRE_LIBS = @X_PRE_LIBS@
|
||||
libwraster_a_DEPENDENCIES = @ALLOCA@
|
||||
libwraster_a_OBJECTS = raster.o draw.o color.o load.o gradient.o \
|
||||
xpixmap.o convert.o context.o misc.o scale.o convolve.o nxpm.o xpm.o \
|
||||
xutil.o ppm.o png.o jpeg.o tiff.o gif.o
|
||||
AR = ar
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
|
||||
test_OBJECTS = test.o
|
||||
test_DEPENDENCIES =
|
||||
test_LDFLAGS =
|
||||
testgrad_OBJECTS = testgrad.o
|
||||
testgrad_DEPENDENCIES =
|
||||
testgrad_LDFLAGS =
|
||||
testdraw_OBJECTS = testdraw.o
|
||||
testdraw_DEPENDENCIES =
|
||||
testdraw_LDFLAGS =
|
||||
view_OBJECTS = view.o
|
||||
view_DEPENDENCIES =
|
||||
view_LDFLAGS =
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
HEADERS = $(include_HEADERS)
|
||||
|
||||
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
|
||||
Makefile.in NEWS TODO alloca.c configure.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP = --best
|
||||
SOURCES = $(libwraster_a_SOURCES) $(test_SOURCES) $(testgrad_SOURCES) $(testdraw_SOURCES) $(view_SOURCES)
|
||||
OBJECTS = $(libwraster_a_OBJECTS) $(test_OBJECTS) $(testgrad_OBJECTS) $(testdraw_OBJECTS) $(view_OBJECTS)
|
||||
|
||||
all: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .o .s
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu wrlib/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
mostlyclean-libLIBRARIES:
|
||||
|
||||
clean-libLIBRARIES:
|
||||
-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
|
||||
|
||||
distclean-libLIBRARIES:
|
||||
|
||||
maintainer-clean-libLIBRARIES:
|
||||
|
||||
install-libLIBRARIES: $(lib_LIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
list='$(lib_LIBRARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
|
||||
else :; fi; \
|
||||
done
|
||||
@$(POST_INSTALL)
|
||||
@list='$(lib_LIBRARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \
|
||||
$(RANLIB) $(DESTDIR)$(libdir)/$$p; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-libLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(lib_LIBRARIES)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(libdir)/$$p; \
|
||||
done
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.S.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
|
||||
clean-compile:
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
maintainer-clean-compile:
|
||||
|
||||
libwraster.a: $(libwraster_a_OBJECTS) $(libwraster_a_DEPENDENCIES)
|
||||
-rm -f libwraster.a
|
||||
$(AR) cru libwraster.a $(libwraster_a_OBJECTS) $(libwraster_a_LIBADD)
|
||||
$(RANLIB) libwraster.a
|
||||
|
||||
mostlyclean-noinstPROGRAMS:
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
|
||||
|
||||
distclean-noinstPROGRAMS:
|
||||
|
||||
maintainer-clean-noinstPROGRAMS:
|
||||
|
||||
test: $(test_OBJECTS) $(test_DEPENDENCIES)
|
||||
@rm -f test
|
||||
$(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS)
|
||||
|
||||
testgrad: $(testgrad_OBJECTS) $(testgrad_DEPENDENCIES)
|
||||
@rm -f testgrad
|
||||
$(LINK) $(testgrad_LDFLAGS) $(testgrad_OBJECTS) $(testgrad_LDADD) $(LIBS)
|
||||
|
||||
testdraw: $(testdraw_OBJECTS) $(testdraw_DEPENDENCIES)
|
||||
@rm -f testdraw
|
||||
$(LINK) $(testdraw_LDFLAGS) $(testdraw_OBJECTS) $(testdraw_LDADD) $(LIBS)
|
||||
|
||||
view: $(view_OBJECTS) $(view_DEPENDENCIES)
|
||||
@rm -f view
|
||||
$(LINK) $(view_LDFLAGS) $(view_OBJECTS) $(view_LDADD) $(LIBS)
|
||||
|
||||
install-includeHEADERS: $(include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(includedir)
|
||||
@list='$(include_HEADERS)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
|
||||
echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
|
||||
$(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
|
||||
done
|
||||
|
||||
uninstall-includeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(include_HEADERS)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(includedir)/$$p; \
|
||||
done
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = wrlib
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file; \
|
||||
done
|
||||
info:
|
||||
dvi:
|
||||
check: all
|
||||
$(MAKE)
|
||||
installcheck:
|
||||
install-exec: install-libLIBRARIES
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install-data: install-includeHEADERS
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install: install-exec install-data all
|
||||
@:
|
||||
|
||||
uninstall: uninstall-libLIBRARIES uninstall-includeHEADERS
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DATADIR)$(libdir) $(DATADIR)$(includedir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(DISTCLEANFILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean: mostlyclean-libLIBRARIES mostlyclean-compile \
|
||||
mostlyclean-noinstPROGRAMS mostlyclean-tags \
|
||||
mostlyclean-generic
|
||||
|
||||
clean: clean-libLIBRARIES clean-compile clean-noinstPROGRAMS clean-tags \
|
||||
clean-generic mostlyclean
|
||||
|
||||
distclean: distclean-libLIBRARIES distclean-compile \
|
||||
distclean-noinstPROGRAMS distclean-tags \
|
||||
distclean-generic clean
|
||||
-rm -f config.status
|
||||
|
||||
maintainer-clean: maintainer-clean-libLIBRARIES \
|
||||
maintainer-clean-compile \
|
||||
maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
.PHONY: mostlyclean-libLIBRARIES distclean-libLIBRARIES \
|
||||
clean-libLIBRARIES maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \
|
||||
install-libLIBRARIES mostlyclean-compile distclean-compile \
|
||||
clean-compile maintainer-clean-compile mostlyclean-noinstPROGRAMS \
|
||||
distclean-noinstPROGRAMS clean-noinstPROGRAMS \
|
||||
maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
|
||||
install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
|
||||
maintainer-clean-tags distdir info dvi installcheck install-exec \
|
||||
install-data install uninstall all installdirs mostlyclean-generic \
|
||||
distclean-generic clean-generic maintainer-clean-generic clean \
|
||||
mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
0
wrlib/NEWS
Normal file
0
wrlib/NEWS
Normal file
33
wrlib/README
Normal file
33
wrlib/README
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
WindowMaker raster graphics library
|
||||
|
||||
This library is used to manipulate images and convert them to
|
||||
a format that can be displayed through the X window system.
|
||||
Read the wraster.h header for an idea of what is available
|
||||
|
||||
|
||||
This Library is LGPL and
|
||||
Copyright (c) Alfredo K. Kojima <kojima@inf.ufrgs.br>
|
||||
|
||||
|
||||
The following environment variables control some parameters:
|
||||
|
||||
RIMAGE_CACHE <integer>
|
||||
|
||||
Is the maximum number of images to store in the internal cache.
|
||||
Default is 8
|
||||
|
||||
RIMAGE_CACHE_SIZE <integer>
|
||||
|
||||
Is the size of the biggest image to store in the cache.
|
||||
Default is 4k (64x64)
|
||||
|
||||
|
||||
|
||||
Porting
|
||||
=======
|
||||
|
||||
It should be fairly easy to port it to other environments
|
||||
(svgalib, libggi etc), probably only requiring wraster.h,
|
||||
context.c and convert.c to be changed. Note that the X specific
|
||||
code should be disabled in that case, including support for libXpm.
|
||||
6
wrlib/TODO
Normal file
6
wrlib/TODO
Normal file
@@ -0,0 +1,6 @@
|
||||
- support for other types of displays and convertion modes (currently only
|
||||
supports PseudoColor and TrueColor in some depths)
|
||||
- Gimp's xcf format?
|
||||
- shared library version
|
||||
- add clipping code to RCombineArea()
|
||||
- remake and optimize converters
|
||||
504
wrlib/alloca.c
Normal file
504
wrlib/alloca.c
Normal file
@@ -0,0 +1,504 @@
|
||||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
#ifndef alloca
|
||||
|
||||
#ifdef emacs
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||
ordinary malloc isn't protected from input signals. On the other
|
||||
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||
them are very simple, and don't have an xmalloc routine.
|
||||
|
||||
Non-Emacs programs expect this to call use xmalloc.
|
||||
|
||||
Callers below should use malloc. */
|
||||
|
||||
#ifndef emacs
|
||||
#define malloc xmalloc
|
||||
#endif
|
||||
extern pointer malloc ();
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
if (new == 0)
|
||||
abort();
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef CRAY_STACK
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
BIN
wrlib/ballot_box.tiff
Normal file
BIN
wrlib/ballot_box.tiff
Normal file
Binary file not shown.
906
wrlib/ballot_box.xpm
Normal file
906
wrlib/ballot_box.xpm
Normal file
@@ -0,0 +1,906 @@
|
||||
/* XPM */
|
||||
static char * ballot_box_xpm[] = {
|
||||
"48 48 855 2",
|
||||
" c None",
|
||||
". c #B8B8B8",
|
||||
"+ c #A0A0A0",
|
||||
"@ c #4A2511",
|
||||
"# c #A7A7A7",
|
||||
"$ c #EDEDED",
|
||||
"% c #EBE8E7",
|
||||
"& c #A6948D",
|
||||
"* c #904B22",
|
||||
"= c #B4622D",
|
||||
"- c #9F5427",
|
||||
"; c #87431F",
|
||||
"> c #4B2410",
|
||||
", c #BFBFBF",
|
||||
"' c #464646",
|
||||
") c #818181",
|
||||
"! c #D4D4D4",
|
||||
"~ c #FEFEFE",
|
||||
"{ c #E79860",
|
||||
"] c #E38848",
|
||||
"^ c #F4E2D5",
|
||||
"/ c #F0E7E2",
|
||||
"( c #C1804A",
|
||||
"_ c #9B562B",
|
||||
": c #7D3E1C",
|
||||
"< c #8A8A8A",
|
||||
"[ c #ECDEDF",
|
||||
"} c #B68183",
|
||||
"| c #E2E2E2",
|
||||
"1 c #6A6A6A",
|
||||
"2 c #686868",
|
||||
"3 c #C6C6C6",
|
||||
"4 c #F7F7F7",
|
||||
"5 c #F5D6C1",
|
||||
"6 c #E7C9B3",
|
||||
"7 c #D1D1D1",
|
||||
"8 c #FBFBFB",
|
||||
"9 c #E7A966",
|
||||
"0 c #E7AC69",
|
||||
"a c #D79A5D",
|
||||
"b c #B77642",
|
||||
"c c #9B562C",
|
||||
"d c #743819",
|
||||
"e c #3E1C0C",
|
||||
"f c #717171",
|
||||
"g c #B4B4B4",
|
||||
"h c #C1A7A8",
|
||||
"i c #B37F80",
|
||||
"j c #BC8E90",
|
||||
"k c #797979",
|
||||
"l c #343434",
|
||||
"m c #E0E0E0",
|
||||
"n c #DABFC0",
|
||||
"o c #924345",
|
||||
"p c #E3CFCF",
|
||||
"q c #A46264",
|
||||
"r c #D1B0B1",
|
||||
"s c #91857C",
|
||||
"t c #ABABAB",
|
||||
"u c #EADBCA",
|
||||
"v c #C98D54",
|
||||
"w c #E7AA67",
|
||||
"x c #E8AC69",
|
||||
"y c #E8AD6B",
|
||||
"z c #EAAF6C",
|
||||
"A c #D99E61",
|
||||
"B c #AD6E3E",
|
||||
"C c #884723",
|
||||
"D c #663015",
|
||||
"E c #503C33",
|
||||
"F c #565656",
|
||||
"G c #7E7878",
|
||||
"H c #978383",
|
||||
"I c #E8E8E8",
|
||||
"J c #DBDBDB",
|
||||
"K c #5F5F5F",
|
||||
"L c #444444",
|
||||
"M c #343130",
|
||||
"N c #EEEEEE",
|
||||
"O c #BF9192",
|
||||
"P c #C8A0A1",
|
||||
"Q c #9B5254",
|
||||
"R c #DDDDDD",
|
||||
"S c #BDBDBD",
|
||||
"T c #646464",
|
||||
"U c #CEC3BA",
|
||||
"V c #8D5730",
|
||||
"W c #E6A865",
|
||||
"X c #E2A466",
|
||||
"Y c #EAB270",
|
||||
"Z c #ECB472",
|
||||
"` c #BC8450",
|
||||
" . c #9A5C32",
|
||||
".. c #763E20",
|
||||
"+. c #4F3120",
|
||||
"@. c #3A312C",
|
||||
"#. c #5D5D5D",
|
||||
"$. c #999999",
|
||||
"%. c #2C2C2C",
|
||||
"&. c #834D28",
|
||||
"*. c #3D3834",
|
||||
"=. c #C0C0C0",
|
||||
"-. c #E1E1E1",
|
||||
";. c #414141",
|
||||
">. c #BBBBBB",
|
||||
",. c #3B1407",
|
||||
"'. c #2F2113",
|
||||
"). c #764A2A",
|
||||
"!. c #DFA061",
|
||||
"~. c #E8AC6A",
|
||||
"{. c #E9AE6B",
|
||||
"]. c #EAB06D",
|
||||
"^. c #EBB270",
|
||||
"/. c #EDB673",
|
||||
"(. c #D9A368",
|
||||
"_. c #B17848",
|
||||
":. c #8A4B27",
|
||||
"<. c #470C06",
|
||||
"[. c #4B220E",
|
||||
"}. c #9D562A",
|
||||
"|. c #CB7F43",
|
||||
"1. c #D98D4C",
|
||||
"2. c #AF7B4F",
|
||||
"3. c #4F4F4F",
|
||||
"4. c #D3C0C0",
|
||||
"5. c #AB7D7E",
|
||||
"6. c #C7C7C7",
|
||||
"7. c #989898",
|
||||
"8. c #535353",
|
||||
"9. c #201714",
|
||||
"0. c #8E8E8E",
|
||||
"a. c #413531",
|
||||
"b. c #B07042",
|
||||
"c. c #E7AB68",
|
||||
"d. c #EAB77D",
|
||||
"e. c #ECB87E",
|
||||
"f. c #EAB06E",
|
||||
"g. c #EDB674",
|
||||
"h. c #EEB877",
|
||||
"i. c #F2C17E",
|
||||
"j. c #D0B17B",
|
||||
"k. c #693E29",
|
||||
"l. c #34160A",
|
||||
"m. c #854520",
|
||||
"n. c #BB6F38",
|
||||
"o. c #DC965F",
|
||||
"p. c #E4AE81",
|
||||
"q. c #F4E1D1",
|
||||
"r. c #C4C4C4",
|
||||
"s. c #333333",
|
||||
"t. c #929292",
|
||||
"u. c #DACDCD",
|
||||
"v. c #A47071",
|
||||
"w. c #7A7A7A",
|
||||
"x. c #212121",
|
||||
"y. c #252525",
|
||||
"z. c #626262",
|
||||
"A. c #CFD8D4",
|
||||
"B. c #F4DABD",
|
||||
"C. c #E9AF6C",
|
||||
"D. c #EAB16F",
|
||||
"E. c #EBB371",
|
||||
"F. c #EDB875",
|
||||
"G. c #F8D693",
|
||||
"H. c #FCDD9A",
|
||||
"I. c #E19151",
|
||||
"J. c #3A1407",
|
||||
"K. c #6B3316",
|
||||
"L. c #B16532",
|
||||
"M. c #D07F41",
|
||||
"N. c #DC9A67",
|
||||
"O. c #AEAEAE",
|
||||
"P. c #9E9E9E",
|
||||
"Q. c #9C9C9C",
|
||||
"R. c #2F2F2F",
|
||||
"S. c #8F8F8F",
|
||||
"T. c #B0B0B0",
|
||||
"U. c #9A9A9A",
|
||||
"V. c #6D6D6D",
|
||||
"W. c #363636",
|
||||
"X. c #0F0F0F",
|
||||
"Y. c #2D2D2D",
|
||||
"Z. c #757575",
|
||||
"`. c #A9ACAA",
|
||||
" + c #91A59C",
|
||||
".+ c #C0CBC6",
|
||||
"++ c #637F72",
|
||||
"@+ c #F0CAA1",
|
||||
"#+ c #EEBB78",
|
||||
"$+ c #FADA98",
|
||||
"%+ c #F8D18E",
|
||||
"&+ c #E58D48",
|
||||
"*+ c #CB6830",
|
||||
"=+ c #502510",
|
||||
"-+ c #9B5328",
|
||||
";+ c #C9773B",
|
||||
">+ c #D27F40",
|
||||
",+ c #D38141",
|
||||
"'+ c #D48344",
|
||||
")+ c #BF8253",
|
||||
"!+ c #85532C",
|
||||
"~+ c #361A0C",
|
||||
"{+ c #686260",
|
||||
"]+ c #CFCFCF",
|
||||
"^+ c #5A5A5A",
|
||||
"/+ c #1A1A1A",
|
||||
"(+ c #5E5E5E",
|
||||
"_+ c #5C5C5C",
|
||||
":+ c #3A3A3A",
|
||||
"<+ c #0D0D0D",
|
||||
"[+ c #3E3E3E",
|
||||
"}+ c #828282",
|
||||
"|+ c #C4C7C6",
|
||||
"1+ c #DFE4E2",
|
||||
"2+ c #15402C",
|
||||
"3+ c #A1B2AA",
|
||||
"4+ c #F6E2CD",
|
||||
"5+ c #EBB882",
|
||||
"6+ c #EFBE7C",
|
||||
"7+ c #FCE09D",
|
||||
"8+ c #F2BC79",
|
||||
"9+ c #D77334",
|
||||
"0+ c #DF7D3A",
|
||||
"a+ c #E07E3B",
|
||||
"b+ c #8B4821",
|
||||
"c+ c #BF6C34",
|
||||
"d+ c #CE7A3D",
|
||||
"e+ c #D07C3E",
|
||||
"f+ c #D17E3F",
|
||||
"g+ c #CA7A3E",
|
||||
"h+ c #864722",
|
||||
"i+ c #511F0C",
|
||||
"j+ c #491909",
|
||||
"k+ c #4B2211",
|
||||
"l+ c #6C6360",
|
||||
"m+ c #323232",
|
||||
"n+ c #131313",
|
||||
"o+ c #191919",
|
||||
"p+ c #393939",
|
||||
"q+ c #C9C9C9",
|
||||
"r+ c #728C80",
|
||||
"s+ c #967568",
|
||||
"t+ c #66331A",
|
||||
"u+ c #E6A965",
|
||||
"v+ c #F4CB88",
|
||||
"w+ c #FEE4A1",
|
||||
"x+ c #E89F5D",
|
||||
"y+ c #DC7736",
|
||||
"z+ c #DD7937",
|
||||
"A+ c #DE7A37",
|
||||
"B+ c #D77536",
|
||||
"C+ c #AF5F2C",
|
||||
"D+ c #E2813C",
|
||||
"E+ c #D77C3B",
|
||||
"F+ c #CD783C",
|
||||
"G+ c #CF7A3D",
|
||||
"H+ c #CA793D",
|
||||
"I+ c #B06733",
|
||||
"J+ c #B26835",
|
||||
"K+ c #815636",
|
||||
"L+ c #1D1715",
|
||||
"M+ c #1B0D08",
|
||||
"N+ c #706F6F",
|
||||
"O+ c #939393",
|
||||
"P+ c #050505",
|
||||
"Q+ c #040404",
|
||||
"R+ c #000000",
|
||||
"S+ c #0D0401",
|
||||
"T+ c #1F0A03",
|
||||
"U+ c #444140",
|
||||
"V+ c #F7E6D6",
|
||||
"W+ c #7A492D",
|
||||
"X+ c #A96F3F",
|
||||
"Y+ c #E6A966",
|
||||
"Z+ c #F8D491",
|
||||
"`+ c #F9D593",
|
||||
" @ c #DF8748",
|
||||
".@ c #DA7434",
|
||||
"+@ c #DB7635",
|
||||
"@@ c #DB7736",
|
||||
"#@ c #D47234",
|
||||
"$@ c #793E24",
|
||||
"%@ c #361F1A",
|
||||
"&@ c #4D1C0A",
|
||||
"*@ c #783919",
|
||||
"=@ c #D87A38",
|
||||
"-@ c #D77B3B",
|
||||
";@ c #CD773B",
|
||||
">@ c #D07D3E",
|
||||
",@ c #D27E40",
|
||||
"'@ c #D38041",
|
||||
")@ c #D48243",
|
||||
"!@ c #D7894A",
|
||||
"~@ c #B28E5F",
|
||||
"{@ c #2A261D",
|
||||
"]@ c #030100",
|
||||
"^@ c #222121",
|
||||
"/@ c #171717",
|
||||
"(@ c #1B0F0B",
|
||||
"_@ c #441708",
|
||||
":@ c #57240E",
|
||||
"<@ c #4D4743",
|
||||
"[@ c #FCF7F3",
|
||||
"}@ c #E5AA70",
|
||||
"|@ c #E2A05E",
|
||||
"1@ c #E8AE6B",
|
||||
"2@ c #FADC99",
|
||||
"3@ c #F3C685",
|
||||
"4@ c #D87638",
|
||||
"5@ c #D77132",
|
||||
"6@ c #D87233",
|
||||
"7@ c #D97334",
|
||||
"8@ c #BF642D",
|
||||
"9@ c #4F1F0D",
|
||||
"0@ c #3A3432",
|
||||
"a@ c #555555",
|
||||
"b@ c #C1C1C1",
|
||||
"c@ c #120000",
|
||||
"d@ c #411608",
|
||||
"e@ c #4D1B09",
|
||||
"f@ c #5C260F",
|
||||
"g@ c #A85A28",
|
||||
"h@ c #D77A3A",
|
||||
"i@ c #CC763A",
|
||||
"j@ c #CE793C",
|
||||
"k@ c #CF7B3D",
|
||||
"l@ c #D07D3F",
|
||||
"m@ c #D78849",
|
||||
"n@ c #FBDD9B",
|
||||
"o@ c #5F553C",
|
||||
"p@ c #1F1F1F",
|
||||
"q@ c #7D5737",
|
||||
"r@ c #D79154",
|
||||
"s@ c #DD9352",
|
||||
"t@ c #804724",
|
||||
"u@ c #733F21",
|
||||
"v@ c #E3A66E",
|
||||
"w@ c #E19C5B",
|
||||
"x@ c #ECB876",
|
||||
"y@ c #EBAE6F",
|
||||
"z@ c #D46B30",
|
||||
"A@ c #D56C30",
|
||||
"B@ c #D66E31",
|
||||
"C@ c #D77032",
|
||||
"D@ c #994B20",
|
||||
"E@ c #46190A",
|
||||
"F@ c #312825",
|
||||
"G@ c #6C6C6C",
|
||||
"H@ c #D2D2D2",
|
||||
"I@ c #B68F90",
|
||||
"J@ c #D7BDBE",
|
||||
"K@ c #060200",
|
||||
"L@ c #331106",
|
||||
"M@ c #8B3712",
|
||||
"N@ c #68270D",
|
||||
"O@ c #59240E",
|
||||
"P@ c #A35829",
|
||||
"Q@ c #CF7B3E",
|
||||
"R@ c #D17D3F",
|
||||
"S@ c #F1C584",
|
||||
"T@ c #7F7250",
|
||||
"U@ c #0D0804",
|
||||
"V@ c #5E3C20",
|
||||
"W@ c #B57642",
|
||||
"X@ c #DA8E4D",
|
||||
"Y@ c #DB8F4F",
|
||||
"Z@ c #DC9150",
|
||||
"`@ c #804725",
|
||||
" # c #D58F51",
|
||||
".# c #E19D5C",
|
||||
"+# c #F2C886",
|
||||
"@# c #FBDC99",
|
||||
"## c #DD8D51",
|
||||
"$# c #D1682E",
|
||||
"%# c #D2692E",
|
||||
"&# c #D36B2F",
|
||||
"*# c #CC672E",
|
||||
"=# c #7D3918",
|
||||
"-# c #4D1A09",
|
||||
";# c #290E05",
|
||||
"># c #321A11",
|
||||
",# c #3B3B3B",
|
||||
"'# c #3D3D3D",
|
||||
")# c #1E0A03",
|
||||
"!# c #903A13",
|
||||
"~# c #873511",
|
||||
"{# c #63250C",
|
||||
"]# c #693015",
|
||||
"^# c #AC5F2E",
|
||||
"/# c #CD783B",
|
||||
"(# c #D38142",
|
||||
"_# c #DD9656",
|
||||
":# c #D68647",
|
||||
"<# c #D88848",
|
||||
"[# c #D88A49",
|
||||
"}# c #D98C4C",
|
||||
"|# c #DC9151",
|
||||
"1# c #DD9453",
|
||||
"2# c #E29F5E",
|
||||
"3# c #F8D592",
|
||||
"4# c #F4CB8A",
|
||||
"5# c #D67B41",
|
||||
"6# c #CD642C",
|
||||
"7# c #CF662D",
|
||||
"8# c #D0672E",
|
||||
"9# c #C15F2A",
|
||||
"0# c #632810",
|
||||
"a# c #7D3817",
|
||||
"b# c #C4642C",
|
||||
"c# c #873F1A",
|
||||
"d# c #7C2B0F",
|
||||
"e# c #8D401A",
|
||||
"f# c #290801",
|
||||
"g# c #803310",
|
||||
"h# c #823311",
|
||||
"i# c #5A210B",
|
||||
"j# c #6A3015",
|
||||
"k# c #BC6C35",
|
||||
"l# c #D37F40",
|
||||
"m# c #D58344",
|
||||
"n# c #D58445",
|
||||
"o# c #D88948",
|
||||
"p# c #D88B4A",
|
||||
"q# c #DA8F4E",
|
||||
"r# c #DB904F",
|
||||
"s# c #E4A665",
|
||||
"t# c #FCDF9C",
|
||||
"u# c #EAB274",
|
||||
"v# c #CD6831",
|
||||
"w# c #CB612A",
|
||||
"x# c #CC632B",
|
||||
"y# c #AD5324",
|
||||
"z# c #511D0B",
|
||||
"A# c #763013",
|
||||
"B# c #CB642C",
|
||||
"C# c #C9612B",
|
||||
"D# c #AC4A1E",
|
||||
"E# c #9D4F22",
|
||||
"F# c #1B0500",
|
||||
"G# c #180902",
|
||||
"H# c #50200A",
|
||||
"I# c #7E3110",
|
||||
"J# c #7B3D1C",
|
||||
"K# c #BE6E36",
|
||||
"L# c #D58546",
|
||||
"M# c #D78748",
|
||||
"N# c #D88949",
|
||||
"O# c #D98B4A",
|
||||
"P# c #ECB977",
|
||||
"Q# c #DE975C",
|
||||
"R# c #C75D27",
|
||||
"S# c #C85F28",
|
||||
"T# c #CA6029",
|
||||
"U# c #93421C",
|
||||
"V# c #622911",
|
||||
"W# c #943412",
|
||||
"X# c #BE5825",
|
||||
"Y# c #D56E31",
|
||||
"Z# c #A55525",
|
||||
"`# c #310802",
|
||||
" $ c #240601",
|
||||
".$ c #150500",
|
||||
"+$ c #200C03",
|
||||
"@$ c #702D0E",
|
||||
"#$ c #752D0F",
|
||||
"$$ c #511D0A",
|
||||
"%$ c #82401D",
|
||||
"&$ c #C8773B",
|
||||
"*$ c #D68546",
|
||||
"=$ c #FADB99",
|
||||
"-$ c #D27C44",
|
||||
";$ c #C55B25",
|
||||
">$ c #C65C26",
|
||||
",$ c #C05B26",
|
||||
"'$ c #793315",
|
||||
")$ c #060606",
|
||||
"!$ c #2E2E2E",
|
||||
"~$ c #EEE1DB",
|
||||
"{$ c #F8EBE4",
|
||||
"]$ c #D5723B",
|
||||
"^$ c #A45425",
|
||||
"/$ c #260D04",
|
||||
"($ c #2C0F05",
|
||||
"_$ c #0C0501",
|
||||
":$ c #070402",
|
||||
"<$ c #3C1807",
|
||||
"[$ c #883611",
|
||||
"}$ c #8D4B24",
|
||||
"|$ c #CA783C",
|
||||
"1$ c #D58444",
|
||||
"2$ c #DD9757",
|
||||
"3$ c #F6D290",
|
||||
"4$ c #F2C989",
|
||||
"5$ c #C55F2B",
|
||||
"6$ c #C25824",
|
||||
"7$ c #C35925",
|
||||
"8$ c #AF4F21",
|
||||
"9$ c #60250E",
|
||||
"0$ c #1C0A04",
|
||||
"a$ c #0A0A0A",
|
||||
"b$ c #87595A",
|
||||
"c$ c #F2D8C9",
|
||||
"d$ c #D0672D",
|
||||
"e$ c #A35224",
|
||||
"f$ c #0D0200",
|
||||
"g$ c #0F0501",
|
||||
"h$ c #282828",
|
||||
"i$ c #070707",
|
||||
"j$ c #0D0501",
|
||||
"k$ c #56220B",
|
||||
"l$ c #6C290E",
|
||||
"m$ c #9B5126",
|
||||
"n$ c #E4A766",
|
||||
"o$ c #FBDE9B",
|
||||
"p$ c #E5AD71",
|
||||
"q$ c #BE5322",
|
||||
"r$ c #BF5523",
|
||||
"s$ c #C15623",
|
||||
"t$ c #9D451C",
|
||||
"u$ c #4C1B0A",
|
||||
"v$ c #100704",
|
||||
"w$ c #3F2C2C",
|
||||
"x$ c #AB9898",
|
||||
"y$ c #EAE3E3",
|
||||
"z$ c #F7EAE3",
|
||||
"A$ c #CE662D",
|
||||
"B$ c #A25123",
|
||||
"C$ c #878787",
|
||||
"D$ c #7F7F7F",
|
||||
"E$ c #DFDFDF",
|
||||
"F$ c #425F51",
|
||||
"G$ c #3E4F47",
|
||||
"H$ c #121212",
|
||||
"I$ c #1F0C03",
|
||||
"J$ c #58210D",
|
||||
"K$ c #DEB67D",
|
||||
"L$ c #D38750",
|
||||
"M$ c #BB5020",
|
||||
"N$ c #BC5221",
|
||||
"O$ c #853816",
|
||||
"P$ c #3F1507",
|
||||
"Q$ c #0A0402",
|
||||
"R$ c #0E0E0E",
|
||||
"S$ c #616161",
|
||||
"T$ c #B69C9D",
|
||||
"U$ c #893336",
|
||||
"V$ c #DB926C",
|
||||
"W$ c #7C3617",
|
||||
"X$ c #EAEDEB",
|
||||
"Y$ c #ACB7B2",
|
||||
"Z$ c #8E9994",
|
||||
"`$ c #424E48",
|
||||
" % c #595959",
|
||||
".% c #130602",
|
||||
"+% c #100601",
|
||||
"@% c #401907",
|
||||
"#% c #9F411D",
|
||||
"$% c #B84D1E",
|
||||
"%% c #B94F1F",
|
||||
"&% c #B54E20",
|
||||
"*% c #6D2B10",
|
||||
"=% c #160702",
|
||||
"-% c #554338",
|
||||
";% c #787878",
|
||||
">% c #382B24",
|
||||
",% c #97481F",
|
||||
"'% c #C55F29",
|
||||
")% c #723114",
|
||||
"!% c #230B02",
|
||||
"~% c #302A28",
|
||||
"{% c #C2C0BE",
|
||||
"]% c #EEF1F0",
|
||||
"^% c #A1AFA8",
|
||||
"/% c #C4CAC7",
|
||||
"(% c #585858",
|
||||
"_% c #280D05",
|
||||
":% c #361207",
|
||||
"<% c #401708",
|
||||
"[% c #280F04",
|
||||
"}% c #551F09",
|
||||
"|% c #9A3E18",
|
||||
"1% c #B74C1D",
|
||||
"2% c #A4451B",
|
||||
"3% c #5E230D",
|
||||
"4% c #742E12",
|
||||
"5% c #963714",
|
||||
"6% c #883111",
|
||||
"7% c #77290E",
|
||||
"8% c #983814",
|
||||
"9% c #9A3814",
|
||||
"0% c #91421B",
|
||||
"a% c #C96029",
|
||||
"b% c #C25C28",
|
||||
"c% c #5E250E",
|
||||
"d% c #1F0A02",
|
||||
"e% c #0A0200",
|
||||
"f% c #311205",
|
||||
"g% c #B8A8A2",
|
||||
"h% c #82998E",
|
||||
"i% c #CECECE",
|
||||
"j% c #140602",
|
||||
"k% c #3F1608",
|
||||
"l% c #712B0F",
|
||||
"m% c #833311",
|
||||
"n% c #57210B",
|
||||
"o% c #170802",
|
||||
"p% c #250C03",
|
||||
"q% c #6B250C",
|
||||
"r% c #993D17",
|
||||
"s% c #B54A1D",
|
||||
"t% c #A2421A",
|
||||
"u% c #873615",
|
||||
"v% c #9D411A",
|
||||
"w% c #B95020",
|
||||
"x% c #BB5121",
|
||||
"y% c #A9441A",
|
||||
"z% c #9C3A15",
|
||||
"A% c #C05723",
|
||||
"B% c #C45B25",
|
||||
"C% c #C75C27",
|
||||
"D% c #B05122",
|
||||
"E% c #55200C",
|
||||
"F% c #160701",
|
||||
"G% c #9E8075",
|
||||
"H% c #BEBEBE",
|
||||
"I% c #371307",
|
||||
"J% c #6A280D",
|
||||
"K% c #813211",
|
||||
"L% c #803111",
|
||||
"M% c #7F3111",
|
||||
"N% c #7E3011",
|
||||
"O% c #762D0F",
|
||||
"P% c #451A08",
|
||||
"Q% c #360B03",
|
||||
"R% c #7C240B",
|
||||
"S% c #481808",
|
||||
"T% c #983C17",
|
||||
"U% c #782E11",
|
||||
"V% c #B74D1E",
|
||||
"W% c #BD5322",
|
||||
"X% c #B44C1E",
|
||||
"Y% c #B84F20",
|
||||
"Z% c #C35924",
|
||||
"`% c #C45A25",
|
||||
" & c #AE4F20",
|
||||
".& c #461909",
|
||||
"+& c #130600",
|
||||
"@& c #2D1105",
|
||||
"#& c #66260D",
|
||||
"$& c #703D2A",
|
||||
"%& c #8F7165",
|
||||
"&& c #6E341C",
|
||||
"*& c #7D3010",
|
||||
"=& c #7C3010",
|
||||
"-& c #7B2F10",
|
||||
";& c #7A2F10",
|
||||
">& c #792E10",
|
||||
",& c #782E10",
|
||||
"'& c #6A280E",
|
||||
")& c #2F1205",
|
||||
"!& c #331206",
|
||||
"~& c #541E0B",
|
||||
"{& c #843313",
|
||||
"]& c #AE451A",
|
||||
"^& c #B1471B",
|
||||
"/& c #BF5422",
|
||||
"(& c #9C451C",
|
||||
"_& c #867872",
|
||||
":& c #A68574",
|
||||
"<& c #3F1B0F",
|
||||
"[& c #0C0300",
|
||||
"}& c #2C1005",
|
||||
"|& c #501D0A",
|
||||
"1& c #772D10",
|
||||
"2& c #752C0F",
|
||||
"3& c #742C0F",
|
||||
"4& c #6F2A0E",
|
||||
"5& c #722B0F",
|
||||
"6& c #511E0A",
|
||||
"7& c #6E270E",
|
||||
"8& c #A93F18",
|
||||
"9& c #B0461B",
|
||||
"0& c #B4491C",
|
||||
"a& c #B54A1C",
|
||||
"b& c #BC5121",
|
||||
"c& c #9A431B",
|
||||
"d& c #3B3431",
|
||||
"e& c #E9E9E9",
|
||||
"f& c #838181",
|
||||
"g& c #260400",
|
||||
"h& c #6B280E",
|
||||
"i& c #732B0F",
|
||||
"j& c #712A0F",
|
||||
"k& c #702A0F",
|
||||
"l& c #6F2A0F",
|
||||
"m& c #6E290E",
|
||||
"n& c #5C220C",
|
||||
"o& c #3D1407",
|
||||
"p& c #832F11",
|
||||
"q& c #AD4419",
|
||||
"r& c #AF451A",
|
||||
"s& c #B2481B",
|
||||
"t& c #B84E1F",
|
||||
"u& c #8C3C18",
|
||||
"v& c #CACACA",
|
||||
"w& c #454545",
|
||||
"x& c #371506",
|
||||
"y& c #702A0E",
|
||||
"z& c #6D290E",
|
||||
"A& c #6C280E",
|
||||
"B& c #6A270E",
|
||||
"C& c #69270E",
|
||||
"D& c #3E1507",
|
||||
"E& c #8B3413",
|
||||
"F& c #AE431A",
|
||||
"G& c #B1461B",
|
||||
"H& c #B5491C",
|
||||
"I& c #893816",
|
||||
"J& c #452B1F",
|
||||
"K& c #A3A3A3",
|
||||
"L& c #DEDEE1",
|
||||
"M& c #E6E6E6",
|
||||
"N& c #0F0000",
|
||||
"O& c #090300",
|
||||
"P& c #160801",
|
||||
"Q& c #531F0A",
|
||||
"R& c #461A09",
|
||||
"S& c #545454",
|
||||
"T& c #724C3D",
|
||||
"U& c #68260E",
|
||||
"V& c #67260D",
|
||||
"W& c #66250D",
|
||||
"X& c #65250D",
|
||||
"Y& c #3D1507",
|
||||
"Z& c #863213",
|
||||
"`& c #AC4119",
|
||||
" * c #B0461A",
|
||||
".* c #863514",
|
||||
"+* c #53382D",
|
||||
"@* c #959595",
|
||||
"#* c #C6C6C9",
|
||||
"$* c #4D4F60",
|
||||
"%* c #7F808D",
|
||||
"&* c #404154",
|
||||
"** c #CECED3",
|
||||
"=* c #BEBFC5",
|
||||
"-* c #040100",
|
||||
";* c #0E0500",
|
||||
">* c #270E04",
|
||||
",* c #382F2C",
|
||||
"'* c #6B4638",
|
||||
")* c #64250D",
|
||||
"!* c #63240D",
|
||||
"~* c #62230D",
|
||||
"{* c #401608",
|
||||
"]* c #722A0F",
|
||||
"^* c #AB4018",
|
||||
"/* c #AD421A",
|
||||
"(* c #AF441A",
|
||||
"_* c #7E3B20",
|
||||
":* c #D3D1D1",
|
||||
"<* c #ECECEC",
|
||||
"[* c #5F6170",
|
||||
"}* c #EEEEEF",
|
||||
"|* c #303246",
|
||||
"1* c #969696",
|
||||
"2* c #CCCCCC",
|
||||
"3* c #5B3324",
|
||||
"4* c #61230C",
|
||||
"5* c #60230C",
|
||||
"6* c #5F230C",
|
||||
"7* c #5E220C",
|
||||
"8* c #70290F",
|
||||
"9* c #AA3F18",
|
||||
"0* c #973916",
|
||||
"a* c #301006",
|
||||
"b* c #312117",
|
||||
"c* c #31302F",
|
||||
"d* c #CDCDCD",
|
||||
"e* c #8F909B",
|
||||
"f* c #1E1E1E",
|
||||
"g* c #D2D2D1",
|
||||
"h* c #696969",
|
||||
"i* c #583224",
|
||||
"j* c #5E220B",
|
||||
"k* c #5D220B",
|
||||
"l* c #5C210B",
|
||||
"m* c #6E280F",
|
||||
"n* c #A83E17",
|
||||
"o* c #A43E18",
|
||||
"p* c #561E0C",
|
||||
"q* c #2B0E05",
|
||||
"r* c #505162",
|
||||
"s* c #9F9FA9",
|
||||
"t* c #BCBDC3",
|
||||
"u* c #D6D6D6",
|
||||
"v* c #9D9D9D",
|
||||
"w* c #737373",
|
||||
"x* c #694F45",
|
||||
"y* c #5B200B",
|
||||
"z* c #5A200B",
|
||||
"A* c #591F0B",
|
||||
"B* c #581F0A",
|
||||
"C* c #381306",
|
||||
"D* c #6D270E",
|
||||
"E* c #A63D17",
|
||||
"F* c #993915",
|
||||
"G* c #240500",
|
||||
"H* c #AEAFB7",
|
||||
"I* c #F0F0F0",
|
||||
"J* c #575757",
|
||||
"K* c #CCCCD1",
|
||||
"L* c #D8D7D7",
|
||||
"M* c #A49590",
|
||||
"N* c #561E0A",
|
||||
"O* c #551D0A",
|
||||
"P* c #351206",
|
||||
"Q* c #6B260E",
|
||||
"R* c #A53C16",
|
||||
"S* c #903514",
|
||||
"T* c #8E8E96",
|
||||
"U* c #9B9BA0",
|
||||
"V* c #F5F5F5",
|
||||
"W* c #342721",
|
||||
"X* c #290E04",
|
||||
"Y* c #4F1B09",
|
||||
"Z* c #521C0A",
|
||||
"`* c #511C09",
|
||||
" = c #69250D",
|
||||
".= c #A33B15",
|
||||
"+= c #822F11",
|
||||
"@= c #1D0200",
|
||||
"#= c #838383",
|
||||
"$= c #6F707E",
|
||||
"%= c #030000",
|
||||
"&= c #0B0400",
|
||||
"*= c #140701",
|
||||
"== c #3B1406",
|
||||
"-= c #4E1A09",
|
||||
";= c #311005",
|
||||
">= c #68240C",
|
||||
",= c #802D10",
|
||||
"'= c #050100",
|
||||
")= c #919191",
|
||||
"!= c #010000",
|
||||
"~= c #0A0300",
|
||||
"{= c #1D0A02",
|
||||
"]= c #270D04",
|
||||
"^= c #351005",
|
||||
"/= c #100000",
|
||||
"(= c #111111",
|
||||
"_= c #0E0501",
|
||||
":= c #0E0400",
|
||||
"<= c #070000",
|
||||
"[= c #909090",
|
||||
" ",
|
||||
" . + @ ",
|
||||
" # $ % & * = - ; > , # ' ",
|
||||
" ) ! ~ ~ ~ ~ { ] ^ / ( _ : > < [ } | + 1 1 ' ' ",
|
||||
" 2 3 4 ~ ~ ~ ~ ~ 5 6 7 8 9 0 a b c d e f g h i j ~ ~ 4 3 k ",
|
||||
" l m ~ n o p q r ~ 4 s t u v w x y z A B C D E F G H 7 I J K L ",
|
||||
" M N O P Q [ ~ I R S T U V W w x y X Y Z ` ...+.@.#.$.%. ",
|
||||
" D &.*.N p r ~ I J =.-.;.>.,.'.).!.~.{.].^.Z /.(._.:...<. ",
|
||||
" [.}.|.1.2.3.~ [ 4.5.7 6.7.8.f 9.0.a.b.c.d.e.f.^.Z g.h.i.j.k. ",
|
||||
" l.m.n.o.p.q.r.s.t.u.v.R S w.L x.y.z.! ~ ~ A.~ B.C.D.E.F.G.H.I.J. ",
|
||||
" K.L.M.N.O.P.N 4 Q.R.S.T.U.V.W.X.Y.Z.`. +.+++ +~ @+y z #+$+%+&+*+J. ",
|
||||
" =+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+++1+2+3+4+5+w x 6+7+8+9+0+a+J. ",
|
||||
" l.b+c+d+e+f+>+g+h+i+j+k+l+r.m+n+l o+p+(+q+~ ~ r+A.s+j+t+u+v+w+x+y+z+A+B+J. ",
|
||||
" K.C+D+E+F+G+e+f+H+I+J+K+L+M+N+O+P+Q+X.R+S+T+U+N ~ V+W+X+Y+Z+`+ @.@+@@@#@$@%@ ' ' ' ",
|
||||
" &@*@=@D+-@;@F+G+>@,@'@)@!@~@{@]@^@/@Q+R+(@_@j+:@<@[@}@|@1@2@3@4@5@6@7@8@9@0@a@b@| | t.",
|
||||
" c@d@e@f@g@h@i@;@j@k@l@,@'@m@n@o@R+]@p@X.q@r@s@t@j+u@v@w@x@w+y@z@A@B@C@D@E@F@G@H@I@J@| ' ",
|
||||
" K@L@M@N@j+O@P@i@;@j@Q@R@,@'@m@S@T@U@V@W@X@Y@Z@s@`@ #.#+#@###$#%#&#*#=#-#;#>#F ,#'#R+x. ",
|
||||
" K@)#!#!#~#{#j+]#^#/#j@e+f+>+(#'+_#:#<#[#}#X@Y@|#1#2#3#4#5#6#7#8#9#0#a#b#c#d#e#L@ ",
|
||||
" K@f#g#!#!#!#h#i#j+j#k#d+e+f+l#(#m#n#:#o#p#1.q#r#s#t#u#v#w#x#6#y#z#A#B#C#B@D#E#J. ",
|
||||
" c@F#G#H#!#!#!#!#I#i#j+J#K#e+f+'@)@m#L#M#N#O#1.P#w+Q#R#S#T#w#U#,.V#W#X#&#A@Y#Z#J. ",
|
||||
" `# $.$+$@$!#!#!#!##$$$j+%$&$,@'@)@m#*$M#q#+#=$-$;$>$R#,$'$;#)$!$~${$]$&#A@^$J. ",
|
||||
" `#/$($_$:$<$[$!#!#!#!##$$$i+}$|$'@)@1$2$3$4$5$6$7$;$8$9$0$a$W.b$N c$d$%#&#e$J. ",
|
||||
" f$g$_+#.h$i$j$k$!#!#!#!#M@l$e@i+m$R@n$o$p$q$r$s$6$t$u$v$X.w$x$y$z$6#A$d$%#B$J. ",
|
||||
" C$D$0.N E$F$G$p+n+H$I$@$!#!#!#!#M@l$j+J$K$L$M$N$q$r$O$P$Q$R$S$T$U$~ V$x#6#A$d$W$($ ",
|
||||
" k . 4 ~ X$Y$Z$`$ %L .%+%@%[$!#!#!#!#~#j+#%$%%%M$&%*%P$=%,.-%F ;%D$>%,%w#x#'%)%!% ",
|
||||
" ~%{%]%++^%/%(%_%:%<%[%G#}%!#!#!#!#j+|%1%$%2%3%4%5%6%7%W#8%9%0%R#S#a%b%c%d% ",
|
||||
" e%f%g%~ h%i%j%:%k%l%m%n%o%p%q%!#!#j+r%s%t%u%v%M$w%x%y%8%z%A%B%>$C%D%E%F% ",
|
||||
" e%/$:%G%1+H%I%J%K%L%M%N%O%P%+%Q%R%S%T%U%U%1%V%%%M$N$W%X%Y%6$Z%`% &.&+& ",
|
||||
" K@@&#&J.$&%&&&N%*&=&-&;&>&,&'&)&.$!&~&{&]&^&1%V%%%M$N$W%/&(&_&:&<&[& ",
|
||||
" K@}&M%l%|&|&#&;&>&,&1&O%2&3&4&5&6&L@7&8&9&0&a&1%V%%%M$b&c&d&T.e&f&' ",
|
||||
" g&-&;&>&3&h&O%2&3&i&5&j&k&l&m&n&o&p&q&r&s&0&a&1%V%t&u&d&# E$~ R v&< S$w& ",
|
||||
" +%x&y&2&3&i&h&j&k&l&m&z&A&h&B&C&D&E&F&r&G&s&0&H&I&J&p+K&-.8 L&~ ~ ~ M&| 3 . $.1 ",
|
||||
" N&O&P&Q&k&R&S&T&A&h&B&C&U&V&W&X&Y&Z&`&F&r& *.*+*S&@*q+#*$*%*&***=*~ ~ ~ ~ ~ ~ S. ",
|
||||
" R+R+-*;*>*,*@*}+'*V&W&X&)*!*!*~*{*]*^*`&/*(*_*m+. :*<*[*%*&*=*&*L&}*|*~ ~ ~ ! ",
|
||||
" R+R+R+f$1*2*O+Z.3*!*~*4*5*6*7*Y&8*9*^*`&0*:%a*b*c*d*=*e*=*&*}*}*&***~ ~ 4 f ",
|
||||
" R+R+f*8 g*2*7.h*i*7*j*k*l*l*J.m*n*9*^*o*p*q*[&R+R+D$~ r*}*~ [*s*~ ~ ~ , ",
|
||||
" R+f*i%L&t*-.u*v*w*x*y*z*A*B*C*D*E*n*9*F*_@G*R+R+R+R+!$i%~ e*e*H*~ ~ I*J* ",
|
||||
" R+R+R+R$3.0.~ ~ }*&*K*-.u*L*M*-#N*O*O*P*Q*R*E*S*_@[& R+R+R+R+D$~ %*s*~ 4 $. ",
|
||||
" l | ~ ~ ~ ~ ~ ~ T*%*L&&*U*-.V*W*X*Y*Z*`*L@ =.=+=J.@= R+R+R+!$i%~ e&$. ",
|
||||
" i$#=I*~ e***~ =***=*[*H*$=8 K&%=&=*===-=;=>=,=L@'= R+R+R$)=w. ",
|
||||
" R+o+$.4 }*$=s*L&&*[*s*s*~ ! l R+R+!=~={=]=C*^=/= R+R+(= ",
|
||||
" R+R+l # $ ~ s*$=L&s*L&~ e&K R+R+R+R+_=:=<= ",
|
||||
" R+R+s.[=e&~ **e*~ ~ | ) R+R+R+ ",
|
||||
" R+R+i$3.! ~ d*4 , ' ",
|
||||
" R+R+s.# J ) o+ ",
|
||||
" R+R+X.'# ",
|
||||
" ",
|
||||
" "};
|
||||
134
wrlib/color.c
Normal file
134
wrlib/color.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* color.c - color stuff (rgb -> hsv convertion etc.)
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1998 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
|
||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
|
||||
#define MIN3(a,b,c) MIN(MIN(a,b), c)
|
||||
#define MAX3(a,b,c) MAX(MAX(a,b), c)
|
||||
|
||||
|
||||
void
|
||||
RHSVtoRGB(RHSVColor *hsv, RColor *rgb)
|
||||
{
|
||||
int h = hsv->hue % 360;
|
||||
int s = hsv->saturation;
|
||||
int v = hsv->value;
|
||||
int i, f;
|
||||
int p, q, t;
|
||||
|
||||
if (s == 0) {
|
||||
rgb->red = rgb->green = rgb->blue = v;
|
||||
return;
|
||||
}
|
||||
i = h / 60;
|
||||
f = h % 60;
|
||||
p = v * (255 - s) / 255;
|
||||
q = v * (255 - s * f / 60) / 255;
|
||||
t = v * (255 - s * (60 - f) / 60) / 255;
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
rgb->red = v;
|
||||
rgb->green = t;
|
||||
rgb->blue = p;
|
||||
break;
|
||||
case 1:
|
||||
rgb->red = q;
|
||||
rgb->green = v;
|
||||
rgb->blue = p;
|
||||
break;
|
||||
case 2:
|
||||
rgb->red = p;
|
||||
rgb->green = v;
|
||||
rgb->blue = t;
|
||||
break;
|
||||
case 3:
|
||||
rgb->red = p;
|
||||
rgb->green = q;
|
||||
rgb->blue = v;
|
||||
break;
|
||||
case 4:
|
||||
rgb->red = t;
|
||||
rgb->green = p;
|
||||
rgb->blue = v;
|
||||
break;
|
||||
case 5:
|
||||
rgb->red = v;
|
||||
rgb->green = p;
|
||||
rgb->blue = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RRGBtoHSV(RColor *rgb, RHSVColor *hsv)
|
||||
{
|
||||
int h, s, v;
|
||||
int max = MAX3(rgb->red, rgb->green, rgb->blue);
|
||||
int min = MIN3(rgb->red, rgb->green, rgb->blue);
|
||||
|
||||
v = max;
|
||||
|
||||
if (max == 0)
|
||||
s = 0;
|
||||
else
|
||||
s = (max - min) * 255 / max;
|
||||
|
||||
if (s == 0)
|
||||
h = 0;
|
||||
else {
|
||||
int rc, gc, bc;
|
||||
|
||||
rc = (max - rgb->red) * 255 / (max - min);
|
||||
gc = (max - rgb->green) * 255 / (max - min);
|
||||
bc = (max - rgb->blue) * 255 / (max - min);
|
||||
|
||||
if (rgb->red == max) {
|
||||
h = ((bc - gc) * 60 / 255);
|
||||
} else if (rgb->green == max) {
|
||||
h = 2*60 + ((rc - bc) * 60 / 255);
|
||||
} else {
|
||||
h = 4*60 + ((gc - rc) * 60 / 255);
|
||||
}
|
||||
if (h < 0)
|
||||
h += 360;
|
||||
}
|
||||
|
||||
hsv->hue = h;
|
||||
hsv->saturation = s;
|
||||
hsv->value = v;
|
||||
}
|
||||
105
wrlib/configure.in
Normal file
105
wrlib/configure.in
Normal file
@@ -0,0 +1,105 @@
|
||||
dnl
|
||||
dnl autoconf input for WRaster library
|
||||
dnl
|
||||
|
||||
AC_INIT(raster.c)
|
||||
AM_INIT_AUTOMAKE(wrlib, 0.3)
|
||||
|
||||
|
||||
CFLAGS="$CFLAGS -O2"
|
||||
|
||||
dnl Checks for programs.
|
||||
dnl ===================
|
||||
AC_PROG_CC
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
|
||||
|
||||
dnl Checks for library functions.
|
||||
dnl ============================
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_ALLOCA
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
XCFLAGS="$X_CFLAGS"
|
||||
|
||||
_XLIBS="$X_LIBS $X_EXTRA_LIBS -lX11"
|
||||
XLIBS="$X_EXTRA_LIBS -lX11"
|
||||
|
||||
XLFLAGS=$X_LIBS
|
||||
|
||||
AC_SUBST(XCFLAGS)
|
||||
AC_SUBST(XLFLAGS)
|
||||
|
||||
dnl Pixmap Support
|
||||
dnl ==============
|
||||
xpm=yes
|
||||
AC_ARG_ENABLE(xpm,
|
||||
[ --disable-xpm disable XPM support through libXpm],
|
||||
xpm=$enableval, xpm=yes)
|
||||
|
||||
GFXFLAGS=""
|
||||
GFXLIBS=""
|
||||
|
||||
if test "$xpm" = yes; then
|
||||
AC_CHECK_LIB(Xpm, XpmCreatePixmapFromData,
|
||||
[GFXFLAGS=-DUSE_XPM GFXLIBS=-lXpm], ,$_XLIBS)
|
||||
fi
|
||||
|
||||
|
||||
dnl test for zlib
|
||||
dnl =============
|
||||
|
||||
AC_CHECK_LIB(z, gzread, zlib=yes, zlib=no)
|
||||
|
||||
|
||||
dnl PNG Support
|
||||
dnl ===========
|
||||
png=yes
|
||||
AC_ARG_ENABLE(png,
|
||||
[ --disable-png disable PNG support through libpng],
|
||||
png=$enableval, png=yes)
|
||||
|
||||
if test "$png" = yes; then
|
||||
if test "$zlib" = yes; then
|
||||
AC_CHECK_LIB(png, png_get_valid, [GFXFLAGS="$GFXFLAGS -DUSE_PNG"
|
||||
GFXLIBS="$GFXLIBS -lpng -lz"], , -lz -lm)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl TIFF Support
|
||||
dnl ============
|
||||
tif=yes
|
||||
AC_ARG_ENABLE(tif,
|
||||
[ --disable-tiff disable use of TIFF images through libtiff],
|
||||
tif=$enableval, tif=yes)
|
||||
|
||||
if test "$tif" = yes; then
|
||||
AC_CHECK_LIB(tiff, TIFFGetVersion,
|
||||
[GFXFLAGS="$GFXFLAGS -DUSE_TIFF" GFXLIBS="$GFXLIBS -ltiff"],, -lm)
|
||||
fi
|
||||
|
||||
|
||||
AC_SUBST(GFXFLAGS)
|
||||
AC_SUBST(GFXLIBS)
|
||||
|
||||
AC_SUBST(XLIBS)
|
||||
|
||||
|
||||
if test "${prefix}" = "NONE"; then
|
||||
prefix="/usr/local"
|
||||
fi
|
||||
if test "${exec_prefix}" = "NONE"; then
|
||||
exec_prefix=$prefix
|
||||
fi
|
||||
|
||||
|
||||
AC_C_CONST
|
||||
|
||||
AC_OUTPUT(Makefile config.h)
|
||||
|
||||
557
wrlib/context.c
Normal file
557
wrlib/context.c
Normal file
@@ -0,0 +1,557 @@
|
||||
/* context.c - X context management
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
static Bool bestContext(Display *dpy, int screen_number, RContext *context);
|
||||
|
||||
static RContextAttributes DEFAULT_CONTEXT_ATTRIBS = {
|
||||
RC_UseSharedMemory|RC_RenderMode|RC_ColorsPerChannel, /* flags */
|
||||
RM_DITHER, /* render_mode */
|
||||
4, /* colors_per_channel */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
True /* use_shared_memory */
|
||||
};
|
||||
|
||||
|
||||
static XColor*
|
||||
allocatePseudoColor(RContext *ctx)
|
||||
{
|
||||
XColor *colors;
|
||||
XColor avcolors[256];
|
||||
int avncolors;
|
||||
int i, ncolors, r, g, b;
|
||||
int retries;
|
||||
int cpc = ctx->attribs->colors_per_channel;
|
||||
|
||||
ncolors = cpc * cpc * cpc;
|
||||
|
||||
if ( ncolors > (1<<ctx->depth) ) {
|
||||
/* reduce colormap size */
|
||||
cpc = ctx->attribs->colors_per_channel = 1<<((int)ctx->depth/3);
|
||||
ncolors = cpc * cpc * cpc;
|
||||
}
|
||||
|
||||
if (cpc < 2 || ncolors > (1<<ctx->depth)) {
|
||||
sprintf(RErrorString, "invalid colormap size %i", cpc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
colors = malloc(sizeof(XColor)*ncolors);
|
||||
if (!colors) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
i=0;
|
||||
|
||||
if ((ctx->attribs->flags & RC_GammaCorrection) && ctx->attribs->rgamma > 0
|
||||
&& ctx->attribs->ggamma > 0 && ctx->attribs->bgamma > 0) {
|
||||
double rg, gg, bg;
|
||||
double tmp;
|
||||
|
||||
/* do gamma correction */
|
||||
rg = 1.0/ctx->attribs->rgamma;
|
||||
gg = 1.0/ctx->attribs->ggamma;
|
||||
bg = 1.0/ctx->attribs->bgamma;
|
||||
for (r=0; r<cpc; r++) {
|
||||
for (g=0; g<cpc; g++) {
|
||||
for (b=0; b<cpc; b++) {
|
||||
|
||||
colors[i].red=(r*0xffff) / (cpc-1);
|
||||
colors[i].green=(g*0xffff) / (cpc-1);
|
||||
colors[i].blue=(b*0xffff) / (cpc-1);
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
|
||||
tmp = (double)colors[i].red / 65536.0;
|
||||
colors[i].red = (unsigned short)(65536.0*pow(tmp, rg));
|
||||
|
||||
tmp = (double)colors[i].green / 65536.0;
|
||||
colors[i].green = (unsigned short)(65536.0*pow(tmp, gg));
|
||||
|
||||
tmp = (double)colors[i].blue / 65536.0;
|
||||
colors[i].blue = (unsigned short)(65536.0*pow(tmp, bg));
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (r=0; r<cpc; r++) {
|
||||
for (g=0; g<cpc; g++) {
|
||||
for (b=0; b<cpc; b++) {
|
||||
colors[i].red=(r*0xffff) / (cpc-1);
|
||||
colors[i].green=(g*0xffff) / (cpc-1);
|
||||
colors[i].blue=(b*0xffff) / (cpc-1);
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* try to allocate the colors */
|
||||
for (i=0; i<ncolors; i++) {
|
||||
if (!XAllocColor(ctx->dpy, ctx->cmap, &(colors[i]))) {
|
||||
colors[i].flags = 0; /* failed */
|
||||
} else {
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
}
|
||||
/* try to allocate close values for the colors that couldn't
|
||||
* be allocated before */
|
||||
avncolors = (1<<ctx->depth>256 ? 256 : 1<<ctx->depth);
|
||||
for (i=0; i<avncolors; i++) avcolors[i].pixel = i;
|
||||
|
||||
XQueryColors(ctx->dpy, ctx->cmap, avcolors, avncolors);
|
||||
|
||||
for (i=0; i<ncolors; i++) {
|
||||
if (colors[i].flags==0) {
|
||||
int j;
|
||||
unsigned long cdiff=0xffffffff, diff;
|
||||
unsigned long closest=0;
|
||||
|
||||
retries = 2;
|
||||
|
||||
while (retries--) {
|
||||
/* find closest color */
|
||||
for (j=0; j<avncolors; j++) {
|
||||
r = (colors[i].red - avcolors[i].red)>>8;
|
||||
g = (colors[i].green - avcolors[i].green)>>8;
|
||||
b = (colors[i].blue - avcolors[i].blue)>>8;
|
||||
diff = r*r + g*g + b*b;
|
||||
if (diff<cdiff) {
|
||||
cdiff = diff;
|
||||
closest = j;
|
||||
}
|
||||
}
|
||||
/* allocate closest color found */
|
||||
colors[i].red = avcolors[closest].red;
|
||||
colors[i].green = avcolors[closest].green;
|
||||
colors[i].blue = avcolors[closest].blue;
|
||||
if (XAllocColor(ctx->dpy, ctx->cmap, &colors[i])) {
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
break; /* succeeded, don't need to retry */
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("close color allocation failed. Retrying...\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
static XColor*
|
||||
allocateGrayScale(RContext *ctx)
|
||||
{
|
||||
XColor *colors;
|
||||
XColor avcolors[256];
|
||||
int avncolors;
|
||||
int i, ncolors, r, g, b;
|
||||
int retries;
|
||||
int cpc = ctx->attribs->colors_per_channel;
|
||||
|
||||
ncolors = cpc * cpc * cpc;
|
||||
|
||||
if (ctx->vclass == StaticGray) {
|
||||
/* we might as well use all grays */
|
||||
ncolors = 1<<ctx->depth;
|
||||
} else {
|
||||
if ( ncolors > (1<<ctx->depth) ) {
|
||||
/* reduce colormap size */
|
||||
cpc = ctx->attribs->colors_per_channel = 1<<((int)ctx->depth/3);
|
||||
ncolors = cpc * cpc * cpc;
|
||||
}
|
||||
|
||||
if (cpc < 2 || ncolors > (1<<ctx->depth)) {
|
||||
sprintf(RErrorString, "invalid colormap size %i", cpc);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ncolors>=256 && ctx->vclass==StaticGray) {
|
||||
/* don't need dithering for 256 levels of gray in StaticGray visual */
|
||||
ctx->attribs->render_mode = RM_MATCH;
|
||||
}
|
||||
|
||||
colors = malloc(sizeof(XColor)*ncolors);
|
||||
if (!colors) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return False;
|
||||
}
|
||||
for (i=0; i<ncolors; i++) {
|
||||
colors[i].red=(i*0xffff) / (ncolors-1);
|
||||
colors[i].green=(i*0xffff) / (ncolors-1);
|
||||
colors[i].blue=(i*0xffff) / (ncolors-1);
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
/* try to allocate the colors */
|
||||
for (i=0; i<ncolors; i++) {
|
||||
#ifdef DEBUG
|
||||
printf("trying:%x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue);
|
||||
#endif
|
||||
if (!XAllocColor(ctx->dpy, ctx->cmap, &(colors[i]))) {
|
||||
colors[i].flags = 0; /* failed */
|
||||
#ifdef DEBUG
|
||||
printf("failed:%x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue);
|
||||
#endif
|
||||
} else {
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
#ifdef DEBUG
|
||||
printf("success:%x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* try to allocate close values for the colors that couldn't
|
||||
* be allocated before */
|
||||
avncolors = (1<<ctx->depth>256 ? 256 : 1<<ctx->depth);
|
||||
for (i=0; i<avncolors; i++) avcolors[i].pixel = i;
|
||||
|
||||
XQueryColors(ctx->dpy, ctx->cmap, avcolors, avncolors);
|
||||
|
||||
for (i=0; i<ncolors; i++) {
|
||||
if (colors[i].flags==0) {
|
||||
int j;
|
||||
unsigned long cdiff=0xffffffff, diff;
|
||||
unsigned long closest=0;
|
||||
|
||||
retries = 2;
|
||||
|
||||
while (retries--) {
|
||||
/* find closest color */
|
||||
for (j=0; j<avncolors; j++) {
|
||||
r = (colors[i].red - avcolors[i].red)>>8;
|
||||
g = (colors[i].green - avcolors[i].green)>>8;
|
||||
b = (colors[i].blue - avcolors[i].blue)>>8;
|
||||
diff = r*r + g*g + b*b;
|
||||
if (diff<cdiff) {
|
||||
cdiff = diff;
|
||||
closest = j;
|
||||
}
|
||||
}
|
||||
/* allocate closest color found */
|
||||
#ifdef DEBUG
|
||||
printf("best match:%x,%x,%x => %x,%x,%x\n",colors[i].red,colors[i].green,colors[i].blue,avcolors[closest].red,avcolors[closest].green,avcolors[closest].blue);
|
||||
#endif
|
||||
colors[i].red = avcolors[closest].red;
|
||||
colors[i].green = avcolors[closest].green;
|
||||
colors[i].blue = avcolors[closest].blue;
|
||||
if (XAllocColor(ctx->dpy, ctx->cmap, &colors[i])) {
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
break; /* succeeded, don't need to retry */
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("close color allocation failed. Retrying...\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
mygetenv(char *var, int scr)
|
||||
{
|
||||
char *p;
|
||||
char varname[64];
|
||||
|
||||
if (scr==0) {
|
||||
p = getenv(var);
|
||||
}
|
||||
if (scr!=0 || !p) {
|
||||
sprintf(varname, "%s%i", var, scr);
|
||||
p = getenv(var);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gatherconfig(RContext *context, int screen_n)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = mygetenv("WRASTER_GAMMA", screen_n);
|
||||
if (ptr) {
|
||||
float g1,g2,g3;
|
||||
if (sscanf(ptr, "%f/%f/%f", &g1, &g2, &g3)!=3
|
||||
|| g1<=0.0 || g2<=0.0 || g3<=0.0) {
|
||||
printf("wrlib: invalid value(s) for gamma correction \"%s\"\n",
|
||||
ptr);
|
||||
} else {
|
||||
context->attribs->flags |= RC_GammaCorrection;
|
||||
context->attribs->rgamma = g1;
|
||||
context->attribs->ggamma = g2;
|
||||
context->attribs->bgamma = g3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
getColormap(RContext *context, int screen_number)
|
||||
{
|
||||
Colormap cmap = None;
|
||||
XStandardColormap *cmaps;
|
||||
int ncmaps, i;
|
||||
|
||||
if (XGetRGBColormaps(context->dpy,
|
||||
RootWindow(context->dpy, screen_number),
|
||||
&cmaps, &ncmaps, XA_RGB_DEFAULT_MAP)) {
|
||||
for (i=0; i<ncmaps; ++i) {
|
||||
if (cmaps[i].visualid == context->visual->visualid) {
|
||||
cmap = cmaps[i].colormap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree(cmaps);
|
||||
}
|
||||
if (cmap == None) {
|
||||
XColor color;
|
||||
|
||||
cmap = XCreateColormap(context->dpy,
|
||||
RootWindow(context->dpy, screen_number),
|
||||
context->visual, AllocNone);
|
||||
|
||||
color.red = color.green = color.blue = 0;
|
||||
XAllocColor(context->dpy, cmap, &color);
|
||||
context->black = color.pixel;
|
||||
|
||||
color.red = color.green = color.blue = 0xffff;
|
||||
XAllocColor(context->dpy, cmap, &color);
|
||||
context->white = color.pixel;
|
||||
}
|
||||
context->cmap = cmap;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
count_offset(unsigned long mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
i=0;
|
||||
while ((mask & 1)==0) {
|
||||
i++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
RContext*
|
||||
RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
||||
{
|
||||
RContext *context;
|
||||
XGCValues gcv;
|
||||
|
||||
|
||||
RErrorString[0]=0;
|
||||
context = malloc(sizeof(RContext));
|
||||
if (!context) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
memset(context, 0, sizeof(RContext));
|
||||
|
||||
context->dpy = dpy;
|
||||
|
||||
context->screen_number = screen_number;
|
||||
|
||||
context->attribs = malloc(sizeof(RContextAttributes));
|
||||
if (!context->attribs) {
|
||||
free(context);
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
if (!attribs)
|
||||
*context->attribs = DEFAULT_CONTEXT_ATTRIBS;
|
||||
else
|
||||
*context->attribs = *attribs;
|
||||
|
||||
/* get configuration from environment variables */
|
||||
gatherconfig(context, screen_number);
|
||||
|
||||
if ((context->attribs->flags & RC_VisualID)) {
|
||||
XVisualInfo *vinfo, templ;
|
||||
int nret;
|
||||
|
||||
templ.screen = screen_number;
|
||||
templ.visualid = context->attribs->visualid;
|
||||
vinfo = XGetVisualInfo(context->dpy, VisualIDMask|VisualScreenMask,
|
||||
&templ, &nret);
|
||||
|
||||
if (!vinfo || nret==0) {
|
||||
sprintf(RErrorString, "invalid visual id %x\n",
|
||||
(unsigned int)context->attribs->visualid);
|
||||
} else {
|
||||
if (vinfo[0].visual == DefaultVisual(dpy, screen_number)) {
|
||||
context->attribs->flags |= RC_DefaultVisual;
|
||||
} else {
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
|
||||
context->visual = vinfo[0].visual;
|
||||
context->depth = vinfo[0].depth;
|
||||
context->vclass = vinfo[0].class;
|
||||
getColormap(context, screen_number);
|
||||
attr.colormap = context->cmap;
|
||||
attr.override_redirect = True;
|
||||
attr.border_pixel = 0;
|
||||
attr.background_pixel = 0;
|
||||
mask = CWBorderPixel|CWColormap|CWOverrideRedirect|CWBackPixel;
|
||||
context->drawable =
|
||||
XCreateWindow(dpy, RootWindow(dpy, screen_number), 1, 1,
|
||||
1, 1, 0, context->depth, CopyFromParent,
|
||||
context->visual, mask, &attr);
|
||||
/* XSetWindowColormap(dpy, context->drawable, attr.colormap);*/
|
||||
}
|
||||
XFree(vinfo);
|
||||
}
|
||||
}
|
||||
|
||||
/* use default */
|
||||
if (!context->visual) {
|
||||
if ((context->attribs->flags & RC_DefaultVisual)
|
||||
|| !bestContext(dpy, screen_number, context)) {
|
||||
context->visual = DefaultVisual(dpy, screen_number);
|
||||
context->depth = DefaultDepth(dpy, screen_number);
|
||||
context->cmap = DefaultColormap(dpy, screen_number);
|
||||
context->drawable = RootWindow(dpy, screen_number);
|
||||
context->black = BlackPixel(dpy, screen_number);
|
||||
context->white = WhitePixel(dpy, screen_number);
|
||||
context->vclass = context->visual->class;
|
||||
}
|
||||
}
|
||||
|
||||
gcv.function = GXcopy;
|
||||
gcv.graphics_exposures = False;
|
||||
context->copy_gc = XCreateGC(dpy, context->drawable, GCFunction
|
||||
|GCGraphicsExposures, &gcv);
|
||||
|
||||
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
||||
context->colors = allocatePseudoColor(context);
|
||||
if (!context->colors) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||
context->colors = allocateGrayScale(context);
|
||||
if (!context->colors) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (context->vclass == TrueColor) {
|
||||
/* calc offsets to create a TrueColor pixel */
|
||||
context->red_offset = count_offset(context->visual->red_mask);
|
||||
context->green_offset = count_offset(context->visual->green_mask);
|
||||
context->blue_offset = count_offset(context->visual->blue_mask);
|
||||
/* disable dithering on 24 bits visuals */
|
||||
if (context->depth >= 24)
|
||||
context->attribs->render_mode = RM_MATCH;
|
||||
}
|
||||
|
||||
/* check avaiability of MIT-SHM */
|
||||
#ifdef XSHM
|
||||
if (!(context->attribs->flags & RC_UseSharedMemory)) {
|
||||
context->attribs->flags |= RC_UseSharedMemory;
|
||||
context->attribs->use_shared_memory = True;
|
||||
}
|
||||
|
||||
if (context->attribs->use_shared_memory) {
|
||||
if (!XShmQueryExtension(context->dpy)) {
|
||||
context->attribs->use_shared_memory = False;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
static Bool
|
||||
bestContext(Display *dpy, int screen_number, RContext *context)
|
||||
{
|
||||
XVisualInfo *vinfo=NULL, rvinfo;
|
||||
int best = -1, numvis, i;
|
||||
long flags;
|
||||
XSetWindowAttributes attr;
|
||||
|
||||
rvinfo.class = TrueColor;
|
||||
rvinfo.screen = screen_number;
|
||||
flags = VisualClassMask | VisualScreenMask;
|
||||
|
||||
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
|
||||
if (vinfo) { /* look for a TrueColor, 24-bit or more (pref 24) */
|
||||
for (i=numvis-1, best = -1; i>=0; i--) {
|
||||
if (vinfo[i].depth == 24) best = i;
|
||||
else if (vinfo[i].depth>24 && best<0) best = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best == -1) { /* look for a DirectColor, 24-bit or more (pref 24) */
|
||||
rvinfo.class = DirectColor;
|
||||
if (vinfo) XFree((char *) vinfo);
|
||||
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
|
||||
if (vinfo) {
|
||||
for (i=0, best = -1; i<numvis; i++) {
|
||||
if (vinfo[i].depth == 24) best = i;
|
||||
else if (vinfo[i].depth>24 && best<0) best = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best > -1) {
|
||||
context->visual = vinfo[best].visual;
|
||||
context->depth = vinfo[best].depth;
|
||||
context->vclass = vinfo[best].class;
|
||||
getColormap(context, screen_number);
|
||||
attr.colormap = context->cmap;
|
||||
attr.override_redirect = True;
|
||||
attr.border_pixel = 0;
|
||||
context->drawable =
|
||||
XCreateWindow(dpy, RootWindow(dpy, screen_number),
|
||||
1, 1, 1, 1, 0, context->depth,
|
||||
CopyFromParent, context->visual,
|
||||
CWBorderPixel|CWColormap|CWOverrideRedirect, &attr);
|
||||
/* XSetWindowColormap(dpy, context->drawable, context->cmap);*/
|
||||
}
|
||||
if (vinfo) XFree((char *) vinfo);
|
||||
|
||||
if (best < 0)
|
||||
return False;
|
||||
else
|
||||
return True;
|
||||
}
|
||||
786
wrlib/convert.c
Normal file
786
wrlib/convert.c
Normal file
@@ -0,0 +1,786 @@
|
||||
/* convert.c - convert RImage to Pixmap
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef __GNUC__
|
||||
# define alloca __builtin_alloca
|
||||
#else
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
# pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||
|
||||
|
||||
typedef struct RConversionTable {
|
||||
unsigned short table[256];
|
||||
unsigned short index;
|
||||
struct RConversionTable *next;
|
||||
} RConversionTable;
|
||||
|
||||
|
||||
/*
|
||||
* Lookup table for index*3/8
|
||||
*/
|
||||
static char errorTable1[]={
|
||||
0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
|
||||
6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11,
|
||||
12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17,
|
||||
18, 18, 18, 19, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23,
|
||||
24, 24, 24, 25, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29,
|
||||
30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35,
|
||||
36, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41,
|
||||
42, 42, 42, 43, 43, 43, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47,
|
||||
48, 48, 48, 49, 49, 49, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53,
|
||||
54, 54, 54, 55, 55, 55, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59,
|
||||
60, 60, 60, 61, 61, 61, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65,
|
||||
66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71,
|
||||
72, 72, 72, 73, 73, 73, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77,
|
||||
78, 78, 78, 79, 79, 79, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83,
|
||||
84, 84, 84, 85, 85, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89,
|
||||
90, 90, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 94, 95
|
||||
};
|
||||
/*
|
||||
* Lookup table for index*2/8
|
||||
*/
|
||||
static char errorTable2[]={
|
||||
0, 1, 2, 1, 2, 3, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5,
|
||||
4, 5, 6, 5, 6, 7, 6, 7, 6, 7, 8, 7, 8, 9, 8, 9,
|
||||
8, 9, 10, 9, 10, 11, 10, 11, 10, 11, 12, 11, 12, 13, 12, 13,
|
||||
12, 13, 14, 13, 14, 15, 14, 15, 14, 15, 16, 15, 16, 17, 16, 17,
|
||||
16, 17, 18, 17, 18, 19, 18, 19, 18, 19, 20, 19, 20, 21, 20, 21,
|
||||
20, 21, 22, 21, 22, 23, 22, 23, 22, 23, 24, 23, 24, 25, 24, 25,
|
||||
24, 25, 26, 25, 26, 27, 26, 27, 26, 27, 28, 27, 28, 29, 28, 29,
|
||||
28, 29, 30, 29, 30, 31, 30, 31, 30, 31, 32, 31, 32, 33, 32, 33,
|
||||
32, 33, 34, 33, 34, 35, 34, 35, 34, 35, 36, 35, 36, 37, 36, 37,
|
||||
36, 37, 38, 37, 38, 39, 38, 39, 38, 39, 40, 39, 40, 41, 40, 41,
|
||||
40, 41, 42, 41, 42, 43, 42, 43, 42, 43, 44, 43, 44, 45, 44, 45,
|
||||
44, 45, 46, 45, 46, 47, 46, 47, 46, 47, 48, 47, 48, 49, 48, 49,
|
||||
48, 49, 50, 49, 50, 51, 50, 51, 50, 51, 52, 51, 52, 53, 52, 53,
|
||||
52, 53, 54, 53, 54, 55, 54, 55, 54, 55, 56, 55, 56, 57, 56, 57,
|
||||
56, 57, 58, 57, 58, 59, 58, 59, 58, 59, 60, 59, 60, 61, 60, 61,
|
||||
60, 61, 62, 61, 62, 63, 62, 63, 62, 63, 64, 63, 64, 65, 64
|
||||
};
|
||||
|
||||
|
||||
|
||||
static RConversionTable *conversionTable = NULL;
|
||||
|
||||
|
||||
static unsigned short*
|
||||
computeTable(unsigned short mask)
|
||||
{
|
||||
RConversionTable *tmp = conversionTable;
|
||||
int i;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->index == mask)
|
||||
break;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
return tmp->table;
|
||||
|
||||
tmp = (RConversionTable *)malloc(sizeof(RConversionTable));
|
||||
if (tmp == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i=0;i<256;i++)
|
||||
tmp->table[i] = (i*mask + 0x7f)/0xff;
|
||||
|
||||
tmp->index = mask;
|
||||
tmp->next = conversionTable;
|
||||
conversionTable = tmp;
|
||||
return tmp->table;
|
||||
}
|
||||
|
||||
|
||||
static RXImage*
|
||||
image2TrueColor(RContext *ctx, RImage *image)
|
||||
{
|
||||
RXImage *ximg;
|
||||
register int x, y, r, g, b;
|
||||
unsigned char *red, *grn, *blu;
|
||||
unsigned long pixel;
|
||||
unsigned short rmask, gmask, bmask;
|
||||
unsigned short roffs, goffs, boffs;
|
||||
unsigned short *rtable, *gtable, *btable;
|
||||
|
||||
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||
if (!ximg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
red = image->data[0];
|
||||
grn = image->data[1];
|
||||
blu = image->data[2];
|
||||
|
||||
roffs = ctx->red_offset;
|
||||
goffs = ctx->green_offset;
|
||||
boffs = ctx->blue_offset;
|
||||
|
||||
rmask = ctx->visual->red_mask >> roffs;
|
||||
gmask = ctx->visual->green_mask >> goffs;
|
||||
bmask = ctx->visual->blue_mask >> boffs;
|
||||
|
||||
#if 0
|
||||
/* this do not seem to increase speed. Only 0.06 second faster in
|
||||
* rendering a 800x600 image to pixmap. 1.12 sec instead of 1.18.
|
||||
* But does not require a 256*256*256 lookup table.
|
||||
*/
|
||||
if (ctx->depth==24) {
|
||||
#ifdef DEBUG
|
||||
puts("true color match for 24bpp");
|
||||
#endif
|
||||
for (y=0; y < image->height; y++) {
|
||||
for (x=0; x < image->width; x++) {
|
||||
pixel = (*(red++)<<roffs) | (*(grn++)<<goffs) | (*(blu++)<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
}
|
||||
}
|
||||
return ximg;
|
||||
}
|
||||
#endif
|
||||
|
||||
rtable = computeTable(rmask);
|
||||
gtable = computeTable(gmask);
|
||||
btable = computeTable(bmask);
|
||||
|
||||
if (rtable==NULL || gtable==NULL || btable==NULL) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->attribs->render_mode==RM_MATCH) {
|
||||
/* fake match */
|
||||
#ifdef DEBUG
|
||||
puts("true color match");
|
||||
#endif
|
||||
for (y=0; y < image->height; y++) {
|
||||
for (x=0; x < image->width; x++) {
|
||||
/* reduce pixel */
|
||||
r = rtable[*red++];
|
||||
g = gtable[*grn++];
|
||||
b = btable[*blu++];
|
||||
pixel = (r<<roffs) | (g<<goffs) | (b<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* dither */
|
||||
unsigned char *rerr, *gerr, *berr;
|
||||
unsigned char *nrerr, *ngerr, *nberr;
|
||||
unsigned char *rerr_, *gerr_, *berr_;
|
||||
unsigned char *nrerr_, *ngerr_, *nberr_;
|
||||
unsigned char *terr;
|
||||
register int ac, err;
|
||||
int width = image->width;
|
||||
int dr=0xff-rmask;
|
||||
int dg=0xff-gmask;
|
||||
int db=0xff-bmask;
|
||||
|
||||
while ((dr & 1)==0) dr = dr >> 1;
|
||||
while ((dg & 1)==0) dg = dg >> 1;
|
||||
while ((db & 1)==0) db = db >> 1;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("true color dither");
|
||||
#endif
|
||||
rerr_ = rerr = (unsigned char*)alloca((width+2)*sizeof(char));
|
||||
gerr_ = gerr = (unsigned char*)alloca((width+2)*sizeof(char));
|
||||
berr_ = berr = (unsigned char*)alloca((width+2)*sizeof(char));
|
||||
nrerr_ = nrerr = (unsigned char*)alloca((width+2)*sizeof(char));
|
||||
ngerr_ = ngerr = (unsigned char*)alloca((width+2)*sizeof(char));
|
||||
nberr_ = nberr = (unsigned char*)alloca((width+2)*sizeof(char));
|
||||
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
for (x=0; x<width; x++) {
|
||||
rerr[x] = *red++;
|
||||
gerr[x] = *grn++;
|
||||
berr[x] = *blu++;
|
||||
}
|
||||
rerr[x] = gerr[x] = berr[x] = 0;
|
||||
/* convert and dither the image to XImage */
|
||||
for (y=0; y<image->height; y++) {
|
||||
if (y<image->height-1) {
|
||||
memcpy(nrerr, red, width);
|
||||
memcpy(ngerr, grn, width);
|
||||
memcpy(nberr, blu, width);
|
||||
red+=width;
|
||||
grn+=width;
|
||||
blu+=width;
|
||||
/* last column */
|
||||
nrerr[x] = *(red-1);
|
||||
ngerr[x] = *(grn-1);
|
||||
nberr[x] = *(blu-1);
|
||||
}
|
||||
for (x=0; x<width; x++) {
|
||||
/* reduce pixel */
|
||||
pixel = (rtable[*rerr]<<roffs) | (gtable[*gerr]<<goffs)
|
||||
| (btable[*berr]<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
/* calc error */
|
||||
err = *rerr&dr;
|
||||
rerr++;
|
||||
/* distribute error */
|
||||
ac = errorTable1[err] + *rerr;
|
||||
*rerr=MIN(ac, 0xff);
|
||||
ac = errorTable1[err] + *nrerr;
|
||||
*nrerr=MIN(ac, 0xff);
|
||||
nrerr++;
|
||||
ac = *nrerr + errorTable2[err];
|
||||
*nrerr=MIN(ac,0xff);
|
||||
|
||||
/* calc error */
|
||||
err = *gerr&dg;
|
||||
gerr++;
|
||||
/* distribute error */
|
||||
ac = errorTable1[err] + *gerr;
|
||||
*gerr=MIN(ac, 0xff);
|
||||
ac = errorTable1[err] + *ngerr;
|
||||
*ngerr=MIN(ac, 0xff);
|
||||
ngerr++;
|
||||
ac = *ngerr + errorTable2[err];
|
||||
*ngerr=MIN(ac,0xff);
|
||||
|
||||
/* calc error */
|
||||
err = *berr&db;
|
||||
berr++;
|
||||
/* distribute error */
|
||||
ac = errorTable1[err] + *berr;
|
||||
*berr=MIN(ac, 0xff);
|
||||
ac = errorTable1[err] + *nberr;
|
||||
*nberr=MIN(ac, 0xff);
|
||||
nberr++;
|
||||
ac = *nberr + errorTable2[err];
|
||||
*nberr=MIN(ac,0xff);
|
||||
}
|
||||
/* skip to next line */
|
||||
rerr = nrerr_;
|
||||
nrerr = rerr_;
|
||||
terr = nrerr_;
|
||||
nrerr_ = rerr_;
|
||||
rerr_ = terr;
|
||||
|
||||
gerr = ngerr_;
|
||||
ngerr = gerr_;
|
||||
terr = ngerr_;
|
||||
ngerr_ = gerr_;
|
||||
gerr_ = terr;
|
||||
|
||||
berr = nberr_;
|
||||
nberr = berr_;
|
||||
terr = nberr_;
|
||||
nberr_ = berr_;
|
||||
berr_ = terr;
|
||||
}
|
||||
}
|
||||
return ximg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static RXImage*
|
||||
image2PseudoColor(RContext *ctx, RImage *image)
|
||||
{
|
||||
RXImage *ximg;
|
||||
register int x, y, r, g, b;
|
||||
unsigned char *red, *grn, *blu;
|
||||
unsigned long pixel;
|
||||
const int cpc=ctx->attribs->colors_per_channel;
|
||||
const unsigned short rmask = cpc-1; /* different sizes could be used */
|
||||
const unsigned short gmask = rmask; /* for r,g,b */
|
||||
const unsigned short bmask = rmask;
|
||||
unsigned short *rtable, *gtable, *btable;
|
||||
const int cpccpc = cpc*cpc;
|
||||
unsigned char *data;
|
||||
int ofs;
|
||||
/*register unsigned char maxrgb = 0xff;*/
|
||||
|
||||
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||
if (!ximg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
red = image->data[0];
|
||||
grn = image->data[1];
|
||||
blu = image->data[2];
|
||||
|
||||
data = ximg->image->data;
|
||||
|
||||
/* Tables are same at the moment because rmask==gmask==bmask. */
|
||||
rtable = computeTable(rmask);
|
||||
gtable = computeTable(gmask);
|
||||
btable = computeTable(bmask);
|
||||
|
||||
if (rtable==NULL || gtable==NULL || btable==NULL) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->attribs->render_mode == RM_MATCH) {
|
||||
/* fake match */
|
||||
#ifdef DEBUG
|
||||
printf("pseudo color match with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
for (y=0, ofs = 0; y<image->height; y++) {
|
||||
for (x=0; x<image->width; x++, ofs++) {
|
||||
/* reduce pixel */
|
||||
r = rtable[red[ofs]];
|
||||
g = gtable[grn[ofs]];
|
||||
b = btable[blu[ofs]];
|
||||
pixel = r*cpccpc + g*cpc + b;
|
||||
/*data[ofs] = ctx->colors[pixel].pixel;*/
|
||||
XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* dither */
|
||||
short *rerr, *gerr, *berr;
|
||||
short *nrerr, *ngerr, *nberr;
|
||||
short *terr;
|
||||
int rer, ger, ber;
|
||||
const int dr=0xff/rmask;
|
||||
const int dg=0xff/gmask;
|
||||
const int db=0xff/bmask;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("pseudo color dithering with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
rerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
gerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
berr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
nrerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
ngerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
nberr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
for (x=0; x<image->width; x++) {
|
||||
rerr[x] = red[x];
|
||||
gerr[x] = grn[x];
|
||||
berr[x] = blu[x];
|
||||
}
|
||||
rerr[x] = gerr[x] = berr[x] = 0;
|
||||
/* convert and dither the image to XImage */
|
||||
for (y=0, ofs=0; y<image->height; y++) {
|
||||
if (y<image->height-1) {
|
||||
int x1;
|
||||
for (x=0, x1=ofs+image->width; x<image->width; x++, x1++) {
|
||||
nrerr[x] = red[x1];
|
||||
ngerr[x] = grn[x1];
|
||||
nberr[x] = blu[x1];
|
||||
}
|
||||
/* last column */
|
||||
x1--;
|
||||
nrerr[x] = red[x1];
|
||||
ngerr[x] = grn[x1];
|
||||
nberr[x] = blu[x1];
|
||||
}
|
||||
for (x=0; x<image->width; x++, ofs++) {
|
||||
/* reduce pixel */
|
||||
if (rerr[x]>0xff) rerr[x]=0xff; else if (rerr[x]<0) rerr[x]=0;
|
||||
if (gerr[x]>0xff) gerr[x]=0xff; else if (gerr[x]<0) gerr[x]=0;
|
||||
if (berr[x]>0xff) berr[x]=0xff; else if (berr[x]<0) berr[x]=0;
|
||||
|
||||
r = rtable[rerr[x]];
|
||||
g = gtable[gerr[x]];
|
||||
b = btable[berr[x]];
|
||||
|
||||
pixel = r*cpccpc + g*cpc + b;
|
||||
/*data[ofs] = ctx->colors[pixel].pixel;*/
|
||||
XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel);
|
||||
/* calc error */
|
||||
rer = rerr[x] - r*dr;
|
||||
ger = gerr[x] - g*dg;
|
||||
ber = berr[x] - b*db;
|
||||
|
||||
/* distribute error */
|
||||
r = (rer*3)/8;
|
||||
g = (ger*3)/8;
|
||||
b = (ber*3)/8;
|
||||
/* x+1, y */
|
||||
rerr[x+1]+=r;
|
||||
gerr[x+1]+=g;
|
||||
berr[x+1]+=b;
|
||||
/* x, y+1 */
|
||||
nrerr[x]+=r;
|
||||
ngerr[x]+=g;
|
||||
nberr[x]+=b;
|
||||
/* x+1, y+1 */
|
||||
nrerr[x+1]+=rer-2*r;
|
||||
ngerr[x+1]+=ger-2*g;
|
||||
nberr[x+1]+=ber-2*b;
|
||||
}
|
||||
/* skip to next line */
|
||||
terr = rerr;
|
||||
rerr = nrerr;
|
||||
nrerr = terr;
|
||||
|
||||
terr = gerr;
|
||||
gerr = ngerr;
|
||||
ngerr = terr;
|
||||
|
||||
terr = berr;
|
||||
berr = nberr;
|
||||
nberr = terr;
|
||||
}
|
||||
}
|
||||
|
||||
return ximg;
|
||||
}
|
||||
|
||||
|
||||
static RXImage*
|
||||
image2GrayScale(RContext *ctx, RImage *image)
|
||||
{
|
||||
RXImage *ximg;
|
||||
register int x, y, g;
|
||||
unsigned char *red, *grn, *blu;
|
||||
const int cpc=ctx->attribs->colors_per_channel;
|
||||
unsigned short gmask;
|
||||
unsigned short *table;
|
||||
unsigned char *data;
|
||||
int ofs;
|
||||
/*register unsigned char maxrgb = 0xff;*/
|
||||
|
||||
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||
if (!ximg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
red = image->data[0];
|
||||
grn = image->data[1];
|
||||
blu = image->data[2];
|
||||
|
||||
data = ximg->image->data;
|
||||
|
||||
if (ctx->vclass == StaticGray)
|
||||
gmask = (1<<ctx->depth) - 1; /* use all grays */
|
||||
else
|
||||
gmask = cpc*cpc*cpc-1;
|
||||
|
||||
table = computeTable(gmask);
|
||||
|
||||
if (table==NULL) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->attribs->render_mode == RM_MATCH) {
|
||||
/* fake match */
|
||||
#ifdef DEBUG
|
||||
printf("grayscale match with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
for (y=0, ofs = 0; y<image->height; y++) {
|
||||
for (x=0; x<image->width; x++, ofs++) {
|
||||
/* reduce pixel */
|
||||
g = table[(red[ofs]*30+grn[ofs]*59+blu[ofs]*11)/100];
|
||||
|
||||
/*data[ofs] = ctx->colors[g].pixel;*/
|
||||
XPutPixel(ximg->image, x, y, ctx->colors[g].pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* dither */
|
||||
short *gerr;
|
||||
short *ngerr;
|
||||
short *terr;
|
||||
int ger;
|
||||
const int dg=0xff/gmask;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("grayscale dither with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
gerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
ngerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||
if (!gerr || !ngerr) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
for (x=0; x<image->width; x++) {
|
||||
gerr[x] = (red[x]*30 + grn[x]*59 + blu[x]*11)/100;
|
||||
}
|
||||
gerr[x] = 0;
|
||||
/* convert and dither the image to XImage */
|
||||
for (y=0, ofs=0; y<image->height; y++) {
|
||||
if (y<image->height-1) {
|
||||
int x1;
|
||||
for (x=0, x1=ofs+image->width; x<image->width; x++, x1++) {
|
||||
ngerr[x] = (red[x1]*30 + grn[x1]*59 + blu[x1]*11)/100;
|
||||
}
|
||||
/* last column */
|
||||
x1--;
|
||||
ngerr[x] = (red[x1]*30 + grn[x1]*59 + blu[x1]*11)/100;
|
||||
}
|
||||
for (x=0; x<image->width; x++, ofs++) {
|
||||
/* reduce pixel */
|
||||
if (gerr[x]>0xff) gerr[x]=0xff; else if (gerr[x]<0) gerr[x]=0;
|
||||
|
||||
g = table[gerr[x]];
|
||||
|
||||
/*data[ofs] = ctx->colors[g].pixel;*/
|
||||
XPutPixel(ximg->image, x, y, ctx->colors[g].pixel);
|
||||
/* calc error */
|
||||
ger = gerr[x] - g*dg;
|
||||
|
||||
/* distribute error */
|
||||
g = (ger*3)/8;
|
||||
/* x+1, y */
|
||||
gerr[x+1]+=g;
|
||||
/* x, y+1 */
|
||||
ngerr[x]+=g;
|
||||
/* x+1, y+1 */
|
||||
ngerr[x+1]+=ger-2*g;
|
||||
}
|
||||
/* skip to next line */
|
||||
terr = gerr;
|
||||
gerr = ngerr;
|
||||
ngerr = terr;
|
||||
}
|
||||
}
|
||||
ximg->image->data = (char*)data;
|
||||
|
||||
return ximg;
|
||||
}
|
||||
|
||||
|
||||
static RXImage*
|
||||
image2Bitmap(RContext *ctx, RImage *image, int threshold)
|
||||
{
|
||||
RXImage *ximg;
|
||||
unsigned char *alpha;
|
||||
int x, y;
|
||||
|
||||
ximg = RCreateXImage(ctx, 1, image->width, image->height);
|
||||
if (!ximg) {
|
||||
return NULL;
|
||||
}
|
||||
alpha = image->data[3];
|
||||
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
XPutPixel(ximg->image, x, y, (*alpha <= threshold ? 0 : 1));
|
||||
alpha++;
|
||||
}
|
||||
}
|
||||
|
||||
return ximg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
|
||||
{
|
||||
RXImage *ximg=NULL;
|
||||
|
||||
assert(context!=NULL);
|
||||
assert(image!=NULL);
|
||||
assert(pixmap!=NULL);
|
||||
|
||||
/* clear error message */
|
||||
RErrorString[0] = 0;
|
||||
|
||||
if (context->vclass == TrueColor)
|
||||
ximg = image2TrueColor(context, image);
|
||||
else if (context->vclass == PseudoColor || context->vclass == StaticColor)
|
||||
ximg = image2PseudoColor(context, image);
|
||||
else if (context->vclass == GrayScale || context->vclass == StaticGray)
|
||||
ximg = image2GrayScale(context, image);
|
||||
|
||||
if (!ximg) {
|
||||
strcat(RErrorString, ":could not convert RImage to XImage");
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
*pixmap = XCreatePixmap(context->dpy, context->drawable, image->width,
|
||||
image->height, context->depth);
|
||||
RPutXImage(context, *pixmap, context->copy_gc, ximg, 0, 0, 0, 0,
|
||||
image->width, image->height);
|
||||
|
||||
RDestroyXImage(context, ximg);
|
||||
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
|
||||
Pixmap *mask, int threshold)
|
||||
{
|
||||
GC gc;
|
||||
XGCValues gcv;
|
||||
RXImage *ximg=NULL;
|
||||
|
||||
assert(context!=NULL);
|
||||
assert(image!=NULL);
|
||||
assert(pixmap!=NULL);
|
||||
assert(mask!=NULL);
|
||||
|
||||
if (!RConvertImage(context, image, pixmap))
|
||||
return False;
|
||||
|
||||
if (image->data[3]==NULL) {
|
||||
*mask = None;
|
||||
return True;
|
||||
}
|
||||
|
||||
ximg = image2Bitmap(context, image, threshold);
|
||||
|
||||
if (!ximg) {
|
||||
strcat(RErrorString, ":could not convert RImage mask to XImage");
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
*mask = XCreatePixmap(context->dpy, context->drawable, image->width,
|
||||
image->height, 1);
|
||||
gcv.foreground = context->black;
|
||||
gcv.background = context->white;
|
||||
gcv.graphics_exposures = False;
|
||||
gc = XCreateGC(context->dpy, *mask, GCForeground|GCBackground
|
||||
|GCGraphicsExposures, &gcv);
|
||||
RPutXImage(context, *mask, gc, ximg, 0, 0, 0, 0,
|
||||
image->width, image->height);
|
||||
RDestroyXImage(context, ximg);
|
||||
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
Bool
|
||||
RGetClosestXColor(RContext *context, RColor *color, XColor *retColor)
|
||||
{
|
||||
RErrorString[0] = 0;
|
||||
|
||||
if (context->vclass == TrueColor) {
|
||||
unsigned short rmask, gmask, bmask;
|
||||
unsigned short roffs, goffs, boffs;
|
||||
unsigned short *rtable, *gtable, *btable;
|
||||
|
||||
roffs = context->red_offset;
|
||||
goffs = context->green_offset;
|
||||
boffs = context->blue_offset;
|
||||
|
||||
rmask = context->visual->red_mask >> roffs;
|
||||
gmask = context->visual->green_mask >> goffs;
|
||||
bmask = context->visual->blue_mask >> boffs;
|
||||
|
||||
rtable = computeTable(rmask);
|
||||
gtable = computeTable(gmask);
|
||||
btable = computeTable(bmask);
|
||||
|
||||
retColor->pixel = (rtable[color->red]<<roffs) |
|
||||
(rtable[color->green]<<goffs) | (rtable[color->blue]<<boffs);
|
||||
|
||||
retColor->red = rtable[color->red] << 8;
|
||||
retColor->green = rtable[color->green] << 8;
|
||||
retColor->blue = rtable[color->blue] << 8;
|
||||
retColor->flags = DoRed|DoGreen|DoBlue;
|
||||
|
||||
} else if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
||||
const int cpc=context->attribs->colors_per_channel;
|
||||
const unsigned short rmask = cpc-1; /* different sizes could be used */
|
||||
const unsigned short gmask = rmask; /* for r,g,b */
|
||||
const unsigned short bmask = rmask;
|
||||
unsigned short *rtable, *gtable, *btable;
|
||||
const int cpccpc = cpc*cpc;
|
||||
int index;
|
||||
|
||||
rtable = computeTable(rmask);
|
||||
gtable = computeTable(gmask);
|
||||
btable = computeTable(bmask);
|
||||
|
||||
if (rtable==NULL || gtable==NULL || btable==NULL) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return False;
|
||||
}
|
||||
index = rtable[color->red]*cpccpc + gtable[color->green]*cpc
|
||||
+ btable[color->blue];
|
||||
*retColor = context->colors[index];
|
||||
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||
|
||||
const int cpc = context->attribs->colors_per_channel;
|
||||
unsigned short gmask;
|
||||
unsigned short *table;
|
||||
int index;
|
||||
|
||||
if (context->vclass == StaticGray)
|
||||
gmask = (1<<context->depth) - 1; /* use all grays */
|
||||
else
|
||||
gmask = cpc*cpc*cpc-1;
|
||||
|
||||
table = computeTable(gmask);
|
||||
if (!table)
|
||||
return False;
|
||||
|
||||
index = table[(color->red*30 + color->green*59 + color->blue*11)/100];
|
||||
|
||||
*retColor = context->colors[index];
|
||||
} else {
|
||||
sprintf(RErrorString, "internal bug:unsupported visual:%i",
|
||||
context->vclass);
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
325
wrlib/convolve.c
Normal file
325
wrlib/convolve.c
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef __GNUC__
|
||||
# define alloca __builtin_alloca
|
||||
#else
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
# pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* RBlurImage--
|
||||
* Apply 3x3 1 1 1 low pass, convolution mask to image.
|
||||
* 1 1 1
|
||||
* 1 1 1 /9
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
RBlurImage(RImage *image)
|
||||
{
|
||||
register int x, y;
|
||||
register int w, tmp;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
|
||||
|
||||
#define MASK(c,pc,p) ((*c + *(c-1) + *(c+1) + pc[p] + pc[p-1] + pc[p+1] \
|
||||
+ *(c+w) + *(c+w-1) + *(c+w+1))/9)
|
||||
|
||||
pr = (unsigned char*)alloca(image->width*sizeof(char));
|
||||
if (!pr)
|
||||
goto outofmem;
|
||||
|
||||
pg = (unsigned char*)alloca(image->width*sizeof(char));
|
||||
if (!pg)
|
||||
goto outofmem;
|
||||
|
||||
pb = (unsigned char*)alloca(image->width*sizeof(char));
|
||||
if (!pb)
|
||||
goto outofmem;
|
||||
|
||||
pa = (unsigned char*)alloca(image->width*sizeof(char));
|
||||
if (!pa)
|
||||
goto outofmem;
|
||||
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
|
||||
for (x=0; x<image->width; x++) {
|
||||
pr[x] = *(r++);
|
||||
pg[x] = *(g++);
|
||||
pb[x] = *(b++);
|
||||
}
|
||||
|
||||
w = image->width;
|
||||
|
||||
for (y=1; y<image->height-1; y++) {
|
||||
pr[w-1] = r[w-1];
|
||||
pg[w-1] = g[w-1];
|
||||
pb[w-1] = b[w-1];
|
||||
|
||||
pr[0] = *(r++);
|
||||
pg[0] = *(g++);
|
||||
pb[0] = *(b++);
|
||||
|
||||
for (x=1; x<image->width-1; x++) {
|
||||
tmp = *r;
|
||||
*(r++) = MASK(r,pr,x);
|
||||
pr[x] = tmp;
|
||||
|
||||
tmp = *g;
|
||||
*(g++) = MASK(g,pg,x);
|
||||
pg[x] = tmp;
|
||||
|
||||
tmp = *b;
|
||||
*(b++) = MASK(b,pb,x);
|
||||
pb[x] = tmp;
|
||||
}
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
}
|
||||
|
||||
#undef MASK
|
||||
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return True;
|
||||
|
||||
outofmem:
|
||||
sprintf(RErrorString, "out of memory");
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
int
|
||||
REdgeDetectImage(RImage *image)
|
||||
{
|
||||
register int x, y, d1, d2, d3, d4, rsum;
|
||||
int w;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
|
||||
RImage *image2;
|
||||
|
||||
|
||||
image2 = RCloneImage(image);
|
||||
|
||||
pr = alloca(image->width*sizeof(char));
|
||||
if (!pr)
|
||||
goto outofmem;
|
||||
|
||||
pg = alloca(image->width*sizeof(char));
|
||||
if (!pg)
|
||||
goto outofmem;
|
||||
|
||||
pb = alloca(image->width*sizeof(char));
|
||||
if (!pb)
|
||||
goto outofmem;
|
||||
|
||||
pa = alloca(image->width*sizeof(char));
|
||||
if (!pa)
|
||||
goto outofmem;
|
||||
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
dr = image2->data[0];
|
||||
dg = image2->data[1];
|
||||
db = image2->data[2];
|
||||
da = image2->data[3];
|
||||
|
||||
|
||||
for (x=0; x<image->width; x++) {
|
||||
*(dr++) = *(r++);
|
||||
*(dg++) = *(g++);
|
||||
*(db++) = *(b++);
|
||||
}
|
||||
|
||||
w = image->width;
|
||||
|
||||
for (y=1; y<image->height-1; y++) {
|
||||
dr[w-1] = r[w-1];
|
||||
dg[w-1] = g[w-1];
|
||||
db[w-1] = b[w-1];
|
||||
|
||||
*(dr++) = *(r++);
|
||||
*(dg++) = *(g++);
|
||||
*(db++) = *(b++);
|
||||
|
||||
for (x=1; x<image->width-1; x++) {
|
||||
d1 = r[w+1] - r[-w-1];
|
||||
d2 = r[1] - r[-1];
|
||||
d3 = r[-w+1] - r[w-1];
|
||||
d4 = r[-w] - r[w];
|
||||
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0) rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0) d1 = -d1;
|
||||
if (d1 > rsum) rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(dr++) = rsum;
|
||||
|
||||
d1 = g[w+1] - g[-w-1];
|
||||
d2 = g[1] - g[-1];
|
||||
d3 = g[-w+1] - g[w-1];
|
||||
d4 = g[-w] - g[w];
|
||||
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0) rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0) d1 = -d1;
|
||||
if (d1 > rsum) rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(dg++) = rsum;
|
||||
|
||||
d1 = b[w+1] - b[-w-1];
|
||||
d2 = b[1] - b[-1];
|
||||
d3 = b[-w+1] - b[w-1];
|
||||
d4 = b[-w] - b[w];
|
||||
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0) rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0) d1 = -d1;
|
||||
if (d1 > rsum) rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(db++) = rsum;
|
||||
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
}
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
|
||||
dr++;
|
||||
dg++;
|
||||
db++;
|
||||
}
|
||||
{
|
||||
r = image->data[0];
|
||||
image2->data[0] = r;
|
||||
g = image->data[1];
|
||||
image2->data[1] = g;
|
||||
b = image->data[2];
|
||||
image2->data[2] = b;
|
||||
RDestroyImage(image2);
|
||||
}
|
||||
|
||||
#undef MASK
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RSmoothImage(RImage *image)
|
||||
{
|
||||
register int x, y;
|
||||
register int v, w;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
w = image->width;
|
||||
for (y=0; y<image->height - 1; y++) {
|
||||
for (x=0; x<image->width - 1; x++) {
|
||||
v = *r + 2 * *(r + 1) + 2 * *(r + w) + *(r + w + 1);
|
||||
*(r++) = v/6;
|
||||
|
||||
v = *g + 2 * *(g + 1) + 2 * *(g + w) + *(g + w + 1);
|
||||
*(g++) = v/6;
|
||||
|
||||
v = *b + 2 * *(b + 1) + 2 * *(b + w) + *(b + w + 1);
|
||||
*(b++) = v/6;
|
||||
}
|
||||
|
||||
/* last column */
|
||||
v = 3 * *r + 3 * *(r + w);
|
||||
*(r++) = v/6;
|
||||
|
||||
v = 3 * *g + 3 * *(g + w);
|
||||
*(g++) = v/6;
|
||||
|
||||
v = 3 * *b + 3 * *(b + w);
|
||||
*(b++) = v/6;
|
||||
}
|
||||
|
||||
/* last line */
|
||||
for (x=0; x<image->width - 1; x++) {
|
||||
v = 3 * *r + 3 * *(r + 1);
|
||||
*(r++) = v/6;
|
||||
|
||||
v = 3 * *g + 3 * *(g + 1);
|
||||
*(g++) = v/6;
|
||||
|
||||
v = 3 * *b + 3 * *(b + 1);
|
||||
*(b++) = v/6;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
535
wrlib/draw.c
Normal file
535
wrlib/draw.c
Normal file
@@ -0,0 +1,535 @@
|
||||
/* draw.c - pixel plotting, line drawing
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1998 Dan Pascu
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Returns the color of the pixel at coordinates (x, y) in "color".
|
||||
*/
|
||||
Bool
|
||||
RGetPixel(RImage *image, int x, int y, RColor *color)
|
||||
{
|
||||
int ofs;
|
||||
|
||||
assert(image!=NULL);
|
||||
if (x < 0 || x >= image->width
|
||||
|| y < 0 || y >= image->height)
|
||||
return False;
|
||||
|
||||
ofs = y*image->width + x;
|
||||
color->red = image->data[0][ofs];
|
||||
color->green = image->data[1][ofs];
|
||||
color->blue = image->data[2][ofs];
|
||||
/* If the image does not have alpha channel, we consider alpha 255 */
|
||||
if (image->data[3])
|
||||
color->alpha = image->data[3][ofs];
|
||||
else
|
||||
color->alpha = 255;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RPutPixel(RImage *image, int x, int y, RColor *color)
|
||||
{
|
||||
int ofs;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(color!=NULL);
|
||||
assert(x >= 0 && x < image->width);
|
||||
assert(y >= 0 && y < image->height);
|
||||
|
||||
ofs = y*image->width + x;
|
||||
sr = image->data[0] + ofs;
|
||||
sg = image->data[1] + ofs;
|
||||
sb = image->data[2] + ofs;
|
||||
sa = image->data[3] + ofs;
|
||||
|
||||
if (color->alpha==255) {
|
||||
*sr = color->red;
|
||||
*sg = color->green;
|
||||
*sb = color->blue;
|
||||
if (image->data[3])
|
||||
*sa = 255;
|
||||
} else {
|
||||
register int alpha, nalpha, r, g, b;
|
||||
|
||||
r = color->red;
|
||||
g = color->green;
|
||||
b = color->blue;
|
||||
alpha = color->alpha;
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
*sr = (((int)*sr * nalpha) + (r * alpha))/256;
|
||||
*sg = (((int)*sg * nalpha) + (g * alpha))/256;
|
||||
*sb = (((int)*sb * nalpha) + (b * alpha))/256;
|
||||
if (image->data[3])
|
||||
*sa = alpha + ((int)*sa * nalpha)/256;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
operatePixel(RImage *image, int ofs, int operation, RColor *color)
|
||||
{
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
register int alpha, nalpha, tmp;
|
||||
int hasAlpha = image->data[3]!=NULL;
|
||||
|
||||
alpha = color->alpha;
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
sr = image->data[0] + ofs;
|
||||
sg = image->data[1] + ofs;
|
||||
sb = image->data[2] + ofs;
|
||||
sa = image->data[3] + ofs;
|
||||
|
||||
switch (operation) {
|
||||
case RClearOperation:
|
||||
*sr = 0;
|
||||
*sg = 0;
|
||||
*sb = 0;
|
||||
if (hasAlpha)
|
||||
*sa = 0;
|
||||
break;
|
||||
case RCopyOperation:
|
||||
*sr = color->red;
|
||||
*sg = color->green;
|
||||
*sb = color->blue;
|
||||
if (hasAlpha)
|
||||
*sa = color->alpha;
|
||||
break;
|
||||
case RNormalOperation:
|
||||
if (color->alpha==255) {
|
||||
*sr = color->red;
|
||||
*sg = color->green;
|
||||
*sb = color->blue;
|
||||
if (hasAlpha)
|
||||
*sa = 255;
|
||||
} else {
|
||||
*sr = (((int)*sr * nalpha) + ((int)color->red * alpha))/256;
|
||||
*sg = (((int)*sg * nalpha) + ((int)color->green * alpha))/256;
|
||||
*sb = (((int)*sb * nalpha) + ((int)color->blue * alpha))/256;
|
||||
}
|
||||
break;
|
||||
case RAddOperation:
|
||||
tmp = color->red + *sr;
|
||||
*sr = MIN(255, tmp);
|
||||
tmp = color->green + *sg;
|
||||
*sg = MIN(255, tmp);
|
||||
tmp = color->blue + *sb;
|
||||
*sb = MIN(255, tmp);
|
||||
if (hasAlpha)
|
||||
*sa = MIN(*sa, color->alpha);
|
||||
break;
|
||||
case RSubtractOperation:
|
||||
tmp = *sr - color->red;
|
||||
*sr = MAX(0, tmp);
|
||||
tmp = *sg - color->green;
|
||||
*sg = MAX(0, tmp);
|
||||
tmp = *sb - color->blue;
|
||||
*sb = MAX(0, tmp);
|
||||
if (hasAlpha)
|
||||
*sa = MIN(*sa, color->alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ROperatePixel(RImage *image, int operation, int x, int y, RColor *color)
|
||||
{
|
||||
int ofs;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(color!=NULL);
|
||||
assert(x >= 0 && x < image->width);
|
||||
assert(y >= 0 && y < image->height);
|
||||
|
||||
ofs = y*image->width + x;
|
||||
|
||||
operatePixel(image, ofs, operation, color);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RPutPixels(RImage *image, RPoint *points, int npoints, int mode, RColor *color)
|
||||
{
|
||||
register int x, y, i;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(points!=NULL);
|
||||
|
||||
x = y = 0;
|
||||
|
||||
for (i=0; i<npoints; i++) {
|
||||
if (mode == RAbsoluteCoordinates) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
} else {
|
||||
x += points[i].x;
|
||||
y += points[i].y;
|
||||
}
|
||||
RPutPixel(image, x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ROperatePixels(RImage *image, int operation, RPoint *points, int npoints,
|
||||
int mode, RColor *color)
|
||||
{
|
||||
register int x, y, i;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(points!=NULL);
|
||||
|
||||
x = y = 0;
|
||||
|
||||
for (i=0; i<npoints; i++) {
|
||||
if (mode == RAbsoluteCoordinates) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
} else {
|
||||
x += points[i].x;
|
||||
y += points[i].y;
|
||||
}
|
||||
ROperatePixel(image, operation, x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine is a generic drawing routine, based on Bresenham's line
|
||||
* drawing algorithm.
|
||||
*/
|
||||
static int
|
||||
genericLine(RImage *image, int x0, int y0, int x1, int y1, RColor *color,
|
||||
int operation, int polyline)
|
||||
{
|
||||
int i, err, du, dv, du2, dv2, uofs, vofs, last;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(x0 >= 0 && x0 <= image->width);
|
||||
assert(x1 >= 0 && x1 <= image->width);
|
||||
assert(y0 >= 0 && y0 <= image->height);
|
||||
assert(y1 >= 0 && y1 <= image->height);
|
||||
|
||||
if (x0 < x1) {
|
||||
du = x1 - x0;
|
||||
uofs = 1;
|
||||
} else {
|
||||
du = x0 - x1;
|
||||
uofs = -1;
|
||||
}
|
||||
if (y0 < y1) {
|
||||
dv = y1 -y0;
|
||||
vofs = image->width;
|
||||
} else {
|
||||
dv = y0 - y1;
|
||||
vofs = -image->width;
|
||||
}
|
||||
|
||||
if (du < dv) {
|
||||
/* Swap coordinates between them, so that always du>dv */
|
||||
i = du; du = dv; dv = i;
|
||||
i = uofs; uofs = vofs; vofs = i;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
du2 = du<<1;
|
||||
dv2 = dv<<1;
|
||||
last = (polyline) ? du-1 : du;
|
||||
|
||||
if (color->alpha==255 || operation==RCopyOperation) {
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
|
||||
i = y0*image->width + x0;
|
||||
sr = image->data[0] + i;
|
||||
sg = image->data[1] + i;
|
||||
sb = image->data[2] + i;
|
||||
sa = image->data[3] + i;
|
||||
|
||||
for (i=0; i<=last; i++) {
|
||||
/* Draw the pixel */
|
||||
*sr = color->red;
|
||||
*sg = color->green;
|
||||
*sb = color->blue;
|
||||
if (image->data[3])
|
||||
*sa = 255;
|
||||
|
||||
/* Compute error for NeXT Step */
|
||||
err += dv2;
|
||||
if (err >= du) {
|
||||
sr += vofs; sg += vofs;
|
||||
sb += vofs; sa += vofs;
|
||||
err -= du2;
|
||||
}
|
||||
sr += uofs; sg += uofs;
|
||||
sb += uofs; sa += uofs;
|
||||
}
|
||||
} else {
|
||||
register int ofs = y0*image->width + x0;
|
||||
|
||||
for (i=0; i<=last; i++) {
|
||||
/* Draw the pixel */
|
||||
operatePixel(image, ofs, operation, color);
|
||||
|
||||
/* Compute error for NeXT Step */
|
||||
err += dv2;
|
||||
if (err >= du) {
|
||||
ofs += vofs;
|
||||
err -= du2;
|
||||
}
|
||||
ofs += uofs;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (mode == RALTER_PIXELS) {
|
||||
RColorOffset *cdelta = (RColorOffset*)cdata;
|
||||
register short r, g, b, a;
|
||||
|
||||
for (i=0; i<=last; i++) {
|
||||
/* Change the pixel with offset */
|
||||
r = (short)*sr + cdelta->red;
|
||||
g = (short)*sg + cdelta->green;
|
||||
b = (short)*sb + cdelta->blue;
|
||||
if (r>255) r = 255; else if (r<0) r = 0;
|
||||
if (g>255) g = 255; else if (g<0) g = 0;
|
||||
if (b>255) b = 255; else if (b<0) b = 0;
|
||||
*sr = (unsigned char) r;
|
||||
*sg = (unsigned char) g;
|
||||
*sb = (unsigned char) b;
|
||||
if (image->data[3]) {
|
||||
a = (short)*sa + cdelta->alpha;
|
||||
if (a>255) a = 255; else if (a<0) a = 0;
|
||||
*sa = (unsigned char) a;
|
||||
}
|
||||
|
||||
/* Compute error for NeXT Step */
|
||||
err += dv2;
|
||||
if (err >= du) {
|
||||
sr += vofs; sg += vofs;
|
||||
sb += vofs; sa += vofs;
|
||||
err -= du2;
|
||||
}
|
||||
sr += uofs; sg += uofs;
|
||||
sb += uofs; sa += uofs;
|
||||
}
|
||||
} else {
|
||||
RColor *color = (RColor*)cdata;
|
||||
|
||||
if (color->alpha==255) {
|
||||
for (i=0; i<=last; i++) {
|
||||
/* Draw the pixel */
|
||||
*sr = color->red;
|
||||
*sg = color->green;
|
||||
*sb = color->blue;
|
||||
if (image->data[3])
|
||||
*sa = 255;
|
||||
|
||||
/* Compute error for NeXT Step */
|
||||
err += dv2;
|
||||
if (err >= du) {
|
||||
sr += vofs; sg += vofs;
|
||||
sb += vofs; sa += vofs;
|
||||
err -= du2;
|
||||
}
|
||||
sr += uofs; sg += uofs;
|
||||
sb += uofs; sa += uofs;
|
||||
}
|
||||
} else {
|
||||
register short alpha, nalpha, r, g ,b;
|
||||
|
||||
alpha = color->alpha;
|
||||
nalpha = 255 - alpha;
|
||||
r = color->red;
|
||||
g = color->green;
|
||||
b = color->blue;
|
||||
|
||||
for (i=0; i<=last; i++) {
|
||||
/* Draw the pixel */
|
||||
*sr = (((int)*sr * nalpha) + (r * alpha))/256;
|
||||
*sg = (((int)*sg * nalpha) + (g * alpha))/256;
|
||||
*sb = (((int)*sb * nalpha) + (b * alpha))/256;
|
||||
if (image->data[3])
|
||||
*sa = alpha + ((int)*sa * nalpha)/256;
|
||||
|
||||
/* Compute error for NeXT Step */
|
||||
err += dv2;
|
||||
if (err >= du) {
|
||||
sr += vofs; sg += vofs;
|
||||
sb += vofs; sa += vofs;
|
||||
err -= du2;
|
||||
}
|
||||
sr += uofs; sg += uofs;
|
||||
sb += uofs; sa += uofs;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RDrawLine(RImage *image, int x0, int y0, int x1, int y1, RColor *color)
|
||||
{
|
||||
return genericLine(image, x0, y0, x1, y1, color, RNormalOperation, False);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ROperateLine(RImage *image, int operation, int x0, int y0, int x1,
|
||||
int y1, RColor *color)
|
||||
{
|
||||
return genericLine(image, x0, y0, x1, y1, color, operation, False);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RDrawLines(RImage *image, RPoint *points, int npoints, int mode, RColor *color)
|
||||
{
|
||||
register int x1, y1, x2, y2, i;
|
||||
|
||||
assert(points!=NULL);
|
||||
|
||||
if (npoints==0)
|
||||
return;
|
||||
|
||||
x1 = points[0].x;
|
||||
y1 = points[0].y;
|
||||
x2 = y2 = 0;
|
||||
|
||||
for (i=1; i<npoints-1; i++) {
|
||||
if (mode == RAbsoluteCoordinates) {
|
||||
x2 = points[i].x;
|
||||
y2 = points[i].y;
|
||||
} else {
|
||||
x2 += points[i-1].x;
|
||||
y2 += points[i-1].y;
|
||||
}
|
||||
/* Don't draw pixels at junction points twice */
|
||||
genericLine(image, x1, y1, x2, y2, color, RNormalOperation, True);
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
i = npoints-1; /* last point */
|
||||
if (mode == RAbsoluteCoordinates) {
|
||||
x2 = points[i].x;
|
||||
y2 = points[i].y;
|
||||
} else {
|
||||
x2 += points[i-1].x;
|
||||
y2 += points[i-1].y;
|
||||
}
|
||||
i = (points[0].x==x2 && points[0].y==y2 && npoints>1);
|
||||
genericLine(image, x1, y1, x2, y2, color, RNormalOperation, i);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ROperateLines(RImage *image, int operation, RPoint *points,
|
||||
int npoints, int mode, RColor *color)
|
||||
{
|
||||
register int x1, y1, x2, y2, i;
|
||||
|
||||
assert(points!=NULL);
|
||||
|
||||
if (npoints==0)
|
||||
return;
|
||||
|
||||
x1 = points[0].x;
|
||||
y1 = points[0].y;
|
||||
x2 = y2 = 0;
|
||||
|
||||
for (i=1; i<npoints-1; i++) {
|
||||
if (mode == RAbsoluteCoordinates) {
|
||||
x2 = points[i].x;
|
||||
y2 = points[i].y;
|
||||
} else {
|
||||
x2 += points[i-1].x;
|
||||
y2 += points[i-1].y;
|
||||
}
|
||||
/* Don't draw pixels at junction points twice */
|
||||
genericLine(image, x1, y1, x2, y2, color, operation, True);
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
i = npoints-1; /* last point */
|
||||
if (mode == RAbsoluteCoordinates) {
|
||||
x2 = points[i].x;
|
||||
y2 = points[i].y;
|
||||
} else {
|
||||
x2 += points[i-1].x;
|
||||
y2 += points[i-1].y;
|
||||
}
|
||||
i = (points[0].x==x2 && points[0].y==y2 && npoints>1);
|
||||
genericLine(image, x1, y1, x2, y2, color, operation, i);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RDrawSegments(RImage *image, RSegment *segs, int nsegs, RColor *color)
|
||||
{
|
||||
register int i;
|
||||
|
||||
assert(segs!=NULL);
|
||||
|
||||
for (i=0; i<nsegs; i++) {
|
||||
genericLine(image, segs->x1, segs->y1, segs->x2, segs->y2, color,
|
||||
RNormalOperation, False);
|
||||
segs++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ROperateSegments(RImage *image, int operation, RSegment *segs,
|
||||
int nsegs, RColor *color)
|
||||
{
|
||||
register int i;
|
||||
|
||||
assert(segs!=NULL);
|
||||
|
||||
for (i=0; i<nsegs; i++) {
|
||||
genericLine(image, segs->x1, segs->y1, segs->x2, segs->y2, color,
|
||||
operation, False);
|
||||
segs++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
201
wrlib/gif.c
Normal file
201
wrlib/gif.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/* gif.c - load GIF image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1998 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#ifdef USE_GIF
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gif_lib.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
static int InterlacedOffset[] = { 0, 4, 2, 1 };
|
||||
static int InterlacedJumps[] = { 8, 8, 4, 2 };
|
||||
|
||||
|
||||
/*
|
||||
* Partially based on code in gif2rgb from giflib, by Gershon Elber.
|
||||
*/
|
||||
RImage*
|
||||
RLoadGIF(RContext *context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
GifFileType *gif = NULL;
|
||||
GifPixelType *buffer = NULL;
|
||||
int i, j, k, ofs = 0;
|
||||
int width, height;
|
||||
GifRecordType recType;
|
||||
ColorMapObject *colormap;
|
||||
unsigned char rmap[256];
|
||||
unsigned char gmap[256];
|
||||
unsigned char bmap[256];
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
/* default error message */
|
||||
sprintf(RErrorString, "file does not contain image of index %i", index);
|
||||
|
||||
gif = DGifOpenFileName(file);
|
||||
|
||||
if (!gif) {
|
||||
sprintf(RErrorString, "could not load gif file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
colormap = gif->SColorMap;
|
||||
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
int extCode;
|
||||
GifByteType *extension;
|
||||
|
||||
if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
switch (recType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (i++ != index)
|
||||
break;
|
||||
|
||||
if (DGifGetImageDesc(gif)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
|
||||
width = gif->Image.Width;
|
||||
height = gif->Image.Height;
|
||||
|
||||
if (gif->Image.ColorMap)
|
||||
colormap = gif->Image.ColorMap;
|
||||
|
||||
/* the gif specs talk about a default colormap, but it
|
||||
* doesnt say what the heck is this default colormap */
|
||||
if (!colormap) {
|
||||
/*
|
||||
* Well, since the spec says the colormap can be anything,
|
||||
* lets just render it with whatever garbage the stack
|
||||
* has :)
|
||||
*
|
||||
sprintf(RErrorString, "bad gif file");
|
||||
|
||||
goto bye;
|
||||
*/
|
||||
} else {
|
||||
for (j = 0; j < colormap->ColorCount; j++) {
|
||||
rmap[j] = colormap->Colors[j].Red;
|
||||
gmap[j] = colormap->Colors[j].Green;
|
||||
bmap[j] = colormap->Colors[j].Blue;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = malloc(width * sizeof(GifColorType));
|
||||
if (!buffer) {
|
||||
sprintf(RErrorString, "out of memory while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
|
||||
if (gif->Image.Interlace) {
|
||||
int l;
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = InterlacedOffset[j]; k < height;
|
||||
k += InterlacedJumps[j]) {
|
||||
if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
ofs = k*width;
|
||||
for (l = 0; l < width; l++, ofs++) {
|
||||
int pixel = buffer[l];
|
||||
image->data[0][ofs] = rmap[pixel];
|
||||
image->data[1][ofs] = gmap[pixel];
|
||||
image->data[2][ofs] = bmap[pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < height; j++) {
|
||||
if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
for (k = 0; k < width; k++, ofs++) {
|
||||
int pixel = buffer[k];
|
||||
image->data[0][ofs] = rmap[pixel];
|
||||
image->data[1][ofs] = gmap[pixel];
|
||||
image->data[2][ofs] = bmap[pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* skip all extension blocks */
|
||||
if (DGifGetExtension(gif, &extCode, &extension)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
while (extension) {
|
||||
if (DGifGetExtensionNext(gif, &extension)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (recType != TERMINATE_RECORD_TYPE && i <= index);
|
||||
|
||||
/* yuck! */
|
||||
goto did_not_get_any_errors;
|
||||
bye:
|
||||
if (image)
|
||||
RDestroyImage(image);
|
||||
image = NULL;
|
||||
did_not_get_any_errors:
|
||||
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
|
||||
if (gif)
|
||||
DGifCloseFile(gif);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_GIF */
|
||||
508
wrlib/gradient.c
Normal file
508
wrlib/gradient.c
Normal file
@@ -0,0 +1,508 @@
|
||||
/* gradient.c - renders gradients
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
static RImage *renderHGradient(unsigned width, unsigned height,
|
||||
int r0, int g0, int b0,
|
||||
int rf, int gf, int bf);
|
||||
static RImage *renderVGradient(unsigned width, unsigned height,
|
||||
int r0, int g0, int b0,
|
||||
int rf, int gf, int bf);
|
||||
static RImage *renderDGradient(unsigned width, unsigned height,
|
||||
int r0, int g0, int b0,
|
||||
int rf, int gf, int bf);
|
||||
|
||||
static RImage *renderMHGradient(unsigned width, unsigned height,
|
||||
RColor **colors, int count);
|
||||
static RImage *renderMVGradient(unsigned width, unsigned height,
|
||||
RColor **colors, int count);
|
||||
static RImage *renderMDGradient(unsigned width, unsigned height,
|
||||
RColor **colors, int count);
|
||||
|
||||
RImage*
|
||||
RRenderMultiGradient(unsigned width, unsigned height, RColor **colors, int style)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
while (colors[count]!=NULL) count++;
|
||||
|
||||
if (count > 2) {
|
||||
switch (style) {
|
||||
case RHorizontalGradient:
|
||||
return renderMHGradient(width, height, colors, count);
|
||||
case RVerticalGradient:
|
||||
return renderMVGradient(width, height, colors, count);
|
||||
case RDiagonalGradient:
|
||||
return renderMDGradient(width, height, colors, count);
|
||||
}
|
||||
} else if (count > 1) {
|
||||
return RRenderGradient(width, height, colors[0], colors[1], style);
|
||||
} else if (count > 0) {
|
||||
return RRenderGradient(width, height, colors[0], colors[0], style);
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RRenderGradient(unsigned width, unsigned height, RColor *from, RColor *to,
|
||||
int style)
|
||||
{
|
||||
switch (style) {
|
||||
case RHorizontalGradient:
|
||||
return renderHGradient(width, height, from->red, from->green,
|
||||
from->blue, to->red, to->green, to->blue);
|
||||
case RVerticalGradient:
|
||||
return renderVGradient(width, height, from->red, from->green,
|
||||
from->blue, to->red, to->green, to->blue);
|
||||
|
||||
case RDiagonalGradient:
|
||||
return renderDGradient(width, height, from->red, from->green,
|
||||
from->blue, to->red, to->green, to->blue);
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* renderHGradient--
|
||||
* Renders a horizontal linear gradient of the specified size in the
|
||||
* RImage format with a border of the specified type.
|
||||
*
|
||||
* Returns:
|
||||
* A 24bit RImage with the gradient (no alpha channel).
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
static RImage*
|
||||
renderHGradient(unsigned width, unsigned height, int r0, int g0, int b0,
|
||||
int rf, int gf, int bf)
|
||||
{
|
||||
int i;
|
||||
unsigned long r, g, b, dr, dg, db;
|
||||
RImage *image;
|
||||
unsigned char *rp, *gp, *bp;
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
rp = image->data[0];
|
||||
gp = image->data[1];
|
||||
bp = image->data[2];
|
||||
|
||||
r = r0 << 16;
|
||||
g = g0 << 16;
|
||||
b = b0 << 16;
|
||||
|
||||
dr = ((rf-r0)<<16)/(int)width;
|
||||
dg = ((gf-g0)<<16)/(int)width;
|
||||
db = ((bf-b0)<<16)/(int)width;
|
||||
/* render the first line */
|
||||
for (i=0; i<width; i++) {
|
||||
*(rp++) = (unsigned char)(r>>16);
|
||||
*(gp++) = (unsigned char)(g>>16);
|
||||
*(bp++) = (unsigned char)(b>>16);
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
}
|
||||
|
||||
|
||||
/* copy the first line to the other lines */
|
||||
for (i=1; i<height; i++) {
|
||||
memcpy(&(image->data[0][i*width]), image->data[0], width);
|
||||
memcpy(&(image->data[1][i*width]), image->data[1], width);
|
||||
memcpy(&(image->data[2][i*width]), image->data[2], width);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* renderVGradient--
|
||||
* Renders a vertical linear gradient of the specified size in the
|
||||
* RImage format with a border of the specified type.
|
||||
*
|
||||
* Returns:
|
||||
* A 24bit RImage with the gradient (no alpha channel).
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
static RImage*
|
||||
renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0,
|
||||
int rf, int gf, int bf)
|
||||
{
|
||||
int i;
|
||||
unsigned long r, g, b, dr, dg, db;
|
||||
RImage *image;
|
||||
unsigned char *rp, *gp, *bp;
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
rp = image->data[0];
|
||||
gp = image->data[1];
|
||||
bp = image->data[2];
|
||||
|
||||
r = r0<<16;
|
||||
g = g0<<16;
|
||||
b = b0<<16;
|
||||
|
||||
dr = ((rf-r0)<<16)/(int)height;
|
||||
dg = ((gf-g0)<<16)/(int)height;
|
||||
db = ((bf-b0)<<16)/(int)height;
|
||||
|
||||
for (i=0; i<height; i++) {
|
||||
memset(rp, (unsigned char)(r>>16), width);
|
||||
memset(gp, (unsigned char)(g>>16), width);
|
||||
memset(bp, (unsigned char)(b>>16), width);
|
||||
rp+=width;
|
||||
gp+=width;
|
||||
bp+=width;
|
||||
r+=dr;
|
||||
g+=dg;
|
||||
b+=db;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* renderDGradient--
|
||||
* Renders a diagonal linear gradient of the specified size in the
|
||||
* RImage format with a border of the specified type.
|
||||
*
|
||||
* Returns:
|
||||
* A 24bit RImage with the gradient (no alpha channel).
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
#if 0
|
||||
/* This version is slower then the second below. It uses more operations,
|
||||
* most of them multiplication of floats. -Dan
|
||||
*/
|
||||
static RImage*
|
||||
renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0,
|
||||
int rf, int gf, int bf)
|
||||
{
|
||||
int x, y;
|
||||
float from_red,from_green,from_blue;
|
||||
float to_red,to_green,to_blue;
|
||||
float dr,dg,db,dx,dy,w,h,xred,yred,xgreen,ygreen,xblue,yblue;
|
||||
RImage *image;
|
||||
unsigned char *rp, *gp, *bp;
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
rp = image->data[0];
|
||||
gp = image->data[1];
|
||||
bp = image->data[2];
|
||||
|
||||
from_red = (float)r0;
|
||||
from_green = (float)g0;
|
||||
from_blue = (float)b0;
|
||||
|
||||
to_red = (float)rf;
|
||||
to_green = (float)gf;
|
||||
to_blue = (float)bf;
|
||||
|
||||
w = (float) width;
|
||||
h = (float) height;
|
||||
|
||||
dr = (to_red - from_red);
|
||||
dg = (to_green - from_green);
|
||||
db = (to_blue - from_blue);
|
||||
|
||||
for (y=0; y<height; y++) {
|
||||
|
||||
dy = y / h;
|
||||
|
||||
yred = dr * dy + from_red;
|
||||
ygreen = dg * dy + from_green;
|
||||
yblue = db * dy + from_blue;
|
||||
|
||||
for (x=0; x<width; x++) {
|
||||
dx = x / w;
|
||||
|
||||
xred = dr * dx + from_red;
|
||||
xgreen = dg * dx + from_green;
|
||||
xblue = db * dx + from_blue;
|
||||
|
||||
*(rp++) = (unsigned char)((xred + yred)/2);
|
||||
*(gp++) = (unsigned char)((xgreen + ygreen)/2);
|
||||
*(bp++) = (unsigned char)((xblue + yblue)/2);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static RImage*
|
||||
renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0,
|
||||
int rf, int gf, int bf)
|
||||
{
|
||||
RImage *image, *tmp;
|
||||
float a;
|
||||
int i, offset;
|
||||
|
||||
if (width == 1)
|
||||
return renderVGradient(width, height, r0, g0, b0, rf, gf, bf);
|
||||
else if (height == 1)
|
||||
return renderHGradient(width, height, r0, g0, b0, rf, gf, bf);
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp = renderHGradient(2*width-1, 1, r0, g0, b0, rf, gf, bf);
|
||||
if (!tmp) {
|
||||
RDestroyImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
a = ((float)(width - 1))/((float)(height - 1));
|
||||
|
||||
/* copy the first line to the other lines with corresponding offset */
|
||||
for (i=0; i<height; i++) {
|
||||
offset = (int)(a*i+0.5);
|
||||
memcpy(&(image->data[0][i*width]), &(tmp->data[0][offset]), width);
|
||||
memcpy(&(image->data[1][i*width]), &(tmp->data[1][offset]), width);
|
||||
memcpy(&(image->data[2][i*width]), &(tmp->data[2][offset]), width);
|
||||
}
|
||||
RDestroyImage(tmp);
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
static RImage*
|
||||
renderMHGradient(unsigned width, unsigned height, RColor **colors, int count)
|
||||
{
|
||||
int i, j, k;
|
||||
unsigned long r, g, b, dr, dg, db;
|
||||
RImage *image;
|
||||
unsigned char *rp, *gp, *bp;
|
||||
unsigned width2;
|
||||
|
||||
|
||||
assert(count > 2);
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
rp = image->data[0];
|
||||
gp = image->data[1];
|
||||
bp = image->data[2];
|
||||
|
||||
if (count > width)
|
||||
count = width;
|
||||
|
||||
if (count > 1)
|
||||
width2 = width/(count-1);
|
||||
else
|
||||
width2 = width;
|
||||
|
||||
k = 0;
|
||||
|
||||
r = colors[0]->red << 16;
|
||||
g = colors[0]->green << 16;
|
||||
b = colors[0]->blue << 16;
|
||||
|
||||
/* render the first line */
|
||||
for (i=1; i<count; i++) {
|
||||
dr = ((int)(colors[i]->red - colors[i-1]->red) <<16)/(int)width2;
|
||||
dg = ((int)(colors[i]->green - colors[i-1]->green)<<16)/(int)width2;
|
||||
db = ((int)(colors[i]->blue - colors[i-1]->blue) <<16)/(int)width2;
|
||||
for (j=0; j<width2; j++) {
|
||||
*(rp++) = (unsigned char)(r>>16);
|
||||
*(gp++) = (unsigned char)(g>>16);
|
||||
*(bp++) = (unsigned char)(b>>16);
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
k++;
|
||||
}
|
||||
r = colors[i]->red << 16;
|
||||
g = colors[i]->green << 16;
|
||||
b = colors[i]->blue << 16;
|
||||
}
|
||||
for (j=k; j<width; j++) {
|
||||
*(rp++) = (unsigned char)(r>>16);
|
||||
*(gp++) = (unsigned char)(g>>16);
|
||||
*(bp++) = (unsigned char)(b>>16);
|
||||
}
|
||||
|
||||
/* copy the first line to the other lines */
|
||||
for (i=1; i<height; i++) {
|
||||
memcpy(&(image->data[0][i*width]), image->data[0], width);
|
||||
memcpy(&(image->data[1][i*width]), image->data[1], width);
|
||||
memcpy(&(image->data[2][i*width]), image->data[2], width);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static RImage*
|
||||
renderMVGradient(unsigned width, unsigned height, RColor **colors, int count)
|
||||
{
|
||||
int i, j, k;
|
||||
unsigned long r, g, b, dr, dg, db;
|
||||
RImage *image;
|
||||
unsigned char *rp, *gp, *bp;
|
||||
unsigned height2;
|
||||
|
||||
|
||||
assert(count > 2);
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
rp = image->data[0];
|
||||
gp = image->data[1];
|
||||
bp = image->data[2];
|
||||
|
||||
if (count > height)
|
||||
count = height;
|
||||
|
||||
if (count > 1)
|
||||
height2 = height/(count-1);
|
||||
else
|
||||
height2 = height;
|
||||
|
||||
k = 0;
|
||||
|
||||
r = colors[0]->red << 16;
|
||||
g = colors[0]->green << 16;
|
||||
b = colors[0]->blue << 16;
|
||||
|
||||
for (i=1; i<count; i++) {
|
||||
dr = ((int)(colors[i]->red - colors[i-1]->red) <<16)/(int)height2;
|
||||
dg = ((int)(colors[i]->green - colors[i-1]->green)<<16)/(int)height2;
|
||||
db = ((int)(colors[i]->blue - colors[i-1]->blue) <<16)/(int)height2;
|
||||
for (j=0; j<height2; j++) {
|
||||
memset(rp, (unsigned char)(r>>16), width);
|
||||
memset(gp, (unsigned char)(g>>16), width);
|
||||
memset(bp, (unsigned char)(b>>16), width);
|
||||
rp+=width;
|
||||
gp+=width;
|
||||
bp+=width;
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
k++;
|
||||
}
|
||||
r = colors[i]->red << 16;
|
||||
g = colors[i]->green << 16;
|
||||
b = colors[i]->blue << 16;
|
||||
}
|
||||
for (j=k; j<height; j++) {
|
||||
memset(rp, (unsigned char)(r>>16), width);
|
||||
memset(gp, (unsigned char)(g>>16), width);
|
||||
memset(bp, (unsigned char)(b>>16), width);
|
||||
rp+=width;
|
||||
gp+=width;
|
||||
bp+=width;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
static RImage*
|
||||
renderMDGradient(unsigned width, unsigned height, RColor **colors, int count)
|
||||
{
|
||||
RImage *image, *tmp;
|
||||
float a;
|
||||
int i, offset;
|
||||
|
||||
assert(count > 2);
|
||||
|
||||
if (width == 1)
|
||||
return renderMVGradient(width, height, colors, count);
|
||||
else if (height == 1)
|
||||
return renderMHGradient(width, height, colors, count);
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (count > width)
|
||||
count = width;
|
||||
if (count > height)
|
||||
count = height;
|
||||
|
||||
if (count > 2)
|
||||
tmp = renderMHGradient(2*width-1, 1, colors, count);
|
||||
else
|
||||
tmp = renderHGradient(2*width-1, 1, colors[0]->red<<8,
|
||||
colors[0]->green<<8, colors[0]->blue<<8,
|
||||
colors[1]->red<<8, colors[1]->green<<8,
|
||||
colors[1]->blue<<8);
|
||||
|
||||
if (!tmp) {
|
||||
RDestroyImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
a = ((float)(width - 1))/((float)(height - 1));
|
||||
|
||||
/* copy the first line to the other lines with corresponding offset */
|
||||
for (i=0; i<height; i++) {
|
||||
offset = (int)(a*i+0.5);
|
||||
memcpy(&(image->data[0][i*width]), &(tmp->data[0][offset]), width);
|
||||
memcpy(&(image->data[1][i*width]), &(tmp->data[1][offset]), width);
|
||||
memcpy(&(image->data[2][i*width]), &(tmp->data[2][offset]), width);
|
||||
}
|
||||
RDestroyImage(tmp);
|
||||
return image;
|
||||
}
|
||||
181
wrlib/jpeg.c
Normal file
181
wrlib/jpeg.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/* jpeg.c - load JPEG image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef USE_JPEG
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <jpeglib.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
/*
|
||||
* <setjmp.h> is used for the optional error recovery mechanism shown in
|
||||
* the second part of the example.
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
/*
|
||||
* ERROR HANDLING:
|
||||
*
|
||||
* The JPEG library's standard error handler (jerror.c) is divided into
|
||||
* several "methods" which you can override individually. This lets you
|
||||
* adjust the behavior without duplicating a lot of code, which you might
|
||||
* have to update with each future release.
|
||||
*
|
||||
* Our example here shows how to override the "error_exit" method so that
|
||||
* control is returned to the library's caller when a fatal error occurs,
|
||||
* rather than calling exit() as the standard error_exit method does.
|
||||
*
|
||||
* We use C's setjmp/longjmp facility to return control. This means that the
|
||||
* routine which calls the JPEG library must first execute a setjmp() call to
|
||||
* establish the return point. We want the replacement error_exit to do a
|
||||
* longjmp(). But we need to make the setjmp buffer accessible to the
|
||||
* error_exit routine. To do this, we make a private extension of the
|
||||
* standard JPEG error handler object. (If we were using C++, we'd say we
|
||||
* were making a subclass of the regular error handler.)
|
||||
*
|
||||
* Here's the extended error handler struct:
|
||||
*/
|
||||
|
||||
struct my_error_mgr {
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
};
|
||||
|
||||
typedef struct my_error_mgr * my_error_ptr;
|
||||
|
||||
/*
|
||||
* Here's the routine that will replace the standard error_exit method:
|
||||
*/
|
||||
|
||||
void
|
||||
my_error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
||||
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadJPEG(RContext *context, char *file_name, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
int i, j;
|
||||
unsigned char *r, *g, *b;
|
||||
JSAMPROW buffer[1];
|
||||
FILE *file;
|
||||
/* We use our private extension JPEG error handler.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
struct my_error_mgr jerr;
|
||||
|
||||
file = fopen(file_name, "r");
|
||||
if (!file) {
|
||||
sprintf(RErrorString, "could not open JPEG file \"%s\"", file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object, close the input file, and return.
|
||||
*/
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_stdio_src(&cinfo, file);
|
||||
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
|
||||
if (!buffer[0]) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
goto bye;
|
||||
}
|
||||
|
||||
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
goto bye;
|
||||
}
|
||||
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
cinfo.quantize_colors = FALSE;
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
|
||||
while (cinfo.output_scanline < cinfo.image_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||
for (i=0,j=0; i<cinfo.image_width; i++) {
|
||||
*(r++) = buffer[0][j++];
|
||||
*(g++) = buffer[0][j++];
|
||||
*(b++) = buffer[0][j++];
|
||||
}
|
||||
}
|
||||
/*
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
*/
|
||||
bye:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
fclose(file);
|
||||
|
||||
if (buffer[0])
|
||||
free(buffer[0]);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_JPEG */
|
||||
384
wrlib/load.c
Normal file
384
wrlib/load.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/* load.c - load image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef USE_PNG
|
||||
#include <png.h>
|
||||
#endif
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
typedef struct RCachedImage {
|
||||
RImage *image;
|
||||
char *file;
|
||||
time_t last_modif; /* last time file was modified */
|
||||
time_t last_use; /* last time image was used */
|
||||
} RCachedImage;
|
||||
|
||||
|
||||
/*
|
||||
* Size of image cache
|
||||
*/
|
||||
static int RImageCacheSize = -1;
|
||||
|
||||
/*
|
||||
* Max. size of image to store in cache
|
||||
*/
|
||||
static int RImageCacheMaxImage = -1; /* 0 = any size */
|
||||
|
||||
#define IMAGE_CACHE_SIZE 8
|
||||
|
||||
#define IMAGE_CACHE_MAX_IMAGE 64*64
|
||||
|
||||
static RCachedImage *RImageCache;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define IM_ERROR -1
|
||||
#define IM_UNKNOWN 0
|
||||
#define IM_XPM 1
|
||||
#define IM_TIFF 2
|
||||
#define IM_PNG 3
|
||||
#define IM_PPM 4
|
||||
#define IM_JPEG 5
|
||||
#define IM_GIF 6
|
||||
/* How many image types do we have. */
|
||||
/* Increase this when adding new image types! */
|
||||
#define IM_TYPES 6
|
||||
|
||||
|
||||
static int identFile(char *path);
|
||||
|
||||
extern RImage *RLoadPPM(RContext *context, char *file_name, int index);
|
||||
|
||||
extern RImage *RLoadXPM(RContext *context, char *file, int index);
|
||||
|
||||
|
||||
#ifdef USE_TIFF
|
||||
extern RImage *RLoadTIFF(RContext *context, char *file, int index);
|
||||
#endif
|
||||
#ifdef USE_PNG
|
||||
extern RImage *RLoadPNG(RContext *context, char *file, int index);
|
||||
#endif
|
||||
#ifdef USE_JPEG
|
||||
extern RImage *RLoadJPEG(RContext *context, char *file_name, int index);
|
||||
#endif
|
||||
#ifdef USE_GIF
|
||||
extern RImage *RLoadGIF(RContext *context, char *file_name, int index);
|
||||
#endif
|
||||
|
||||
|
||||
static char*
|
||||
wstrdup(char *s)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = malloc(strlen(s)+1);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
return strcpy(tmp, s);
|
||||
}
|
||||
|
||||
char**
|
||||
RSupportedFileFormats(void)
|
||||
{
|
||||
char **tmp;
|
||||
int i = 0;
|
||||
|
||||
tmp = malloc(sizeof(char*)*(IM_TYPES+1));
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
memset(tmp, 0, sizeof(char*)*(IM_TYPES+1));
|
||||
|
||||
/* built-in */
|
||||
tmp[i++] = wstrdup("XPM");
|
||||
if (!tmp[i-1]) {
|
||||
RFreeStringList(tmp);
|
||||
return NULL;
|
||||
}
|
||||
/* built-in */
|
||||
tmp[i++] = wstrdup("PPM");
|
||||
if (!tmp[i-1]) {
|
||||
RFreeStringList(tmp);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef USE_TIFF
|
||||
tmp[i++] = wstrdup("TIFF");
|
||||
if (!tmp[i-1]) {
|
||||
RFreeStringList(tmp);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_PNG
|
||||
tmp[i++] = wstrdup("PNG");
|
||||
if (!tmp[i-1]) {
|
||||
RFreeStringList(tmp);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_JPEG
|
||||
tmp[i++] = wstrdup("JPEG");
|
||||
if (!tmp[i-1]) {
|
||||
RFreeStringList(tmp);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_GIF
|
||||
tmp[i++] = wstrdup("GIF");
|
||||
if (!tmp[i-1]) {
|
||||
RFreeStringList(tmp);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
tmp[i] = NULL;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RFreeStringList(char **list)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; list[i]!=NULL; i++) {
|
||||
free(list[i]);
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_cache()
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = getenv("RIMAGE_CACHE");
|
||||
if (!tmp || sscanf(tmp, "%i", &RImageCacheSize)!=1) {
|
||||
RImageCacheSize = IMAGE_CACHE_SIZE;
|
||||
}
|
||||
if (RImageCacheSize<0)
|
||||
RImageCacheSize = 0;
|
||||
|
||||
tmp = getenv("RIMAGE_CACHE_SIZE");
|
||||
if (!tmp || sscanf(tmp, "%i", &RImageCacheMaxImage)!=1) {
|
||||
RImageCacheMaxImage = IMAGE_CACHE_MAX_IMAGE;
|
||||
}
|
||||
|
||||
if (RImageCacheSize>0) {
|
||||
RImageCache = malloc(sizeof(RCachedImage)*RImageCacheSize);
|
||||
if (RImageCache==NULL) {
|
||||
printf("wrlib: out of memory for image cache\n");
|
||||
return;
|
||||
}
|
||||
memset(RImageCache, 0, sizeof(RCachedImage)*RImageCacheSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadImage(RContext *context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
int i;
|
||||
struct stat st;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
if (RImageCacheSize<0) {
|
||||
init_cache();
|
||||
}
|
||||
|
||||
if (RImageCacheSize>0) {
|
||||
|
||||
for (i=0; i<RImageCacheSize; i++) {
|
||||
if (RImageCache[i].file
|
||||
&& strcmp(file, RImageCache[i].file)==0) {
|
||||
|
||||
if (stat(file, &st)==0
|
||||
&& st.st_mtime == RImageCache[i].last_modif) {
|
||||
RImageCache[i].last_use = time(NULL);
|
||||
|
||||
return RCloneImage(RImageCache[i].image);
|
||||
|
||||
} else {
|
||||
free(RImageCache[i].file);
|
||||
RImageCache[i].file = NULL;
|
||||
RDestroyImage(RImageCache[i].image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (identFile(file)) {
|
||||
case IM_ERROR:
|
||||
sprintf(RErrorString, "error opening file");
|
||||
return NULL;
|
||||
|
||||
case IM_UNKNOWN:
|
||||
sprintf(RErrorString, "unknown image format");
|
||||
return NULL;
|
||||
|
||||
case IM_XPM:
|
||||
image = RLoadXPM(context, file, index);
|
||||
break;
|
||||
|
||||
#ifdef USE_TIFF
|
||||
case IM_TIFF:
|
||||
image = RLoadTIFF(context, file, index);
|
||||
break;
|
||||
#endif /* USE_TIFF */
|
||||
|
||||
#ifdef USE_PNG
|
||||
case IM_PNG:
|
||||
image = RLoadPNG(context, file, index);
|
||||
break;
|
||||
#endif /* USE_PNG */
|
||||
|
||||
#ifdef USE_JPEG
|
||||
case IM_JPEG:
|
||||
image = RLoadJPEG(context, file, index);
|
||||
break;
|
||||
#endif /* USE_JPEG */
|
||||
|
||||
#ifdef USE_GIF
|
||||
case IM_GIF:
|
||||
image = RLoadGIF(context, file, index);
|
||||
break;
|
||||
#endif /* USE_GIF */
|
||||
|
||||
case IM_PPM:
|
||||
image = RLoadPPM(context, file, index);
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(RErrorString, "unsupported image format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* store image in cache */
|
||||
if (RImageCacheSize>0 && image &&
|
||||
(RImageCacheMaxImage==0
|
||||
|| RImageCacheMaxImage >= image->width*image->height)) {
|
||||
time_t oldest=time(NULL);
|
||||
int oldest_idx = 0;
|
||||
int done = 0;
|
||||
|
||||
for (i=0; i<RImageCacheSize; i++) {
|
||||
if (!RImageCache[i].file) {
|
||||
RImageCache[i].file = malloc(strlen(file)+1);
|
||||
strcpy(RImageCache[i].file, file);
|
||||
RImageCache[i].image = RCloneImage(image);
|
||||
RImageCache[i].last_modif = st.st_mtime;
|
||||
RImageCache[i].last_use = time(NULL);
|
||||
done = 1;
|
||||
break;
|
||||
} else {
|
||||
if (oldest > RImageCache[i].last_use) {
|
||||
oldest = RImageCache[i].last_use;
|
||||
oldest_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if no slot available, dump least recently used one */
|
||||
if (!done) {
|
||||
free(RImageCache[oldest_idx].file);
|
||||
RDestroyImage(RImageCache[oldest_idx].image);
|
||||
RImageCache[oldest_idx].file = malloc(strlen(file)+1);
|
||||
strcpy(RImageCache[oldest_idx].file, file);
|
||||
RImageCache[oldest_idx].image = RCloneImage(image);
|
||||
RImageCache[oldest_idx].last_modif = st.st_mtime;
|
||||
RImageCache[oldest_idx].last_use = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
identFile(char *path)
|
||||
{
|
||||
int fd;
|
||||
unsigned char buffer[32];
|
||||
|
||||
if (!path)
|
||||
return IM_ERROR;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return IM_ERROR;
|
||||
if (read(fd, buffer, 32)<1) {
|
||||
close(fd);
|
||||
return IM_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/* check for XPM */
|
||||
if (strncmp((char*)buffer, "/* XPM */", 9)==0)
|
||||
return IM_XPM;
|
||||
|
||||
/* check for TIFF */
|
||||
if ((buffer[0]=='I' && buffer[1]=='I' && buffer[2]=='*' && buffer[3]==0)
|
||||
||(buffer[0]=='M' && buffer[1]=='M' && buffer[2]==0 && buffer[3]=='*'))
|
||||
return IM_TIFF;
|
||||
|
||||
#ifdef USE_PNG
|
||||
/* check for PNG */
|
||||
if (png_check_sig(buffer, 8))
|
||||
return IM_PNG;
|
||||
#endif
|
||||
|
||||
/* check for raw PPM or PGM */
|
||||
if (buffer[0]=='P' && (buffer[1]=='5' || buffer[1]=='6'))
|
||||
return IM_PPM;
|
||||
|
||||
/* check for JPEG */
|
||||
if (buffer[0] == 0xff && buffer[1] == 0xd8)
|
||||
return IM_JPEG;
|
||||
|
||||
/* check for GIF */
|
||||
if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F')
|
||||
return IM_GIF;
|
||||
|
||||
return IM_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
131
wrlib/misc.c
Normal file
131
wrlib/misc.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
int
|
||||
RBevelImage(RImage *image, int bevel_type)
|
||||
{
|
||||
RColor color;
|
||||
RColor cdelta;
|
||||
int w, h;
|
||||
|
||||
if (image->width<3 || image->height<3)
|
||||
return False;
|
||||
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
if (bevel_type>0) { /* raised */
|
||||
/* top */
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
ROperateLine(image, RAddOperation, 0, 0, w-1, 0, &cdelta);
|
||||
if (bevel_type==RBEV_RAISED3 && w>3)
|
||||
ROperateLine(image, RAddOperation, 1, 1, w-3, 1,&cdelta);
|
||||
|
||||
/* left */
|
||||
ROperateLine(image, RAddOperation, 0, 1, 0, h-1, &cdelta);
|
||||
if (bevel_type==RBEV_RAISED3 && h>3)
|
||||
ROperateLine(image, RAddOperation, 1, 2, 1, h-3, &cdelta);
|
||||
|
||||
/* bottom */
|
||||
color.alpha = 255;
|
||||
color.red = color.green = color.blue = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
if (bevel_type==RBEV_RAISED2 || bevel_type==RBEV_RAISED3) {
|
||||
ROperateLine(image, RSubtractOperation, 0, h-2, w-3,
|
||||
h-2, &cdelta);
|
||||
RDrawLine(image, 0, h-1, w-1, h-1, &color);
|
||||
} else {
|
||||
ROperateLine(image, RSubtractOperation, 0, h-1, w-1, h-1,
|
||||
&cdelta);
|
||||
}
|
||||
|
||||
/* right */
|
||||
if (bevel_type==RBEV_RAISED2 || bevel_type==RBEV_RAISED3) {
|
||||
ROperateLine(image, RSubtractOperation, w-2, 0, w-2, h-2,
|
||||
&cdelta);
|
||||
RDrawLine(image, w-1, 0, w-1, h-2, &color);
|
||||
} else {
|
||||
ROperateLine(image, RSubtractOperation, w-1, 0, w-1, h-2,
|
||||
&cdelta);
|
||||
}
|
||||
} else { /* sunken */
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
ROperateLine(image, RSubtractOperation, 0, 0, w-1, 0,
|
||||
&cdelta); /* top */
|
||||
ROperateLine(image, RSubtractOperation, 0, 1, 0, h-1,
|
||||
&cdelta); /* left */
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
ROperateLine(image, RAddOperation, 0, h-1, w-1, h-1, &cdelta); /* bottom */
|
||||
ROperateLine(image, RAddOperation, w-1, 0, w-1, h-2, &cdelta); /* right */
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RClearImage(RImage *image, RColor *color)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
bytes = image->width*image->height;
|
||||
|
||||
if (color->alpha==255) {
|
||||
memset(image->data[0], color->red, bytes);
|
||||
memset(image->data[1], color->green, bytes);
|
||||
memset(image->data[2], color->blue, bytes);
|
||||
if (image->data[3])
|
||||
memset(image->data[3], 0xff, bytes);
|
||||
} else {
|
||||
register int i;
|
||||
unsigned char *dr, *dg, *db;
|
||||
int alpha, nalpha, r, g, b;
|
||||
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
|
||||
r = color->red;
|
||||
g = color->green;
|
||||
b = color->blue;
|
||||
alpha = color->alpha;
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
for (i=0; i<bytes; i++) {
|
||||
*dr = (((int)*dr * nalpha) + (r * alpha))/256;
|
||||
*dg = (((int)*dg * nalpha) + (g * alpha))/256;
|
||||
*db = (((int)*db * nalpha) + (b * alpha))/256;
|
||||
dr++; dg++; db++;
|
||||
}
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
413
wrlib/nxpm.c
Normal file
413
wrlib/nxpm.c
Normal file
@@ -0,0 +1,413 @@
|
||||
/* nxpm.c - load "normalized" XPM image
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef __GNUC__
|
||||
# define alloca __builtin_alloca
|
||||
#else
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
# pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
/*
|
||||
* Restricted support for XPM images.
|
||||
*
|
||||
* The images must be in the following "normalized" format:
|
||||
*
|
||||
*
|
||||
* line content
|
||||
* 1 signature comment
|
||||
* 2 ignored ( normally "static char *xpm[] = {" )
|
||||
* 3 "width height color_count chars" where chars is 1 or 2
|
||||
* 4 color definitions. Only c values with #rrggbb or #rrrrggggbbb
|
||||
* format OR None
|
||||
* n data
|
||||
*
|
||||
* - no comments or blank lines are allowed, except for the signature
|
||||
* - all lines must have at most 256 characters
|
||||
* - no white spaces allowed at left of each line
|
||||
*/
|
||||
|
||||
#define LINEWIDTH 64
|
||||
|
||||
#ifndef USE_XPM
|
||||
|
||||
|
||||
RImage*
|
||||
RGetImageFromXPMData(RContext *context, char **data)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
unsigned char *color_table[4];
|
||||
unsigned short *symbol_table;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
int i, j, k, line = 0;
|
||||
int transp;
|
||||
unsigned short color;
|
||||
int bsize;
|
||||
int w, h, ccount, csize;
|
||||
|
||||
if (sscanf(data[line++], "%i %i %i %i", &w, &h, &ccount, &csize)!=4
|
||||
|| w <= 0 || h <= 0 || ccount <= 0 || csize <= 0)
|
||||
goto bad_format;
|
||||
|
||||
if (csize!=1 && csize!=2)
|
||||
goto bad_format;
|
||||
|
||||
color_table[0] = alloca(ccount);
|
||||
color_table[1] = alloca(ccount);
|
||||
color_table[2] = alloca(ccount);
|
||||
color_table[3] = alloca(ccount);
|
||||
symbol_table = alloca(ccount * sizeof(unsigned short));
|
||||
|
||||
bsize = csize * w + 16;
|
||||
|
||||
if (!color_table[0] || !color_table[1] || !color_table[2] ||
|
||||
!color_table[3] || !symbol_table || !bsize) {
|
||||
sprintf(RErrorString, "out of memory while converting XPM data");
|
||||
alloca(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transp = 0;
|
||||
/* get color table */
|
||||
for (i=0; i<ccount; i++) {
|
||||
symbol_table[i] = data[line][0];
|
||||
if (csize==2)
|
||||
symbol_table[i] |= data[line][1]<<8;
|
||||
|
||||
j = csize;
|
||||
while (data[line][j]!='#' && data[line][j]!=0
|
||||
&& data[line][j]!='N') j++;
|
||||
|
||||
if (data[line][j]=='#') {
|
||||
unsigned int red, green, blue;
|
||||
|
||||
k = 0;
|
||||
j++;
|
||||
while (data[line][j+k]!=0) k++;
|
||||
if (k==6) {
|
||||
if (sscanf(&(data[line][j]), "%2x%2x%2x", &red, &green, &blue)!=3)
|
||||
goto bad_format;
|
||||
} else if (k==12) {
|
||||
if (sscanf(&(data[line][j]), "%4x%4x%4x", &red, &green, &blue)!=3)
|
||||
goto bad_format;
|
||||
red >>= 8;
|
||||
green >>= 8;
|
||||
blue >>= 8;
|
||||
} else
|
||||
goto bad_format;
|
||||
|
||||
color_table[0][i] = red;
|
||||
color_table[1][i] = green;
|
||||
color_table[2][i] = blue;
|
||||
color_table[3][i] = 255;
|
||||
} else if (strncmp(&(data[line][j]), "None", 4)==0) {
|
||||
color_table[3][i] = 0;
|
||||
transp = 1;
|
||||
} else {
|
||||
goto bad_format;
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
||||
image = RCreateImage(w, h, transp);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory while converting XPM data");
|
||||
alloca(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
for (i=0; i<h; i++) {
|
||||
if (csize==1) {
|
||||
for (j=0; j<w; j++) {
|
||||
color = data[line][j];
|
||||
|
||||
for (k=0; k<ccount; k++) {
|
||||
if (symbol_table[k] == color)
|
||||
break;
|
||||
}
|
||||
if (k==ccount)
|
||||
k = 0;
|
||||
|
||||
*(r++) = color_table[0][k];
|
||||
*(g++) = color_table[1][k];
|
||||
*(b++) = color_table[2][k];
|
||||
if (a)
|
||||
*(a++) = color_table[3][k];
|
||||
}
|
||||
} else {
|
||||
for (j=0; j<w*2; j++) {
|
||||
color = data[line][j++];
|
||||
color |= data[line][j];
|
||||
|
||||
for (k=0; k<ccount; k++) {
|
||||
if (symbol_table[k] == color)
|
||||
break;
|
||||
}
|
||||
if (k==ccount)
|
||||
k = 0;
|
||||
|
||||
*(r++) = color_table[0][k];
|
||||
*(g++) = color_table[1][k];
|
||||
*(b++) = color_table[2][k];
|
||||
if (a)
|
||||
*(a++) = color_table[3][k];
|
||||
}
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return image;
|
||||
|
||||
bad_format:
|
||||
sprintf(RErrorString, "XPM data is not in the normalized format");
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
if (image)
|
||||
RDestroyImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadXPM(RContext *context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
char line[LINEWIDTH+1];
|
||||
char *buffer;
|
||||
unsigned char *color_table[4];
|
||||
unsigned short *symbol_table;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
int i, j, k;
|
||||
int transp;
|
||||
unsigned short color;
|
||||
int bsize;
|
||||
int w, h, ccount, csize;
|
||||
FILE *f;
|
||||
|
||||
f = fopen(file, "r");
|
||||
if (!f) {
|
||||
sprintf(RErrorString, "can't open XPM file \"%s\"", file);
|
||||
return NULL;
|
||||
}
|
||||
/* sig */
|
||||
if (!fgets(line, LINEWIDTH, f))
|
||||
goto bad_file;
|
||||
/* declaration */
|
||||
if (!fgets(line, LINEWIDTH, f))
|
||||
goto bad_file;
|
||||
|
||||
/* data */
|
||||
if (!fgets(line, LINEWIDTH, f))
|
||||
goto bad_file;
|
||||
|
||||
if (line[0]=='/')
|
||||
if (!fgets(line, LINEWIDTH, f))
|
||||
goto bad_file;
|
||||
|
||||
if (sscanf(line, "\"%i %i %i %i\"", &w, &h, &ccount, &csize)!=4
|
||||
|| w <= 0 || h <= 0 || ccount <= 0 || csize <= 0)
|
||||
goto bad_file;
|
||||
|
||||
if (csize!=1 && csize!=2)
|
||||
goto bad_format;
|
||||
|
||||
color_table[0] = alloca(ccount);
|
||||
color_table[1] = alloca(ccount);
|
||||
color_table[2] = alloca(ccount);
|
||||
color_table[3] = alloca(ccount);
|
||||
symbol_table = alloca(ccount * sizeof(unsigned short));
|
||||
|
||||
bsize = csize * w + 16;
|
||||
buffer = alloca(bsize);
|
||||
|
||||
if (!color_table[0] || !color_table[1] || !color_table[2] ||
|
||||
!color_table[3] || !symbol_table || !bsize) {
|
||||
sprintf(RErrorString, "out of memory while loading XPM file \"%s\"",
|
||||
file);
|
||||
fclose(f);
|
||||
alloca(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transp = 0;
|
||||
/* get color table */
|
||||
for (i=0; i<ccount; i++) {
|
||||
if (!fgets(line, LINEWIDTH, f))
|
||||
goto bad_file;
|
||||
if (line[0]=='/')
|
||||
if (!fgets(line, LINEWIDTH, f))
|
||||
goto bad_file;
|
||||
|
||||
symbol_table[i] = line[1];
|
||||
if (csize==2)
|
||||
symbol_table[i] |= line[2]<<8;
|
||||
|
||||
j = csize+1;
|
||||
while (line[j]!='#' && line[j]!='"' && line[j]!=0 && line[j]!='N') j++;
|
||||
|
||||
if (line[j]=='#') {
|
||||
unsigned int red, green, blue;
|
||||
|
||||
k = 0;
|
||||
j++;
|
||||
while (line[j+k]!='"' && line[j+k]!=0) k++;
|
||||
if (k==6) {
|
||||
if (sscanf(&(line[j]), "%2x%2x%2x", &red, &green, &blue)!=3)
|
||||
goto bad_format;
|
||||
} else if (k==12) {
|
||||
if (sscanf(&(line[j]), "%4x%4x%4x", &red, &green, &blue)!=3)
|
||||
goto bad_format;
|
||||
red >>= 8;
|
||||
green >>= 8;
|
||||
blue >>= 8;
|
||||
} else
|
||||
goto bad_format;
|
||||
|
||||
color_table[0][i] = red;
|
||||
color_table[1][i] = green;
|
||||
color_table[2][i] = blue;
|
||||
color_table[3][i] = 255;
|
||||
} else if (strncmp(&(line[j]), "None", 4)==0) {
|
||||
color_table[3][i] = 0;
|
||||
transp = 1;
|
||||
} else {
|
||||
goto bad_format;
|
||||
}
|
||||
}
|
||||
|
||||
image = RCreateImage(w, h, transp);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory while loading XPM file \"%s\"",
|
||||
file);
|
||||
fclose(f);
|
||||
alloca(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
for (i=0; i<h; i++) {
|
||||
if (!fgets(buffer, bsize, f))
|
||||
goto bad_file;
|
||||
if (buffer[0]=='/')
|
||||
if (!fgets(buffer, bsize, f))
|
||||
goto bad_file;
|
||||
|
||||
if (csize==1) {
|
||||
for (j=1; j<=w; j++) {
|
||||
color = buffer[j];
|
||||
|
||||
for (k=0; k<ccount; k++) {
|
||||
if (symbol_table[k] == color)
|
||||
break;
|
||||
}
|
||||
if (k==ccount)
|
||||
k = 0;
|
||||
|
||||
*(r++) = color_table[0][k];
|
||||
*(g++) = color_table[1][k];
|
||||
*(b++) = color_table[2][k];
|
||||
if (a)
|
||||
*(a++) = color_table[3][k];
|
||||
}
|
||||
} else {
|
||||
for (j=1; j<=w*2; j++) {
|
||||
color = buffer[j++];
|
||||
color |= buffer[j] << 8;
|
||||
|
||||
for (k=0; k<ccount; k++) {
|
||||
if (symbol_table[k] == color)
|
||||
break;
|
||||
}
|
||||
if (k==ccount) {
|
||||
k = 0;
|
||||
}
|
||||
|
||||
*(r++) = color_table[0][k];
|
||||
*(g++) = color_table[1][k];
|
||||
*(b++) = color_table[2][k];
|
||||
if (a)
|
||||
*(a++) = color_table[3][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return image;
|
||||
|
||||
bad_format:
|
||||
sprintf(RErrorString, "XPM file \"%s\" is not in the normalized format", file);
|
||||
fclose(f);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
if (image)
|
||||
RDestroyImage(image);
|
||||
return NULL;
|
||||
|
||||
bad_file:
|
||||
sprintf(RErrorString, "bad XPM file \"%s\"", file);
|
||||
fclose(f);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
if (image)
|
||||
RDestroyImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
243
wrlib/png.c
Normal file
243
wrlib/png.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/* png.c - load PNG image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef __GNUC__
|
||||
# define alloca __builtin_alloca
|
||||
#else
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
# pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_PNG
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <png.h>
|
||||
|
||||
#if PNG_LIBPNG_VER < 96
|
||||
#error libpng_must_be_more_at_least_0_96
|
||||
#endif
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadPNG(RContext *context, char *file, int index)
|
||||
{
|
||||
char *tmp;
|
||||
RImage *image=NULL;
|
||||
FILE *f;
|
||||
png_structp png;
|
||||
png_infop pinfo, einfo;
|
||||
png_color_16p bkcolor;
|
||||
int alpha;
|
||||
int x, y, i;
|
||||
double gamma, sgamma;
|
||||
png_uint_32 width, height;
|
||||
int depth, junk, color_type;
|
||||
png_bytep *png_rows;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
|
||||
f = fopen(file, "r");
|
||||
if (!f) {
|
||||
sprintf(RErrorString, "could not open file \"%s\"", file);
|
||||
return NULL;
|
||||
}
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||
(png_error_ptr)NULL, (png_error_ptr)NULL);
|
||||
if (!png) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pinfo = png_create_info_struct(png);
|
||||
if (!pinfo) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
einfo = png_create_info_struct(png);
|
||||
if (!einfo) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (setjmp(png->jmpbuf)) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
if (image)
|
||||
RDestroyImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
png_init_io(png, f);
|
||||
|
||||
png_read_info(png, pinfo);
|
||||
|
||||
png_get_IHDR(png, pinfo, &width, &height, &depth, &color_type,
|
||||
&junk, &junk, &junk);
|
||||
|
||||
|
||||
/* check for an alpha channel */
|
||||
if (png_get_valid(png, pinfo, PNG_INFO_tRNS))
|
||||
alpha = True;
|
||||
else
|
||||
alpha = (color_type & PNG_COLOR_MASK_ALPHA);
|
||||
|
||||
/* allocate RImage */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "could not create RImage");
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* normalize to 8bpp with alpha channel */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && depth < 8)
|
||||
png_set_expand(png);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
|
||||
png_set_expand(png);
|
||||
|
||||
if (png_get_valid(png, pinfo, PNG_INFO_tRNS))
|
||||
png_set_expand(png);
|
||||
|
||||
if (depth == 16)
|
||||
png_set_strip_16(png);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png);
|
||||
|
||||
/* set gamma correction */
|
||||
if ((context->attribs->flags & RC_GammaCorrection)
|
||||
&& context->depth != 8) {
|
||||
sgamma = (context->attribs->rgamma + context->attribs->ggamma +
|
||||
context->attribs->bgamma) / 3;
|
||||
} else if ((tmp = getenv("DISPLAY_GAMMA")) != NULL) {
|
||||
sgamma = atof(tmp);
|
||||
if (sgamma==0)
|
||||
sgamma = 1;
|
||||
} else {
|
||||
sgamma = 2.0;
|
||||
}
|
||||
|
||||
if (png_get_gAMA(png, pinfo, &gamma))
|
||||
png_set_gamma(png, sgamma, gamma);
|
||||
else
|
||||
png_set_gamma(png, sgamma, 0.45);
|
||||
|
||||
/* do the transforms */
|
||||
png_read_update_info(png, pinfo);
|
||||
|
||||
/* set background color */
|
||||
if (png_get_bKGD(png, pinfo, &bkcolor)) {
|
||||
image->background.red = bkcolor->red >> 8;
|
||||
image->background.green = bkcolor->green >> 8;
|
||||
image->background.blue = bkcolor->blue >> 8;
|
||||
}
|
||||
|
||||
png_rows = alloca(sizeof(char*)*height);
|
||||
if (!png_rows) {
|
||||
sprintf(RErrorString, "out of memory loading \"%s\"", file);
|
||||
fclose(f);
|
||||
RDestroyImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
for (y=0; y<height; y++) {
|
||||
png_rows[y] = alloca(png_get_rowbytes(png, pinfo));
|
||||
if (!png_rows[y]) {
|
||||
sprintf(RErrorString, "out of memory loading \"%s\"", file);
|
||||
fclose(f);
|
||||
RDestroyImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* read data */
|
||||
png_read_image(png, png_rows);
|
||||
|
||||
png_read_end(png, einfo);
|
||||
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
|
||||
fclose(f);
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
/* convert to RImage */
|
||||
if (alpha) {
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0, i=0; x<width; x++) {
|
||||
*(r++) = *(png_rows[y]+i++);
|
||||
*(g++) = *(png_rows[y]+i++);
|
||||
*(b++) = *(png_rows[y]+i++);
|
||||
*(a++) = *(png_rows[y]+i++);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0, i=0; x<width; x++) {
|
||||
*(r++) = *(png_rows[y]+i++);
|
||||
*(g++) = *(png_rows[y]+i++);
|
||||
*(b++) = *(png_rows[y]+i++);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_PNG */
|
||||
172
wrlib/ppm.c
Normal file
172
wrlib/ppm.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/* ppm.c - load PPM image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
static RImage*
|
||||
load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
{
|
||||
RImage *image;
|
||||
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
if (!raw) {
|
||||
|
||||
} else {
|
||||
if (max<256) {
|
||||
if (!fgets(image->data[0], w*h, file))
|
||||
goto short_file;
|
||||
memcpy(image->data[0], image->data[1], w*h);
|
||||
memcpy(image->data[0], image->data[2], w*h);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
short_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static RImage*
|
||||
load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
{
|
||||
RImage *image;
|
||||
int i;
|
||||
char buf[3];
|
||||
char *r, *g, *b;
|
||||
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
if (!raw) {
|
||||
|
||||
} else {
|
||||
if (max<256) {
|
||||
i = 0;
|
||||
while (i < w*h) {
|
||||
if (fread(buf, 1, 3, file)!=3)
|
||||
goto short_file;
|
||||
*(r++) = buf[0];
|
||||
*(g++) = buf[1];
|
||||
*(b++) = buf[2];
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
|
||||
short_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadPPM(RContext *context, char *file_name, int index)
|
||||
{
|
||||
FILE *file;
|
||||
RImage *image = NULL;
|
||||
char buffer[256];
|
||||
int w, h, m;
|
||||
int type;
|
||||
|
||||
#define GETL() if (!fgets(buffer, 255, file)) goto short_file
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
file = fopen(file_name, "r");
|
||||
if (!file) {
|
||||
sprintf(RErrorString, "could not open PPM file \"%s\"", file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get signature */
|
||||
GETL();
|
||||
|
||||
/* only accept raw pixmaps or graymaps */
|
||||
if (buffer[0] != 'P' || (buffer[1] != '5' && buffer[1] != '6')) {
|
||||
sprintf(RErrorString, "unknown PPM format in \"%s\"", file_name);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = buffer[1];
|
||||
|
||||
/* skip comments */
|
||||
while (1) {
|
||||
GETL();
|
||||
|
||||
if (buffer[0]!='#')
|
||||
break;
|
||||
}
|
||||
|
||||
/* get size */
|
||||
if (sscanf(buffer, "%i %i", &w, &h)!=2)
|
||||
goto bad_file;
|
||||
|
||||
|
||||
GETL();
|
||||
if (sscanf(buffer, "%i", &m)!=1 || m < 1)
|
||||
goto bad_file;
|
||||
|
||||
if (type=='5')
|
||||
image = load_graymap(file_name, file, w, h, m, type=='5');
|
||||
else if (type=='6')
|
||||
image = load_pixmap(file_name, file, w, h, m, type=='6');
|
||||
|
||||
fclose(file);
|
||||
return image;
|
||||
|
||||
bad_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be corrupted", file_name);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
|
||||
short_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
529
wrlib/raster.c
Normal file
529
wrlib/raster.c
Normal file
@@ -0,0 +1,529 @@
|
||||
/* raster.c - main and other misc stuff
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define MAXERRLEN 512
|
||||
|
||||
|
||||
char *WRasterLibVersion="0.2";
|
||||
|
||||
char RErrorString[MAXERRLEN];
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RCreateImage(unsigned width, unsigned height, int alpha)
|
||||
{
|
||||
RImage *image=NULL;
|
||||
int i;
|
||||
|
||||
assert(width>0 && height>0);
|
||||
|
||||
image = malloc(sizeof(RImage));
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(image, 0, sizeof(RImage));
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
for (i=0; i<3+(alpha?1:0); i++) {
|
||||
image->data[i] = malloc(width*height);
|
||||
if (!image->data[i])
|
||||
goto error;
|
||||
}
|
||||
return image;
|
||||
|
||||
error:
|
||||
for (i=0; i<4; i++) {
|
||||
if (image->data[i])
|
||||
free(image->data[i]);
|
||||
}
|
||||
if (image)
|
||||
free(image);
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RCloneImage(RImage *image)
|
||||
{
|
||||
RImage *new_image;
|
||||
|
||||
assert(image!=NULL);
|
||||
|
||||
new_image = RCreateImage(image->width, image->height, image->data[3]!=NULL);
|
||||
if (!new_image)
|
||||
return NULL;
|
||||
|
||||
new_image->background = image->background;
|
||||
memcpy(new_image->data[0], image->data[0], image->width*image->height);
|
||||
memcpy(new_image->data[1], image->data[1], image->width*image->height);
|
||||
memcpy(new_image->data[2], image->data[2], image->width*image->height);
|
||||
if (image->data[3])
|
||||
memcpy(new_image->data[3], image->data[3], image->width*image->height);
|
||||
|
||||
return new_image;
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RGetSubImage(RImage *image, int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
int i, ofs;
|
||||
RImage *new_image;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(x>=0 && y>=0);
|
||||
assert(x<image->width && y<image->height);
|
||||
assert(width>0 && height>0);
|
||||
|
||||
if (x+width > image->width)
|
||||
width = image->width-x;
|
||||
if (y+height > image->height)
|
||||
height = image->height-y;
|
||||
|
||||
new_image = RCreateImage(width, height, image->data[3]!=NULL);
|
||||
if (!new_image)
|
||||
return NULL;
|
||||
new_image->background = image->background;
|
||||
ofs = image->width*y+x;
|
||||
|
||||
sr = image->data[0]+ofs;
|
||||
sg = image->data[1]+ofs;
|
||||
sb = image->data[2]+ofs;
|
||||
sa = image->data[3]+ofs;
|
||||
|
||||
dr = new_image->data[0];
|
||||
dg = new_image->data[1];
|
||||
db = new_image->data[2];
|
||||
da = new_image->data[3];
|
||||
|
||||
for (i=0; i<height; i++) {
|
||||
memcpy(dr, sr, width);
|
||||
memcpy(dg, sg, width);
|
||||
memcpy(db, sb, width);
|
||||
sr += image->width;
|
||||
sg += image->width;
|
||||
sb += image->width;
|
||||
dr += width;
|
||||
dg += width;
|
||||
db += width;
|
||||
if (da) {
|
||||
memcpy(da, sa, width);
|
||||
sa += image->width;
|
||||
da += width;
|
||||
}
|
||||
}
|
||||
return new_image;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RDestroyImage(RImage *image)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(image!=NULL);
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
if (image->data[i])
|
||||
free(image->data[i]);
|
||||
}
|
||||
free(image);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* RCombineImages-
|
||||
* Combines two equal sized images with alpha image. The second
|
||||
* image will be placed on top of the first one.
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
RCombineImages(RImage *image, RImage *src)
|
||||
{
|
||||
register int i;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
int alpha, calpha;
|
||||
|
||||
|
||||
assert(image->width == src->width);
|
||||
assert(image->height == src->height);
|
||||
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
da = image->data[3];
|
||||
|
||||
sr = src->data[0];
|
||||
sg = src->data[1];
|
||||
sb = src->data[2];
|
||||
sa = src->data[3];
|
||||
|
||||
if (!sa) {
|
||||
memcpy(dr, sr, image->height*image->width);
|
||||
memcpy(dg, sg, image->height*image->width);
|
||||
memcpy(db, sb, image->height*image->width);
|
||||
} else {
|
||||
for (i=0; i<image->height*image->width; i++) {
|
||||
alpha = *sa;
|
||||
calpha = 255 - *sa;
|
||||
*dr = (((int)*dr * calpha) + ((int)*sr * alpha))/256;
|
||||
*dg = (((int)*dg * calpha) + ((int)*sg * alpha))/256;
|
||||
*db = (((int)*db * calpha) + ((int)*sb * alpha))/256;
|
||||
if (image->data[3])
|
||||
*da |= *sa;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
da++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
|
||||
{
|
||||
register int i;
|
||||
unsigned char *dr, *dg, *db;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
int c_opaqueness;
|
||||
|
||||
|
||||
assert(image->width == src->width);
|
||||
assert(image->height == src->height);
|
||||
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
|
||||
sr = src->data[0];
|
||||
sg = src->data[1];
|
||||
sb = src->data[2];
|
||||
sa = src->data[3];
|
||||
|
||||
c_opaqueness = 255 - opaqueness;
|
||||
#define OP opaqueness
|
||||
if (!src->data[3]) {
|
||||
#define COP c_opaqueness
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
*dr = (((int)*dr *(int)COP) + ((int)*sr *(int)OP))/256;
|
||||
*dg = (((int)*dg *(int)COP) + ((int)*sg *(int)OP))/256;
|
||||
*db = (((int)*db *(int)COP) + ((int)*sb *(int)OP))/256;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
}
|
||||
#undef COP
|
||||
} else {
|
||||
int tmp;
|
||||
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
tmp= (*sa * opaqueness)/256;
|
||||
*dr = (((int)*dr *(int)(255-tmp)) + ((int)*sr *(int)tmp))/256;
|
||||
*dg = (((int)*dg *(int)(255-tmp)) + ((int)*sg *(int)tmp))/256;
|
||||
*db = (((int)*db *(int)(255-tmp)) + ((int)*sb *(int)tmp))/256;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
}
|
||||
}
|
||||
#undef OP
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
|
||||
unsigned height, int dx, int dy)
|
||||
{
|
||||
int x, y, dwi, swi;
|
||||
unsigned char *dr, *dg, *db;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
int alpha, calpha;
|
||||
|
||||
|
||||
assert(dy < image->height);
|
||||
assert(dx < image->width);
|
||||
|
||||
assert(sy + height <= src->height);
|
||||
assert(sx + width <= src->width);
|
||||
|
||||
dr = image->data[0] + dy*(int)image->width + dx;
|
||||
dg = image->data[1] + dy*(int)image->width + dx;
|
||||
db = image->data[2] + dy*(int)image->width + dx;
|
||||
|
||||
sr = src->data[0] + sy*(int)src->width + sx;
|
||||
sg = src->data[1] + sy*(int)src->width + sx;
|
||||
sb = src->data[2] + sy*(int)src->width + sx;
|
||||
sa = src->data[3] + sy*(int)src->width + sx;
|
||||
|
||||
swi = src->width - width;
|
||||
dwi = image->width - width;
|
||||
|
||||
if (height > image->height - dy)
|
||||
height = image->height - dy;
|
||||
|
||||
if (!src->data[3]) {
|
||||
for (y=sy; y<height+sy; y++) {
|
||||
for (x=sx; x<width+sx; x++) {
|
||||
*(dr++) = *(sr++);
|
||||
*(dg++) = *(sg++);
|
||||
*(db++) = *(sb++);
|
||||
}
|
||||
dr += dwi; dg += dwi; db += dwi;
|
||||
sr += swi; sg += swi; sb += swi;
|
||||
}
|
||||
} else {
|
||||
for (y=sy; y<height+sy; y++) {
|
||||
for (x=sx; x<width+sx; x++) {
|
||||
alpha = *sa;
|
||||
calpha = 255 - alpha;
|
||||
*dr = (((int)*dr * calpha) + ((int)*sr * alpha))/256;
|
||||
*dg = (((int)*dg * calpha) + ((int)*sg * alpha))/256;
|
||||
*db = (((int)*db * calpha) + ((int)*sb * alpha))/256;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
}
|
||||
dr += dwi; dg += dwi; db += dwi;
|
||||
sr += swi; sg += swi; sb += swi;
|
||||
sa += swi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
|
||||
unsigned width, unsigned height, int dx, int dy,
|
||||
int opaqueness)
|
||||
{
|
||||
int x, y, dwi, swi;
|
||||
int c_opaqueness;
|
||||
unsigned char *dr, *dg, *db;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
|
||||
assert(dy <= image->height);
|
||||
assert(dx <= image->width);
|
||||
|
||||
assert(sy <= height);
|
||||
assert(sx <= width);
|
||||
|
||||
dr = image->data[0] + dy*image->width + dx;
|
||||
dg = image->data[1] + dy*image->width + dx;
|
||||
db = image->data[2] + dy*image->width + dx;
|
||||
|
||||
sr = src->data[0] + sy*src->width;
|
||||
sg = src->data[1] + sy*src->width;
|
||||
sb = src->data[2] + sy*src->width;
|
||||
sa = src->data[3] + sy*src->width;
|
||||
|
||||
swi = src->width - width;
|
||||
dwi = image->width - width;
|
||||
|
||||
/* clip */
|
||||
width -= sx;
|
||||
height -= sy;
|
||||
|
||||
if (height > image->height - dy)
|
||||
height = image->height - dy;
|
||||
|
||||
c_opaqueness = 255 - opaqueness;
|
||||
#define OP opaqueness
|
||||
if (!src->data[3]) {
|
||||
#define COP c_opaqueness
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0; x<width; x++) {
|
||||
*dr = (((int)*dr *(int)COP) + ((int)*sr *(int)OP))/256;
|
||||
*dg = (((int)*dg *(int)COP) + ((int)*sg *(int)OP))/256;
|
||||
*db = (((int)*db *(int)COP) + ((int)*sb *(int)OP))/256;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
}
|
||||
dr += dwi; dg += dwi; db += dwi;
|
||||
sr += swi; sg += swi; sb += swi;
|
||||
}
|
||||
#undef COP
|
||||
} else {
|
||||
int tmp;
|
||||
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0; x<width; x++) {
|
||||
tmp= (*sa * opaqueness)/256;
|
||||
*dr = (((int)*dr *(int)(255-tmp)) + ((int)*sr *(int)tmp))/256;
|
||||
*dg = (((int)*dg *(int)(255-tmp)) + ((int)*sg *(int)tmp))/256;
|
||||
*db = (((int)*db *(int)(255-tmp)) + ((int)*sb *(int)tmp))/256;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
}
|
||||
dr += dwi; dg += dwi; db += dwi;
|
||||
sr += swi; sg += swi; sb += swi;
|
||||
sa += swi;
|
||||
}
|
||||
}
|
||||
#undef OP
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
RCombineImageWithColor(RImage *image, RColor *color)
|
||||
{
|
||||
register int i;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
int alpha, nalpha, r, g, b;
|
||||
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
da = image->data[3];
|
||||
|
||||
if (!da) {
|
||||
/* Image has no alpha channel, so we consider it to be all 255 */
|
||||
return;
|
||||
}
|
||||
r = color->red;
|
||||
g = color->green;
|
||||
b = color->blue;
|
||||
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
alpha = *da;
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
*dr = (((int)*dr * alpha) + (r * nalpha))/256;
|
||||
*dg = (((int)*dg * alpha) + (g * nalpha))/256;
|
||||
*db = (((int)*db * alpha) + (b * nalpha))/256;
|
||||
dr++; dg++; db++; da++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RMakeTiledImage(RImage *tile, unsigned width, unsigned height)
|
||||
{
|
||||
int x, y;
|
||||
unsigned w;
|
||||
unsigned long tile_size = tile->width * tile->height;
|
||||
unsigned long tx = 0;
|
||||
int have_alpha = (tile->data[3]!=NULL);
|
||||
RImage *image;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
|
||||
if (width == tile->width && height == tile->height)
|
||||
image = RCloneImage(tile);
|
||||
else if (width <= tile->width && height <= tile->height)
|
||||
image = RGetSubImage(tile, 0, 0, width, height);
|
||||
else {
|
||||
|
||||
image = RCreateImage(width, height, have_alpha);
|
||||
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
da = image->data[3];
|
||||
|
||||
sr = tile->data[0];
|
||||
sg = tile->data[1];
|
||||
sb = tile->data[2];
|
||||
sa = tile->data[3];
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x += tile->width) {
|
||||
|
||||
w = (width - x < tile->width) ? width - x : tile->width;
|
||||
|
||||
memcpy(dr, sr+tx, w);
|
||||
memcpy(dg, sg+tx, w);
|
||||
memcpy(db, sb+tx, w);
|
||||
if (have_alpha) {
|
||||
memcpy(da, sa+tx, w);
|
||||
da += w;
|
||||
}
|
||||
|
||||
dr += w;
|
||||
dg += w;
|
||||
db += w;
|
||||
|
||||
}
|
||||
tx = (tx + tile->width) % tile_size;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RMakeCenteredImage(RImage *image, unsigned width, unsigned height, RColor *color)
|
||||
{
|
||||
int x, y, w, h, sx, sy;
|
||||
RImage *tmp;
|
||||
|
||||
tmp = RCreateImage(width, height, False);
|
||||
if (!tmp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RClearImage(tmp, color);
|
||||
|
||||
if (image->height < height) {
|
||||
h = image->height;
|
||||
y = (height - h)/2;
|
||||
sy = 0;
|
||||
} else {
|
||||
sy = (image->height - height)/2;
|
||||
y = 0;
|
||||
h = height;
|
||||
}
|
||||
if (image->width < width) {
|
||||
w = image->width;
|
||||
x = (width - w)/2;
|
||||
sx = 0;
|
||||
} else {
|
||||
sx = (image->width - width)/2;
|
||||
x = 0;
|
||||
w = width;
|
||||
}
|
||||
RCombineArea(tmp, image, sx, sy, w, h, x, y);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
143
wrlib/scale.c
Normal file
143
wrlib/scale.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/* scale.c - image scaling
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* RScaleImage--
|
||||
* Creates a scaled copy of an image.
|
||||
*
|
||||
* Returns:
|
||||
* The new scaled image.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
RImage*
|
||||
RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
|
||||
{
|
||||
int ox;
|
||||
int px, py;
|
||||
register int x, y, t;
|
||||
int dx, dy;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
RImage *img;
|
||||
|
||||
assert(new_width >= 0 && new_height >= 0);
|
||||
|
||||
if (new_width == image->width && new_height == image->height)
|
||||
return RCloneImage(image);
|
||||
|
||||
img = RCreateImage(new_width, new_height, image->data[3]!=NULL);
|
||||
|
||||
if (!img)
|
||||
return NULL;
|
||||
|
||||
/* fixed point math idea taken from Imlib by
|
||||
* Carsten Haitzler (Rasterman) */
|
||||
dx = (image->width<<16)/new_width;
|
||||
dy = (image->height<<16)/new_height;
|
||||
|
||||
py = 0;
|
||||
|
||||
dr = img->data[0];
|
||||
dg = img->data[1];
|
||||
db = img->data[2];
|
||||
da = img->data[3];
|
||||
|
||||
if (image->data[3]!=NULL) {
|
||||
int ot;
|
||||
ot = -1;
|
||||
for (y=0; y<new_height; y++) {
|
||||
t = image->width*(py>>16);
|
||||
|
||||
sr = image->data[0]+t;
|
||||
sg = image->data[1]+t;
|
||||
sb = image->data[2]+t;
|
||||
sa = image->data[3]+t;
|
||||
|
||||
ot = t;
|
||||
ox = 0;
|
||||
px = 0;
|
||||
for (x=0; x<new_width; x++) {
|
||||
px += dx;
|
||||
|
||||
*(dr++) = *sr;
|
||||
*(dg++) = *sg;
|
||||
*(db++) = *sb;
|
||||
*(da++) = *sa;
|
||||
|
||||
t = (px - ox)>>16;
|
||||
ox += t<<16;
|
||||
|
||||
sr += t;
|
||||
sg += t;
|
||||
sb += t;
|
||||
sa += t;
|
||||
}
|
||||
py += dy;
|
||||
}
|
||||
} else {
|
||||
int ot;
|
||||
ot = -1;
|
||||
for (y=0; y<new_height; y++) {
|
||||
t = image->width*(py>>16);
|
||||
|
||||
sr = image->data[0]+t;
|
||||
sg = image->data[1]+t;
|
||||
sb = image->data[2]+t;
|
||||
|
||||
ot = t;
|
||||
ox = 0;
|
||||
px = 0;
|
||||
for (x=0; x<new_width; x++) {
|
||||
px += dx;
|
||||
|
||||
*(dr++) = *sr;
|
||||
*(dg++) = *sg;
|
||||
*(db++) = *sb;
|
||||
|
||||
t = (px-ox)>>16;
|
||||
ox += t<<16;
|
||||
|
||||
sr += t;
|
||||
sg += t;
|
||||
sb += t;
|
||||
}
|
||||
py += dy;
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
85
wrlib/test.c
Normal file
85
wrlib/test.c
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Display *dpy;
|
||||
Window win;
|
||||
RContext *ctx;
|
||||
RImage *img, *tile, *new, *mini, *tiled;
|
||||
Pixmap pix;
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
int a=0;
|
||||
|
||||
if (argc<1) {
|
||||
puts("You must supply t,p or x as the file type to load");
|
||||
puts("t is tiff, p is png and x is xpm");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (argc>1) {
|
||||
if (argv[1][0]=='t')
|
||||
a=1;
|
||||
else if (argv[1][0]=='p')
|
||||
a=2;
|
||||
else a=0;
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10, 250, 250,
|
||||
0, 0, 0);
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel | RC_DefaultVisual;
|
||||
|
||||
attr.render_mode = RM_DITHER;
|
||||
attr.colors_per_channel = 4;
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
#ifdef USE_TIFF
|
||||
if (a==1)
|
||||
img = RLoadImage(ctx, "ballot_box.tiff", 0);
|
||||
#endif
|
||||
#ifdef USE_PNG
|
||||
if (a==2)
|
||||
img = RLoadImage(ctx, "test.png", 0);
|
||||
#endif
|
||||
#ifdef USE_XPM
|
||||
if (a==0)
|
||||
img = RLoadImage(ctx, "ballot_box.xpm", 0);
|
||||
#endif
|
||||
|
||||
if (!img) {
|
||||
puts(RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
new = RLoadImage(ctx, "tile.xpm", 0);
|
||||
if (!new) {
|
||||
puts(RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
RCombineArea(new, img, 0, 0, img->width, img->height, 8, 8);
|
||||
RConvertImage(ctx, new, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, new->width, new->height,
|
||||
0, 0);
|
||||
|
||||
mini = RScaleImage(new, 20, 20);
|
||||
RConvertImage(ctx, mini, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 20, 20,
|
||||
new->width, new->height);
|
||||
|
||||
tiled = RMakeTiledImage(img, 160, 160);
|
||||
RConvertImage(ctx, tiled, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 160, 160,
|
||||
new->width+mini->width, new->height+mini->height);
|
||||
|
||||
XFlush(dpy);
|
||||
getchar();
|
||||
}
|
||||
BIN
wrlib/test.png
Normal file
BIN
wrlib/test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
555
wrlib/testdraw.c
Normal file
555
wrlib/testdraw.c
Normal file
@@ -0,0 +1,555 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
Display *dpy;
|
||||
RContext *ctx;
|
||||
char *ProgName;
|
||||
|
||||
|
||||
void
|
||||
testDraw()
|
||||
{
|
||||
RImage *img, *tile, *icon, *tmp;
|
||||
RColor color, from, to;
|
||||
RColor cdelta;
|
||||
RSegment segs[20];
|
||||
int i, x, y;
|
||||
XSetWindowAttributes val;
|
||||
Pixmap pix, back;
|
||||
Window win;
|
||||
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 128, 256,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
back = XCreatePixmap(ctx->dpy, ctx->drawable, 128, 256, ctx->depth);
|
||||
|
||||
/* Dark blue tile gradient */
|
||||
from.red = 0x28;
|
||||
from.green = 0x45;
|
||||
from.blue = 0x69;
|
||||
from.alpha = 0xff;
|
||||
to.red = 0x08;
|
||||
to.green = 0x24;
|
||||
to.blue = 0x20;
|
||||
to.alpha = 0xff;
|
||||
|
||||
/* Standard gray tile gradient */
|
||||
/*from.red = 0xa6;
|
||||
from.green = 0xa6;
|
||||
from.blue = 0xb6;
|
||||
from.alpha = 0xff;
|
||||
to.red = 0x51;
|
||||
to.green = 0x55;
|
||||
to.blue = 0x61;
|
||||
to.alpha = 0xff;*/
|
||||
|
||||
/* Make the tile, and put it as a sample in the first place */
|
||||
tile = RRenderGradient(64, 64, &from, &to, RGRD_DIAGONAL);
|
||||
img = RCloneImage(tile);
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 0, 0);
|
||||
|
||||
/* Read the image, and combine it with the tile. Put it as a sample
|
||||
* in the second slot, and also save a copy for later use. */
|
||||
icon = RLoadImage(ctx, "ballot_box.xpm", 0);
|
||||
if (!icon) {
|
||||
puts(RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
RCombineArea(img, icon, 0, 0, icon->width, icon->height, 8, 8);
|
||||
RDestroyImage(icon);
|
||||
tmp = img;
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 64, 0);
|
||||
|
||||
img = RCloneImage(tile);
|
||||
|
||||
/* Draw random pixels on image */
|
||||
for (i=0; i< 200; i++) {
|
||||
color.red = rand()%256;
|
||||
color.green = rand()%256;
|
||||
color.blue = rand()%256;
|
||||
color.alpha = 255;
|
||||
x = rand()%64;
|
||||
y = rand()%64;
|
||||
RPutPixel(img, x, y, &color);
|
||||
}
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 0, 64);
|
||||
|
||||
RDestroyImage(img);
|
||||
img = RCloneImage(tile);
|
||||
|
||||
/* Alter random pixels in image with the same amount for r/g/b */
|
||||
for (i=0; i< 200; i++) {
|
||||
cdelta.red = cdelta.green = cdelta.blue = rand()%511 - 255;
|
||||
cdelta.alpha = 0;
|
||||
x = rand()%64;
|
||||
y = rand()%64;
|
||||
ROperatePixel(img, RAddOperation, x, y, &cdelta);
|
||||
}
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 64, 64);
|
||||
|
||||
RDestroyImage(img);
|
||||
img = RCloneImage(tile);
|
||||
|
||||
/* Draw lines in all directions to test different slopes */
|
||||
color.red = 0xff;
|
||||
color.green = 0x7d;
|
||||
color.blue = 0x52;
|
||||
color.alpha = 0xff;
|
||||
for (i=0; i<16; i++)
|
||||
segs[i].x1 = segs[i].y1 = 31;
|
||||
|
||||
segs[6].x2 = segs[7].x2 = segs[8].x2 = segs[9].x2 = segs[10].x2 = 0;
|
||||
segs[2].y2 = segs[3].y2 = segs[4].y2 = segs[5].y2 = segs[6].y2 = 0;
|
||||
segs[5].x2 = segs[11].x2 = 16;
|
||||
segs[1].y2 = segs[7].y2 = 16;
|
||||
segs[4].x2 = segs[12].x2 = 31;
|
||||
segs[0].y2 = segs[8].y2 = 31;
|
||||
segs[3].x2 = segs[13].x2 = 46;
|
||||
segs[9].y2 = segs[15].y2 = 46;
|
||||
segs[0].x2 = segs[1].x2 = segs[2].x2 = segs[14].x2 = segs[15].x2 = 62;
|
||||
segs[10].y2 = segs[11].y2 = segs[12].y2 = segs[13].y2 = segs[14].y2 = 62;
|
||||
RDrawSegments(img, segs, 9, &color);
|
||||
|
||||
/* Also test how alpha channel behaves when drawing lines */
|
||||
color.alpha = 0x80;
|
||||
RDrawSegments(img, &segs[9], 7, &color);
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 0, 128);
|
||||
|
||||
RDestroyImage(img);
|
||||
img = RCloneImage(tile);
|
||||
|
||||
/* Alter lines in all directions (test different slopes) */
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
cdelta.alpha = 0;
|
||||
ROperateSegments(img, RAddOperation, segs, 16, &cdelta);
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 64, 128);
|
||||
|
||||
RDestroyImage(img);
|
||||
|
||||
/* Create a bevel around the icon, and save it for a later use */
|
||||
img = tmp;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
cdelta.alpha = 0;
|
||||
ROperateLine(img, RAddOperation, 8, 8, 56, 8, &cdelta);
|
||||
ROperateLine(img, RAddOperation, 8, 9, 8, 56, &cdelta);
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
cdelta.alpha = 0;
|
||||
ROperateLine(img, RSubtractOperation, 8, 56, 56, 56, &cdelta);
|
||||
ROperateLine(img, RSubtractOperation, 56, 8, 56, 55, &cdelta);
|
||||
RDestroyImage(tile);
|
||||
tmp = RCloneImage(img);
|
||||
|
||||
/* Draw some solid lines over the icon */
|
||||
color.red = 0xff;
|
||||
color.green = 0x7d;
|
||||
color.blue = 0x52;
|
||||
color.alpha = 0xff;
|
||||
for (i=16; i<24; i++) {
|
||||
RDrawLine(img, 9, i, 55, i, &color);
|
||||
}
|
||||
|
||||
/* Also try some lines with alpha over the icon */
|
||||
color.alpha = 0x80;
|
||||
for (i=40; i<48; i++) {
|
||||
RDrawLine(img, 9, i, 55, i, &color);
|
||||
}
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 0, 192);
|
||||
|
||||
RDestroyImage(img);
|
||||
|
||||
/* Restore the image with the icon, and alter some lines */
|
||||
img = tmp;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
cdelta.alpha = 0;
|
||||
for (i=16; i<24; i++) {
|
||||
ROperateLine(img, RSubtractOperation, 9, i, 55, i, &cdelta);
|
||||
}
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
for (i=40; i<48; i++) {
|
||||
ROperateLine(img, RAddOperation, 9, i, 55, i, &cdelta);
|
||||
}
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 64, 192);
|
||||
|
||||
|
||||
XSetWindowBackgroundPixmap(dpy, win, back);
|
||||
XMapRaised(dpy, win);
|
||||
XClearWindow(dpy, win);
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
testBevel()
|
||||
{
|
||||
RImage *img, *tile;
|
||||
RColor color, from, to;
|
||||
XSetWindowAttributes val;
|
||||
Pixmap pix, back;
|
||||
Window win;
|
||||
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 140, 140,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
back = XCreatePixmap(ctx->dpy, ctx->drawable, 140, 140, ctx->depth);
|
||||
|
||||
/* Standard gray tile gradient */
|
||||
from.red = 0xa6;
|
||||
from.green = 0xa6;
|
||||
from.blue = 0xb6;
|
||||
from.alpha = 0xff;
|
||||
to.red = 0x51;
|
||||
to.green = 0x55;
|
||||
to.blue = 0x61;
|
||||
to.alpha = 0xff;
|
||||
|
||||
/* Dark blue tile gradient */
|
||||
/*from.red = 0x28;
|
||||
from.green = 0x45;
|
||||
from.blue = 0x69;
|
||||
from.alpha = 0xff;
|
||||
to.red = 0x08;
|
||||
to.green = 0x24;
|
||||
to.blue = 0x20;
|
||||
to.alpha = 0xff;*/
|
||||
|
||||
/* Create Background */
|
||||
img = RCreateImage(140, 140, True);
|
||||
color.red = 0x28;
|
||||
color.green = 0x45;
|
||||
color.blue = 0x69;
|
||||
color.alpha = 0xff;
|
||||
RClearImage(img, &color);
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 140, 140, 0, 0);
|
||||
RDestroyImage(img);
|
||||
|
||||
tile = RRenderGradient(64, 64, &from, &to, RGRD_DIAGONAL);
|
||||
|
||||
img = RCloneImage(tile);
|
||||
RBevelImage(img, RBEV_SUNKEN);
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 3, 3);
|
||||
RDestroyImage(img);
|
||||
|
||||
img = RCloneImage(tile);
|
||||
RBevelImage(img, RBEV_RAISED);
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 73, 3);
|
||||
RDestroyImage(img);
|
||||
|
||||
img = RCloneImage(tile);
|
||||
RBevelImage(img, RBEV_RAISED2);
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 3, 73);
|
||||
RDestroyImage(img);
|
||||
|
||||
img = RCloneImage(tile);
|
||||
RBevelImage(img, RBEV_RAISED3);
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 73, 73);
|
||||
RDestroyImage(img);
|
||||
|
||||
XSetWindowBackgroundPixmap(dpy, win, back);
|
||||
XMapRaised(dpy, win);
|
||||
XClearWindow(dpy, win);
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
drawClip()
|
||||
{
|
||||
RImage *img;
|
||||
RColor color, from, to, tmp;
|
||||
RColor cdelta, cdelta1;
|
||||
RSegment segs[20];
|
||||
XSetWindowAttributes val;
|
||||
Pixmap pix, back;
|
||||
Window win;
|
||||
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 64, 64,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
back = XCreatePixmap(ctx->dpy, ctx->drawable, 64, 64, ctx->depth);
|
||||
|
||||
/* Standard gray tile gradient */
|
||||
from.red = 0xa6;
|
||||
from.green = 0xa6;
|
||||
from.blue = 0xb6;
|
||||
from.alpha = 0xff;
|
||||
to.red = 0x51;
|
||||
to.green = 0x55;
|
||||
to.blue = 0x61;
|
||||
to.alpha = 0xff;
|
||||
|
||||
/* Dark blue tile gradient */
|
||||
from.red = 0x28;
|
||||
from.green = 0x45;
|
||||
from.blue = 0x69;
|
||||
from.alpha = 0xff;
|
||||
to.red = 0x08;
|
||||
to.green = 0x24;
|
||||
to.blue = 0x20;
|
||||
to.alpha = 0xff;
|
||||
|
||||
img = RRenderGradient(64, 64, &from, &to, RGRD_DIAGONAL);
|
||||
|
||||
RBevelImage(img, RBEV_RAISED3);
|
||||
#if 1
|
||||
color.alpha = 255;
|
||||
color.red = color.green = color.blue = 0;
|
||||
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
|
||||
cdelta1.alpha = 0;
|
||||
cdelta1.red = cdelta1.green = cdelta1.blue = 40;
|
||||
|
||||
segs[0].x1 = segs[2].y1 = segs[4].x1 = segs[4].x2 = 63-21;
|
||||
segs[0].x2 = segs[2].y2 = segs[1].x2 = segs[3].y2 = 63-2;
|
||||
segs[0].y1 = segs[2].x1 = segs[1].y1 = segs[3].x1 = 2;
|
||||
segs[0].y2 = segs[2].x2 = segs[6].x1 = segs[6].x2 = 21;
|
||||
segs[1].x1 = segs[3].y1 = segs[5].x1 = segs[5].x2 = 63-22;
|
||||
segs[1].y2 = segs[3].x2 = segs[7].x1 = segs[7].x2 = 22;
|
||||
|
||||
segs[4].y1 = segs[5].y1 = segs[10].x1 = segs[11].x1 = 0;
|
||||
segs[4].y2 = segs[5].y2 = segs[10].x2 = segs[11].x2 = 1;
|
||||
segs[6].y1 = segs[7].y1 = segs[8].x1 = segs[9].x1 = 63-1;
|
||||
segs[6].y2 = segs[7].y2 = segs[8].x2 = segs[9].x2 = 63;
|
||||
segs[8].y1 = segs[8].y2 = 21;
|
||||
segs[9].y1 = segs[9].y2 = 22;
|
||||
segs[10].y1 = segs[10].y2 = 63-21;
|
||||
segs[11].y1 = segs[11].y2 = 63-22;
|
||||
/* Black segments */
|
||||
RDrawSegments(img, segs, 12, &color);
|
||||
|
||||
segs[0].x1 = segs[3].y1 = 63-20;
|
||||
segs[0].x2 = segs[1].y2 = segs[2].x2 = segs[3].y2 = 63-2;
|
||||
segs[0].y1 = segs[1].x1 = segs[2].y1 = segs[3].x1 = 2;
|
||||
segs[1].y1 = segs[2].x1 = 63-23;
|
||||
segs[0].y2 = segs[3].x2 = 20;
|
||||
segs[1].x2 = segs[2].y2 = 23;
|
||||
/* Bevels arround black segments */
|
||||
ROperateSegments(img, RAddOperation, segs, 2, &cdelta);
|
||||
ROperateSegments(img, RSubtractOperation, &segs[2], 2 ,&cdelta1);
|
||||
|
||||
RGetPixel(img, 63-2, 20, &tmp);
|
||||
/*RPutPixel(img, 63-1, 23, &tmp);*/
|
||||
RDrawLine(img, 63-1, 23, 63, 23, &tmp);
|
||||
RGetPixel(img, 63-23, 2, &tmp);
|
||||
RDrawLine(img, 63-23, 0, 63-23, 1, &tmp);
|
||||
|
||||
RGetPixel(img, 23, 63-2, &tmp);
|
||||
/*RPutPixel(img, 23, 63-1, &tmp);*/
|
||||
RDrawLine(img, 23, 63-1, 23, 63, &tmp);
|
||||
RGetPixel(img, 2, 63-20, &tmp);
|
||||
RDrawLine(img, 0, 63-23, 1, 63-23, &tmp);
|
||||
#else
|
||||
color.alpha = 255;
|
||||
color.red = color.green = color.blue = 0;
|
||||
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
|
||||
cdelta1.alpha = 0;
|
||||
cdelta1.red = cdelta1.green = cdelta1.blue = 40;
|
||||
|
||||
RDrawLine(img, 63-21, 2, 63-2, 21, &color); /* upper 2 black lines */
|
||||
ROperateLine(img, RAddOperation, 63-20, 2, 63-2, 20, &cdelta); /* the bevel arround them */
|
||||
ROperateLine(img, RSubtractOperation, 63-22, 2, 63-2, 22, &cdelta1);
|
||||
RDrawLine(img, 63-21, 0, 63-21, 1, &color); /* upper small black lines */
|
||||
RDrawLine(img, 63-1, 21, 63, 21, &color);
|
||||
|
||||
RGetPixel(img, 63-2, 20, &tmp);
|
||||
RPutPixel(img, 63-1, 22, &tmp);
|
||||
RGetPixel(img, 2, 63-22, &tmp);
|
||||
RDrawLine(img, 63-22, 0, 63-22, 1, &tmp);
|
||||
|
||||
RDrawLine(img, 2, 63-21, 21, 63-2, &color); /* lower 2 black lines */
|
||||
ROperateLine(img, RSubtractOperation, 2, 63-20, 20, 63-2, &cdelta1); /* the bevel arround them */
|
||||
ROperateLine(img, RAddOperation, 2, 63-22, 22, 63-2, &cdelta);
|
||||
RDrawLine(img, 21, 63-1, 21, 63, &color); /* lower small black lines */
|
||||
RDrawLine(img, 0, 63-21, 1, 63-21, &color);
|
||||
ROperateLine(img, RAddOperation, 22, 63-1, 22, 63, &cdelta);
|
||||
/*ROperateLine(img, RAddOperation, 22, 63-1, 22, 63, &cdelta);*/ /* the bevel arround them */
|
||||
ROperateLine(img, RSubtractOperation, 0, 63-22, 1, 63-22, &cdelta1);
|
||||
#endif
|
||||
|
||||
RConvertImage(ctx, img, &pix);
|
||||
XCopyArea(dpy, pix, back, ctx->copy_gc, 0, 0, 64, 64, 0, 0);
|
||||
RDestroyImage(img);
|
||||
|
||||
XSetWindowBackgroundPixmap(dpy, win, back);
|
||||
XMapRaised(dpy, win);
|
||||
XClearWindow(dpy, win);
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
benchmark()
|
||||
{
|
||||
RImage *img;
|
||||
RColor color;
|
||||
RColor cdelta;
|
||||
double t1, t2, total, d1=0, d2=0, d3=0;
|
||||
struct timeval timev;
|
||||
int i, j;
|
||||
|
||||
puts("Starting benchmark");
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
|
||||
img = RCreateImage(1024, 768, True);
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("Image created in %f sec\n", total);
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
|
||||
color.red = 0x28;
|
||||
color.green = 0x45;
|
||||
color.blue = 0x69;
|
||||
color.alpha = 0xff;
|
||||
RClearImage(img, &color);
|
||||
|
||||
color.red = 0xff;
|
||||
color.green = 0x7d;
|
||||
color.blue = 0x52;
|
||||
color.alpha = 0xff;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
cdelta.alpha = 0;
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("Image filled in %f sec\n", total);
|
||||
|
||||
for(j=1; j<6; j++) {
|
||||
printf("Pass %d...\n", j);
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
|
||||
color.alpha = 0xff;
|
||||
for (i=0; i< 10000; i++) {
|
||||
RDrawLine(img, 0, i%64, i%64, 63, &color);
|
||||
}
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("Drawing 10000 lines in %f sec\n", total);
|
||||
d1 += total;
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
|
||||
color.alpha = 80;
|
||||
for (i=0; i< 10000; i++) {
|
||||
RDrawLine(img, 0, i%64, i%64, 63, &color);
|
||||
}
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("Drawing 10000 lines with alpha in %f sec\n", total);
|
||||
d2+=total;
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
|
||||
for (i=0; i< 10000; i++) {
|
||||
ROperateLine(img, RAddOperation, 0, i%64, i%64, 63, &cdelta);
|
||||
}
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("Altering 10000 lines in %f sec\n", total);
|
||||
d3+=total;
|
||||
}
|
||||
printf("Average: %f, %f, %f\n", d1/5, d2/5, d3/5);
|
||||
|
||||
RDestroyImage(img);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
int visualID = -1;
|
||||
|
||||
ProgName = strrchr(argv[0],'/');
|
||||
if (!ProgName)
|
||||
ProgName = argv[0];
|
||||
else
|
||||
ProgName++;
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
|
||||
attr.render_mode = RM_DITHER;
|
||||
attr.colors_per_channel = 4;
|
||||
|
||||
if (visualID >= 0) {
|
||||
attr.flags |= RC_VisualID;
|
||||
attr.visualid = visualID;
|
||||
}
|
||||
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
|
||||
if (!ctx) {
|
||||
printf("could not initialize graphics library context: %s\n",
|
||||
RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Here are the things we want to test */
|
||||
testDraw();
|
||||
|
||||
testBevel();
|
||||
/*
|
||||
drawClip();
|
||||
|
||||
benchmark();
|
||||
*/
|
||||
getchar();
|
||||
}
|
||||
207
wrlib/testgrad.c
Normal file
207
wrlib/testgrad.c
Normal file
@@ -0,0 +1,207 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef BENCH
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
Display *dpy;
|
||||
Window win;
|
||||
RContext *ctx;
|
||||
RImage *imgh, *imgv, *imgd;
|
||||
Pixmap pix;
|
||||
char *ProgName;
|
||||
|
||||
|
||||
void
|
||||
print_help()
|
||||
{
|
||||
printf("usage: %s [-options] color1 [color2 ...]\n", ProgName);
|
||||
puts("options:");
|
||||
puts(" -m match colors");
|
||||
puts(" -d dither colors (default)");
|
||||
puts(" -c <cpc> colors per channel to use");
|
||||
puts(" -v <vis-id> visual id to use");
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
RColor **colors = NULL;
|
||||
int i, rmode = RM_DITHER, ncolors = 0, cpc = 4;
|
||||
char **color_name;
|
||||
XColor color;
|
||||
XSetWindowAttributes val;
|
||||
int visualID = -1;
|
||||
#ifdef BENCH
|
||||
double t1, t2, total, t, rt;
|
||||
struct timeval timev;
|
||||
#endif
|
||||
|
||||
ProgName = strrchr(argv[0],'/');
|
||||
if (!ProgName)
|
||||
ProgName = argv[0];
|
||||
else
|
||||
ProgName++;
|
||||
|
||||
color_name = (char **) malloc(sizeof(char*) * argc);
|
||||
if(color_name == NULL) {
|
||||
fprintf(stderr, "Cannot allocate memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc>1) {
|
||||
for (i=1; i<argc; i++) {
|
||||
if (strcmp(argv[i], "-m")==0) {
|
||||
rmode = RM_MATCH;
|
||||
} else if (strcmp(argv[i], "-d")==0) {
|
||||
rmode = RM_DITHER;
|
||||
} else if (strcmp(argv[i], "-c")==0) {
|
||||
i++;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "too few arguments for %s\n", argv[i-1]);
|
||||
exit(0);
|
||||
}
|
||||
if (sscanf(argv[i], "%i", &cpc)!=1) {
|
||||
fprintf(stderr, "bad value for colors per channel: \"%s\"\n", argv[i]);
|
||||
exit(0);
|
||||
}
|
||||
} else if (strcmp(argv[i], "-v")==0) {
|
||||
i++;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "too few arguments for %s\n", argv[i-1]);
|
||||
exit(0);
|
||||
}
|
||||
if (sscanf(argv[i], "%i", &visualID)!=1) {
|
||||
fprintf(stderr, "bad value for visual ID: \"%s\"\n", argv[i]);
|
||||
exit(0);
|
||||
}
|
||||
} else if (argv[i][0] != '-') {
|
||||
color_name[ncolors++] = argv[i];
|
||||
} else {
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ncolors == 0) {
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
|
||||
attr.render_mode = rmode;
|
||||
attr.colors_per_channel = cpc;
|
||||
|
||||
if (visualID >= 0) {
|
||||
attr.flags |= RC_VisualID;
|
||||
attr.visualid = visualID;
|
||||
}
|
||||
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
|
||||
if (!ctx) {
|
||||
printf("could not initialize graphics library context: %s\n",
|
||||
RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
colors = malloc(sizeof(RColor*)*(ncolors+1));
|
||||
for (i=0; i<ncolors; i++) {
|
||||
if (!XParseColor(dpy, ctx->cmap, color_name[i], &color)) {
|
||||
printf("could not parse color \"%s\"\n", color_name[i]);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
colors[i] = malloc(sizeof(RColor));
|
||||
colors[i]->red = color.red >> 8;
|
||||
colors[i]->green = color.green >> 8;
|
||||
colors[i]->blue = color.blue >> 8;
|
||||
printf("0x%02x%02x%02x\n", colors[i]->red, colors[i]->green,
|
||||
colors[i]->blue);
|
||||
}
|
||||
}
|
||||
colors[i] = NULL;
|
||||
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
#ifdef BENCH
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 250, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
#else
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 750, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
#endif
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
|
||||
#ifdef BENCH
|
||||
rt = 0;
|
||||
gettimeofday(&timev, NULL);
|
||||
t = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
for (i=0; i<9; i++) {
|
||||
if (i>0)
|
||||
printf("\nrepeating...\n\n");
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
if (i%3==0)
|
||||
imgh = RRenderMultiGradient(250, 250, colors, RGRD_HORIZONTAL);
|
||||
else if (i%3==1)
|
||||
imgh = RRenderMultiGradient(250, 250, colors, RGRD_VERTICAL);
|
||||
else
|
||||
imgh = RRenderMultiGradient(250, 250, colors, RGRD_DIAGONAL);
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("gradient rendered in %f sec\n", total);
|
||||
|
||||
RConvertImage(ctx, imgh, &pix);
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t1 - t2;
|
||||
rt += total;
|
||||
printf("image converted in %f sec\n", total);
|
||||
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
|
||||
|
||||
XFlush(dpy);
|
||||
}
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
printf("------------------------------------------\n");
|
||||
printf("%i images processed in %f sec\n", i, t1-t);
|
||||
printf("average time per convertion %f sec\n", rt/i);
|
||||
printf("------------------------------------------\n");
|
||||
#else
|
||||
imgh = RRenderMultiGradient(250, 250, colors, RGRD_HORIZONTAL);
|
||||
imgv = RRenderMultiGradient(250, 250, colors, RGRD_VERTICAL);
|
||||
imgd = RRenderMultiGradient(250, 250, colors, RGRD_DIAGONAL);
|
||||
|
||||
RConvertImage(ctx, imgh, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
|
||||
RConvertImage(ctx, imgv, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 250, 0);
|
||||
RConvertImage(ctx, imgd, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 500, 0);
|
||||
|
||||
XFlush(dpy);
|
||||
#endif
|
||||
|
||||
getchar();
|
||||
}
|
||||
141
wrlib/tiff.c
Normal file
141
wrlib/tiff.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/* tiff.c - load TIFF image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#ifdef USE_TIFF
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <tiff.h>
|
||||
#include <tiffio.h>
|
||||
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadTIFF(RContext *context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
TIFF *tif;
|
||||
int i;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
uint16 alpha, amode;
|
||||
uint32 width, height;
|
||||
uint32 *data, *ptr;
|
||||
uint16 extrasamples;
|
||||
uint16 *sampleinfo;
|
||||
|
||||
|
||||
tif = TIFFOpen(file, "r");
|
||||
if (!tif)
|
||||
return NULL;
|
||||
|
||||
/* seek index */
|
||||
i = index;
|
||||
while (i>0) {
|
||||
if (!TIFFReadDirectory(tif)) {
|
||||
sprintf(RErrorString, "bad index %i for file \"%s\"", index, file);
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
/* get info */
|
||||
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
|
||||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
|
||||
&extrasamples, &sampleinfo);
|
||||
|
||||
alpha = (extrasamples == 1 &&
|
||||
((sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA) || (sampleinfo[0] == EXTRASAMPLE_UNASSALPHA)));
|
||||
amode = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
|
||||
if (width<1 || height<1) {
|
||||
sprintf(RErrorString, "bad data in file \"%s\"", file);
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read data */
|
||||
ptr = data = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
|
||||
|
||||
if (!data) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
} else {
|
||||
if (!TIFFReadRGBAImage(tif, width, height, data, 0)) {
|
||||
sprintf(RErrorString, "error reading file \"%s\"", file);
|
||||
} else {
|
||||
|
||||
/* convert data */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
|
||||
if (image) {
|
||||
int x, y;
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
/* data seems to be stored upside down */
|
||||
data += width * (height-1);
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0; x<width; x++) {
|
||||
|
||||
*(r) = (*data) & 0xff;
|
||||
*(g) = (*data >> 8) & 0xff;
|
||||
*(b) = (*data >> 16) & 0xff;
|
||||
|
||||
if (alpha) {
|
||||
*(a) = (*data >> 24) & 0xff;
|
||||
|
||||
if (amode && (*a > 0)) {
|
||||
*r = (*r * 255) / *(a);
|
||||
*g = (*g * 255) / *(a);
|
||||
*b = (*b * 255) / *(a);
|
||||
}
|
||||
|
||||
a++;
|
||||
}
|
||||
|
||||
r++; g++; b++;
|
||||
data++;
|
||||
}
|
||||
data -= 2*width;
|
||||
}
|
||||
}
|
||||
}
|
||||
_TIFFfree(ptr);
|
||||
}
|
||||
|
||||
TIFFClose(tif);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_TIFF */
|
||||
121
wrlib/tile.xpm
Normal file
121
wrlib/tile.xpm
Normal file
@@ -0,0 +1,121 @@
|
||||
/* XPM */
|
||||
static char * image_name[] = {
|
||||
"64 64 54 1",
|
||||
" c white",
|
||||
". c #000000000000",
|
||||
"X c #514461856185",
|
||||
"o c #A289A289B2CA",
|
||||
"O c #A289A289A289",
|
||||
"+ c #A2899248B2CA",
|
||||
"@ c #9248A289A289",
|
||||
"# c #A2899248A289",
|
||||
"$ c #92489248A289",
|
||||
"% c #924892489248",
|
||||
"& c #92488207A289",
|
||||
"* c #820792489248",
|
||||
"= c #924882079248",
|
||||
"- c #820782079248",
|
||||
"; c #820782078207",
|
||||
": c #820771C69248",
|
||||
"> c #618551446185",
|
||||
", c #9248A289B2CA",
|
||||
"< c #92489248B2CA",
|
||||
"1 c #82079248A289",
|
||||
"2 c #82078207A289",
|
||||
"3 c #71C682079248",
|
||||
"4 c #71C682078207",
|
||||
"5 c #514451446185",
|
||||
"6 c #514451445144",
|
||||
"7 c #820771C68207",
|
||||
"8 c #410351445144",
|
||||
"9 c #514441035144",
|
||||
"0 c #71C671C69248",
|
||||
"q c #71C671C68207",
|
||||
"w c #71C671C671C6",
|
||||
"e c #410341035144",
|
||||
"r c #71C661858207",
|
||||
"t c #618571C68207",
|
||||
"y c #410351444103",
|
||||
"u c #410341034103",
|
||||
"i c #618571C671C6",
|
||||
"p c #410330C24103",
|
||||
"a c #30C241034103",
|
||||
"s c #71C6618571C6",
|
||||
"d c #6185618571C6",
|
||||
"f c #618561858207",
|
||||
"g c #30C230C230C2",
|
||||
"h c #618561856185",
|
||||
"j c #30C230C24103",
|
||||
"k c #5144618571C6",
|
||||
"l c #30C2410330C2",
|
||||
"z c #6185514471C6",
|
||||
"x c #208130C230C2",
|
||||
"c c #30C2208130C2",
|
||||
"v c #5144514471C6",
|
||||
"b c #2081208130C2",
|
||||
"n c #208120812081",
|
||||
"m c #410330C25144",
|
||||
" .",
|
||||
" X.",
|
||||
" oOoO+O+O+O+@#$+@#$#$#$$$#$$%&%&%&%&*&*&*=-=*=-=-=--;---;:;:;>.",
|
||||
" oo@o,o@o@o@+@+@<@$@$@$@$@$1$$$*$*$*&*&*2*&*2*-*-*-----3-3-4-X.",
|
||||
" oO+OoO#O+@#@#@#$#@#$#%#$$%$%$%&%&*=%&*=*=*=-=-=--;-;-;:;:;:;5.",
|
||||
" ,ooo@+@+@+@+@<@#@<@$$$$$$$$$*$1$*&*&*&*&*2*---*-----3---4:4:6.",
|
||||
" +O+O+O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=*=---=--;---;:;:4:;:45.",
|
||||
" @o@o@o@+@+@<@$@$@$$$@$1$1$*$*$*&*&*2*=*2*-*-*-----4-3-4:4-4:6.",
|
||||
" +O#O+@#@#@#$#$#$#%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:4745.",
|
||||
" @+@+@+@+@<@#@$@$$$$$$$$$*$*$*&*&*&*&*2*---*-----3---4:4:4:4:8.",
|
||||
" #O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=-=---=--;:;-;:;:4:4:474:49.",
|
||||
" @o@<@+@<@$@$@$$$$$1$1$*$*$*&*&*2*=*2*-*-*-----4-4-4:4:4:4:408.",
|
||||
" +@#@#@#$#$#$$%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:474747q9.",
|
||||
" @+@+@<@$$$@$$$$$1$$$*&*$*&*&*&*&*2*---------3-3-4:4:4:4:404q8.",
|
||||
" #$#@#$#$#$$%$$$%&%&%&%&*=-&*=-=-=---=--;:;:;:;:4:4:474:47q7q9.",
|
||||
" @#@<@$@$@$$$$$*$1$*$*$*&*&*2*-*2*-*-*-3---4-4-4:4:4:4:404q4q8.",
|
||||
" #@#$#$#$$%$%$%&%$%&%&*=*=*=-=*=-=;=--;-;-;:;:47;:474747q7q7q9.",
|
||||
" @<@$$$@$$$$$1$$$*&*&*&*&*&*=*2*---------4-3-4:4:4:4:404qq04q8.",
|
||||
" #$#$#$$%$%$%&%&%&%&*=-&*=-=-=------;:;:;:;:4:4:47q747qqq7qqq9.",
|
||||
" @$@$@$$$$$*$1$*$*$*&*&*2*-*-*---*-3-3-4-4-4:4:4:4:404q4q4qqq8.",
|
||||
" #$#$$%$%$%&%&%&%&*=*=*=-=-=-=;=--;:;-;:;:474:474747q7q7qqwqw9.",
|
||||
" $$@$$$$$*$$$*&*&*&*&*2*=*2*---------4-3-4:4:4:4:404qqq4qqqqqe.",
|
||||
" #$$%$%$%&%&*&%&*=-&*=-=-=------;:;:;:;:4:4:47q7q7qqq7qqwrqqw9.",
|
||||
" @$$$$$*$1$*&*$*2*&*2*-*-*-----3-3-4-4-4:4:404:404q4q4qqqqqtqy.",
|
||||
" $%$%$%&%&%=%&*=*=*=-=-=--;=--;:;-;:;:474:474747q7q7qqwqwqwrwe.",
|
||||
" $$$$*$1$*&*&*&*&*2*--2*-----3---4:3-4:4:4:4:404qqqqqqqqqtqtqu.",
|
||||
" &%$%&%&*&*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqq7qqwrqrwrwrip.",
|
||||
" $$*$*$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q404q4q4qtqqqiqtqiru.",
|
||||
" $%&%&*=%&*=*=*=-=-=--;-;-;:;-;:;:474:47q747q7q7qqwqwqwrwrirwu.",
|
||||
" *$1$*&*&*&*&*2*---*-----3---4:4:4:4:4:4:404qqqqqqqqqtqtqirira.",
|
||||
" &%&*=*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqqqqqwrqrwrwriririp.",
|
||||
" *$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q4q4qqq4qtqtqiqiqiriqira.",
|
||||
" &*=*&*=*=*=-=-=--;-;-;:;:;:;:474:47q7q7q7q7qqwrwqwrwrirwrisip.",
|
||||
" *&*&*&*&*2*---*-----3---4:4:4:4:404:404qqqqqqqqqtqtqiriririra.",
|
||||
" =*&*=-=*=---=--;---;:;:4:;:474:47q7q7qqqqqqwrwrwrwriririsdrdp.",
|
||||
" *&*2*=*2*-*-*-----4-3-4:4-4:4:404q4q4qqqqqtqtqiqiqiriqifirifa.",
|
||||
" &*=*=*=-=-=--;-;-;:;:;:;:474747q7q7qqq7qqwrwqwrwrirwrisisisdp.",
|
||||
" *&*&*2*---*-----3-3-4:4:4:4:404qq04qqqqqtqqqirtqiririririfida.",
|
||||
" =-=-=---=--;:;-;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdrdsdddp.",
|
||||
" *=*2*-*-*-----4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiriqifififidida.",
|
||||
" =*=-=-=--;-;-;:;:4:;:474747q7q7qqwqwqwrwqwrwrirwrisdsisdsdsdp.",
|
||||
" *2*---------4-3-4:4:4:4:404qq04qqqqqtqqqiririririririfidddddg.",
|
||||
" =---=--;:;:;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdsdsddddddhj.",
|
||||
" *---*-3---4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiririfififidddidkdl.",
|
||||
" =;=--;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrirwrisdsdsdsdsddhzhj.",
|
||||
" --------4-3-4:4:4:4:404qq04qqqqqtqqqiririririfirifidddddddddx.",
|
||||
" ---;:;:;:;:4:4:47q747qqq7qqwqqqwrwrirwriririsdsdsddddddhzhzhc.",
|
||||
" --3-3-4-4-4:4:4:4:404q4q4qqqqqtqtqiriqiririfififidddddkdkdXdx.",
|
||||
" -;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrisisisdsdsdddsddhzhdhzhg.",
|
||||
" ----4-3-4:4:4:4:404qqq4qqqqqtqtqiriririrififdfidddddkdddkzkdx.",
|
||||
" :;:;:;:4:4:47q7q7qqq7qqwrqqwrwriririririsdsdsddddddhzhzhzhzXc.",
|
||||
" 3-4-4-4:4:404:404q4q4qqqqqtqtqiriqiririfidididddddkdkdXdXdXzx.",
|
||||
" -;:;:474:47q747q7q7qqwqwqwrwrirwrisisisdsdsddddddhzhdhzhzXzhc.",
|
||||
" 4:4-4:4:4:4:404qqqqqqqqqtqtqiriririrififdfidddddkdddkzkdXzXzx.",
|
||||
" :;:4:4:47q7q7qqq7qqwrqrwrwriririsirisdsdsddddddhzhzhzhzXzXzXc.",
|
||||
" 4-4:4:404q404qqq4qtqqqiqtqiriqiririfidididddddkdkdXdXdXzXzXvx.",
|
||||
" :474:47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddddddhzhzhzhzXzhzX>5c.",
|
||||
" 4:4:4:4:404qqqqqqqqqtqtqiririririfiddfidddddkdddXzkdXzXzXvXzx.",
|
||||
" :4:47q7q7qqqqqqwrwrwrwriririsdrisdddsddddddhzhzXzhzXzXzX>5>5c.",
|
||||
" 4:404q4q4qqqqqtqtqiqiqiriqiririfidididddddkdkdXzXdXzXzXvXvXvx.",
|
||||
" :47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddhdddhzhzhzhzXzXzX>5>5>5b.",
|
||||
" 404:404qqqqqqqqqiqtqiririririfidddidddddkdkdXzkzXzXzXvXv5vX5n.",
|
||||
" >65656569698989y9e9u9ueumueupupapaplpgjgjgjgcgcgcgcxcbcncnbnb.",
|
||||
" ..............................................................."};
|
||||
62
wrlib/view.c
Normal file
62
wrlib/view.c
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "tile.xpm"
|
||||
Display *dpy;
|
||||
Window win;
|
||||
RContext *ctx;
|
||||
RImage *img;
|
||||
Pixmap pix;
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
attr.render_mode = RM_DITHER;
|
||||
attr.colors_per_channel = 4;
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
|
||||
if (argc<2)
|
||||
img = RGetImageFromXPMData(ctx, image_name);
|
||||
else
|
||||
img = RLoadImage(ctx, argv[1], argc>2 ? atol(argv[2]) : 0);
|
||||
|
||||
if (!img) {
|
||||
puts(RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
if (!RConvertImage(ctx, img, &pix)) {
|
||||
puts(RErrorString);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10, img->width,
|
||||
img->height, 0, 0, 0);
|
||||
XSelectInput(dpy, win, ExposureMask);
|
||||
XMapRaised(dpy, win);
|
||||
XSync(dpy, False);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, img->width, img->height,
|
||||
0, 0);
|
||||
|
||||
XSync(dpy, False);
|
||||
while (1) {
|
||||
XEvent ev;
|
||||
XNextEvent(dpy, &ev);
|
||||
if (ev.type==Expose)
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, img->width, img->height,
|
||||
0, 0);
|
||||
}
|
||||
XFlush(dpy);
|
||||
|
||||
getchar();
|
||||
}
|
||||
364
wrlib/wraster.h
Normal file
364
wrlib/wraster.h
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997, 1998 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Environment variables:
|
||||
*
|
||||
* WRASTER_GAMMA <rgamma>/<ggamma>/<bgamma>
|
||||
* gamma correction value. Must be greater than 0
|
||||
* Only for PseudoColor visuals.
|
||||
*
|
||||
* Default:
|
||||
* WRASTER_GAMMA 1/1/1
|
||||
*
|
||||
*
|
||||
* If you want a specific value for a screen, append the screen number
|
||||
* preceded by a hash to the variable name as in
|
||||
* WRASTER_GAMMA#1
|
||||
* for screen number 1
|
||||
*/
|
||||
|
||||
#ifndef RLRASTER_H_
|
||||
#define RLRASTER_H_
|
||||
|
||||
|
||||
/* version of the header for the library: 0.8 */
|
||||
#define WRASTER_HEADER_VERSION 8
|
||||
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef XSHM
|
||||
#include <X11/extensions/XShm.h>
|
||||
#endif
|
||||
|
||||
/* RM_MATCH or RM_DITHER */
|
||||
#define RC_RenderMode (1<<0)
|
||||
|
||||
/* number of colors per channel for colormap in PseudoColor mode */
|
||||
#define RC_ColorsPerChannel (1<<1)
|
||||
|
||||
/* do gamma correction */
|
||||
#define RC_GammaCorrection (1<<2)
|
||||
|
||||
/* visual id to use */
|
||||
#define RC_VisualID (1<<3)
|
||||
|
||||
/* shared memory usage */
|
||||
#define RC_UseSharedMemory (1<<4)
|
||||
|
||||
/* use default instead of best visual */
|
||||
#define RC_DefaultVisual (1<<5)
|
||||
|
||||
typedef struct RContextAttributes {
|
||||
int flags;
|
||||
int render_mode;
|
||||
int colors_per_channel; /* for PseudoColor */
|
||||
float rgamma; /* gamma correction for red, */
|
||||
float ggamma; /* green, */
|
||||
float bgamma; /* and blue */
|
||||
VisualID visualid; /* visual ID to use */
|
||||
int use_shared_memory; /* True of False */
|
||||
} RContextAttributes;
|
||||
|
||||
|
||||
/*
|
||||
* describes a screen in terms of depth, visual, number of colors
|
||||
* we can use, if we should do dithering, and what colors to use for
|
||||
* dithering.
|
||||
*/
|
||||
typedef struct RContext {
|
||||
Display *dpy;
|
||||
int screen_number;
|
||||
Colormap cmap;
|
||||
|
||||
RContextAttributes *attribs;
|
||||
|
||||
GC copy_gc;
|
||||
|
||||
Visual *visual;
|
||||
int depth;
|
||||
Window drawable; /* window to pass for XCreatePixmap().*/
|
||||
/* generally = root */
|
||||
int vclass;
|
||||
|
||||
unsigned long black;
|
||||
unsigned long white;
|
||||
|
||||
int red_offset; /* only used in 24bpp */
|
||||
int green_offset;
|
||||
int blue_offset;
|
||||
|
||||
/* only used for pseudocolor and grayscale */
|
||||
int ncolors; /* total number of colors we can use */
|
||||
XColor *colors; /* internal colormap */
|
||||
} RContext;
|
||||
|
||||
|
||||
typedef struct RColor {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char alpha;
|
||||
} RColor;
|
||||
|
||||
|
||||
typedef struct RHSVColor {
|
||||
unsigned short hue; /* 0-359 */
|
||||
unsigned char saturation; /* 0-255 */
|
||||
unsigned char value; /* 0-255 */
|
||||
} RHSVColor;
|
||||
|
||||
|
||||
|
||||
typedef struct RPoint {
|
||||
int x, y;
|
||||
} RPoint;
|
||||
|
||||
|
||||
typedef struct RSegment {
|
||||
int x1, y1, x2, y2;
|
||||
} RSegment;
|
||||
|
||||
|
||||
/*
|
||||
* internal 24bit+alpha image representation
|
||||
*/
|
||||
typedef struct RImage {
|
||||
unsigned width, height; /* size of the image */
|
||||
RColor background; /* background color */
|
||||
unsigned char *data[4]; /* image data (R,G,B,A) */
|
||||
} RImage;
|
||||
|
||||
|
||||
/*
|
||||
* internal wrapper for XImage. Used for shm abstraction
|
||||
*/
|
||||
typedef struct RXImage {
|
||||
XImage *image;
|
||||
#ifdef XSHM
|
||||
XShmSegmentInfo info;
|
||||
int is_shared;
|
||||
#endif
|
||||
} RXImage;
|
||||
|
||||
|
||||
/* note that not all operations are supported in all functions */
|
||||
enum {
|
||||
RClearOperation, /* clear with 0 */
|
||||
RCopyOperation,
|
||||
RNormalOperation, /* same as combine */
|
||||
RAddOperation,
|
||||
RSubtractOperation
|
||||
};
|
||||
|
||||
|
||||
/* image display modes */
|
||||
enum {
|
||||
RDitheredRendering = 0,
|
||||
RBestMatchRendering = 1
|
||||
};
|
||||
|
||||
/* bw compat */
|
||||
#define RM_DITHER RDitheredRendering
|
||||
#define RM_MATCH RBestMatchRendering
|
||||
|
||||
enum {
|
||||
RAbsoluteCoordinates = 0,
|
||||
RRelativeCoordinates = 1
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
RSunkenBevel = -1,
|
||||
RRaisedBevel = 1
|
||||
};
|
||||
/* bw compat */
|
||||
#define RBEV_SUNKEN RSunkenBevel
|
||||
/* 1 pixel wide */
|
||||
#define RBEV_RAISED RRaisedBevel
|
||||
/* 1 pixel wide on top/left 2 on bottom/right */
|
||||
#define RBEV_RAISED2 2
|
||||
/* 2 pixel width */
|
||||
#define RBEV_RAISED3 3
|
||||
|
||||
enum {
|
||||
RHorizontalGradient = 2,
|
||||
RVerticalGradient = 3,
|
||||
RDiagonalGradient = 4
|
||||
};
|
||||
/* for backwards compatibility */
|
||||
#define RGRD_HORIZONTAL RHorizontalGradient
|
||||
#define RGRD_VERTICAL RVerticalGradient
|
||||
#define RGRD_DIAGONAL RDiagonalGradient
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Returns a NULL terminated array of strings containing the
|
||||
* supported formats, such as: TIFF, XPM, PNG, JPEG, PPM, GIF
|
||||
*/
|
||||
char **RSupportedFileFormats(void);
|
||||
|
||||
void RFreeStringList(char **list);
|
||||
|
||||
/*
|
||||
* Xlib contexts
|
||||
*/
|
||||
RContext *RCreateContext(Display *dpy, int screen_number,
|
||||
RContextAttributes *attribs);
|
||||
|
||||
|
||||
Bool RGetClosestXColor(RContext *context, RColor *color, XColor *retColor);
|
||||
|
||||
/*
|
||||
* RImage creation
|
||||
*/
|
||||
RImage *RCreateImage(unsigned width, unsigned height, int alpha);
|
||||
|
||||
RImage *RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask);
|
||||
|
||||
RImage *RCreateImageFromDrawable(RContext *context, Drawable drawable,
|
||||
Pixmap mask);
|
||||
|
||||
RImage *RLoadImage(RContext *context, char *file, int index);
|
||||
|
||||
|
||||
void RDestroyImage(RImage *image);
|
||||
|
||||
RImage *RGetImageFromXPMData(RContext *context, char **data);
|
||||
|
||||
|
||||
/*
|
||||
* Area manipulation
|
||||
*/
|
||||
RImage *RCloneImage(RImage *image);
|
||||
|
||||
RImage *RGetSubImage(RImage *image, int x, int y, unsigned width,
|
||||
unsigned height);
|
||||
|
||||
void RCombineImageWithColor(RImage *image, RColor *color);
|
||||
|
||||
void RCombineImages(RImage *image, RImage *src);
|
||||
|
||||
void RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
|
||||
unsigned height, int dx, int dy);
|
||||
|
||||
void RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness);
|
||||
|
||||
void RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
|
||||
unsigned width, unsigned height, int dx, int dy,
|
||||
int opaqueness);
|
||||
|
||||
RImage *RScaleImage(RImage *image, unsigned new_width, unsigned new_height);
|
||||
|
||||
RImage *RMakeTiledImage(RImage *tile, unsigned width, unsigned height);
|
||||
|
||||
RImage* RMakeCenteredImage(RImage *image, unsigned width, unsigned height,
|
||||
RColor *color);
|
||||
|
||||
/*
|
||||
* Drawing
|
||||
*/
|
||||
Bool RGetPixel(RImage *image, int x, int y, RColor *color);
|
||||
|
||||
void RPutPixel(RImage *image, int x, int y, RColor *color);
|
||||
|
||||
void ROperatePixel(RImage *image, int operation, int x, int y, RColor *color);
|
||||
|
||||
void RPutPixels(RImage *image, RPoint *points, int npoints, int mode,
|
||||
RColor *color);
|
||||
|
||||
void ROperatePixels(RImage *image, int operation, RPoint *points,
|
||||
int npoints, int mode, RColor *color);
|
||||
|
||||
int RDrawLine(RImage *image, int x0, int y0, int x1, int y1, RColor *color);
|
||||
|
||||
int ROperateLine(RImage *image, int operation, int x0, int y0, int x1, int y1,
|
||||
RColor *color);
|
||||
|
||||
void RDrawLines(RImage *image, RPoint *points, int npoints, int mode,
|
||||
RColor *color);
|
||||
|
||||
void ROperateLines(RImage *image, int operation, RPoint *points, int npoints,
|
||||
int mode, RColor *color);
|
||||
|
||||
void RDrawSegments(RImage *image, RSegment *segs, int nsegs, RColor *color);
|
||||
|
||||
void ROperateSegments(RImage *image, int operation, RSegment *segs, int nsegs,
|
||||
RColor *color);
|
||||
|
||||
/*
|
||||
* Color convertion
|
||||
*/
|
||||
void RRGBtoHSV(RColor *color, RHSVColor *hsv);
|
||||
void RHSVtoRGB(RHSVColor *hsv, RColor *rgb);
|
||||
|
||||
/*
|
||||
* Painting
|
||||
*/
|
||||
int RClearImage(RImage *image, RColor *color);
|
||||
|
||||
int RBevelImage(RImage *image, int bevel_type);
|
||||
|
||||
RImage *RRenderGradient(unsigned width, unsigned height, RColor *from,
|
||||
RColor *to, int style);
|
||||
|
||||
|
||||
RImage *RRenderMultiGradient(unsigned width, unsigned height, RColor **colors,
|
||||
int style);
|
||||
|
||||
/*
|
||||
* Convertion into X Pixmaps
|
||||
*/
|
||||
int RConvertImage(RContext *context, RImage *image, Pixmap *pixmap);
|
||||
|
||||
int RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
|
||||
Pixmap *mask, int threshold);
|
||||
|
||||
|
||||
/*
|
||||
* misc. utilities
|
||||
*/
|
||||
RXImage *RCreateXImage(RContext *context, int depth,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
void RDestroyXImage(RContext *context, RXImage *ximage);
|
||||
|
||||
void RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage,
|
||||
int src_x, int src_y, int dest_x, int dest_y,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
|
||||
/****** Global Variables *******/
|
||||
|
||||
/*
|
||||
* Where error strings are stored
|
||||
*/
|
||||
extern char RErrorString[];
|
||||
|
||||
|
||||
#endif
|
||||
169
wrlib/xpixmap.c
Normal file
169
wrlib/xpixmap.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/* xpixmap.c - Make RImage from Pixmap or XImage
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
|
||||
static int
|
||||
get_shifts(unsigned long mask)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
while (mask) {
|
||||
mask>>=1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
|
||||
{
|
||||
RImage *img;
|
||||
int x, y;
|
||||
unsigned long pixel;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
int rshift, gshift, bshift;
|
||||
int rmask, gmask, bmask;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(image->format==ZPixmap);
|
||||
assert(!mask || mask->format==ZPixmap);
|
||||
|
||||
img = RCreateImage(image->width, image->height, mask!=NULL);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* I don't know why, but XGetImage() for pixmaps don't set the
|
||||
* {red,green,blue}_mask values correctly. This will not
|
||||
* work for imageis of depth different than the root window
|
||||
* one used in wrlib
|
||||
*/
|
||||
if (context->depth==image->depth) {
|
||||
rmask = context->visual->red_mask;
|
||||
gmask = context->visual->green_mask;
|
||||
bmask = context->visual->blue_mask;
|
||||
} else {
|
||||
rmask = image->red_mask;
|
||||
gmask = image->green_mask;
|
||||
bmask = image->blue_mask;
|
||||
}
|
||||
|
||||
/* how many bits to shift to normalize the color into 8bpp */
|
||||
rshift = get_shifts(rmask) - 8;
|
||||
gshift = get_shifts(gmask) - 8;
|
||||
bshift = get_shifts(bmask) - 8;
|
||||
|
||||
r = img->data[0];
|
||||
g = img->data[1];
|
||||
b = img->data[2];
|
||||
a = img->data[3];
|
||||
|
||||
#define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
|
||||
: ((pixel) & rmask) << -rshift)
|
||||
#define NORMALIZE_GREEN(pixel) ((gshift>0) ? ((pixel) & gmask) >> gshift \
|
||||
: ((pixel) & gmask) << -gshift)
|
||||
#define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
|
||||
: ((pixel) & bmask) << -bshift)
|
||||
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
*(r++) = NORMALIZE_RED(pixel);
|
||||
*(g++) = NORMALIZE_GREEN(pixel);
|
||||
*(b++) = NORMALIZE_BLUE(pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask && a) {
|
||||
for (y = 0; y < mask->height; y++) {
|
||||
for (x = 0; x < mask->width; x++) {
|
||||
if (XGetPixel(mask, x, y)) {
|
||||
*(a++) = 0xff;
|
||||
} else {
|
||||
*(a++) = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
|
||||
{
|
||||
RImage *image;
|
||||
XImage *pimg, *mimg;
|
||||
unsigned int w, h, bar;
|
||||
int foo;
|
||||
Window baz;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
assert(drawable!=None);
|
||||
|
||||
if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo,
|
||||
&w, &h, &bar, &bar)) {
|
||||
printf("wrlib:invalid window or pixmap passed to RCreateImageFromPixmap\n");
|
||||
return NULL;
|
||||
}
|
||||
pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes,
|
||||
ZPixmap);
|
||||
|
||||
if (!pimg) {
|
||||
sprintf(RErrorString, "could not get image");
|
||||
return NULL;
|
||||
}
|
||||
mimg = NULL;
|
||||
if (mask) {
|
||||
if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo,
|
||||
&w, &h, &bar, &bar)) {
|
||||
mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes,
|
||||
ZPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
image = RCreateImageFromXImage(context, pimg, mimg);
|
||||
|
||||
XDestroyImage(pimg);
|
||||
if (mimg)
|
||||
XDestroyImage(mimg);
|
||||
|
||||
return image;
|
||||
}
|
||||
228
wrlib/xpm.c
Normal file
228
wrlib/xpm.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/* xpm.c - load XPM image from file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#ifdef USE_XPM
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/xpm.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
RImage*
|
||||
RGetImageFromXPMData(RContext *context, char **data)
|
||||
{
|
||||
Display *dpy = context->dpy;
|
||||
Colormap cmap = context->cmap;
|
||||
RImage *image;
|
||||
XpmImage xpm;
|
||||
unsigned char *color_table[3];
|
||||
unsigned char *r, *g, *b, *a;
|
||||
int *p;
|
||||
int i;
|
||||
int transp=-1;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
if (XpmCreateXpmImageFromData(data, &xpm, (XpmInfo *)NULL)!=XpmSuccess) {
|
||||
sprintf(RErrorString, "error converting XPM data");
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height<1 || xpm.width < 1) {
|
||||
sprintf(RErrorString, "can't convert XPM data. Size too weird");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xpm.colorTable==NULL) {
|
||||
sprintf(RErrorString, "error converting XPM data");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, ":could not create RImage");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make color table */
|
||||
for (i=0; i<3; i++) {
|
||||
color_table[i] = malloc(xpm.ncolors*sizeof(char));
|
||||
if (!color_table[i]) {
|
||||
for (i=i-1;i>=0; i--) {
|
||||
if (color_table[i])
|
||||
free(color_table[i]);
|
||||
}
|
||||
RDestroyImage(image);
|
||||
sprintf(RErrorString, "out of memory while converting XPM data");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<xpm.ncolors; i++) {
|
||||
XColor xcolor;
|
||||
|
||||
if (strncmp(xpm.colorTable[i].c_color,"None",4)==0) {
|
||||
color_table[0][i]=0;
|
||||
color_table[1][i]=0;
|
||||
color_table[2][i]=0;
|
||||
transp = i;
|
||||
continue;
|
||||
}
|
||||
if (XParseColor(dpy, cmap, xpm.colorTable[i].c_color, &xcolor)) {
|
||||
color_table[0][i] = xcolor.red>>8;
|
||||
color_table[1][i] = xcolor.green>>8;
|
||||
color_table[2][i] = xcolor.blue>>8;
|
||||
} else {
|
||||
color_table[0][i]=0xbe;
|
||||
color_table[1][i]=0xbe;
|
||||
color_table[2][i]=0xbe;
|
||||
}
|
||||
}
|
||||
memset(image->data[3], 255, xpm.width*xpm.height);
|
||||
/* convert pixmap to RImage */
|
||||
p = (int*)xpm.data;
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
for (i=0; i<xpm.width*xpm.height; i++) {
|
||||
if (*p==transp)
|
||||
*a=0;
|
||||
a++;
|
||||
*(r++)=color_table[0][*p];
|
||||
*(g++)=color_table[1][*p];
|
||||
*(b++)=color_table[2][*p];
|
||||
p++;
|
||||
}
|
||||
for(i=0; i<3; i++) {
|
||||
free(color_table[i]);
|
||||
}
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadXPM(RContext *context, char *file, int index)
|
||||
{
|
||||
Display *dpy = context->dpy;
|
||||
Colormap cmap = context->cmap;
|
||||
RImage *image;
|
||||
XpmImage xpm;
|
||||
unsigned char *color_table[3];
|
||||
unsigned char *r, *g, *b, *a;
|
||||
int *p;
|
||||
int i;
|
||||
int transp=-1;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
if (XpmReadFileToXpmImage(file, &xpm, (XpmInfo *)NULL)!=XpmSuccess) {
|
||||
sprintf(RErrorString, "error loading XPM file \"%s\"", file);
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height<1 || xpm.width < 1) {
|
||||
sprintf(RErrorString, "can't load XPM file \"%s\". Size too weird",
|
||||
file);
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xpm.colorTable==NULL) {
|
||||
sprintf(RErrorString, "error loading XPM file \"%s\"", file);
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
strcat(RErrorString, ":could not create RImage");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make color table */
|
||||
for (i=0; i<3; i++) {
|
||||
color_table[i] = malloc(xpm.ncolors*sizeof(char));
|
||||
if (!color_table[i]) {
|
||||
for (i=i-1;i>=0; i--) {
|
||||
if (color_table[i])
|
||||
free(color_table[i]);
|
||||
}
|
||||
RDestroyImage(image);
|
||||
sprintf(RErrorString, "out of memory while loading file \"%s\"",
|
||||
file);
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<xpm.ncolors; i++) {
|
||||
XColor xcolor;
|
||||
|
||||
if (strncmp(xpm.colorTable[i].c_color,"None",4)==0) {
|
||||
color_table[0][i]=0;
|
||||
color_table[1][i]=0;
|
||||
color_table[2][i]=0;
|
||||
transp = i;
|
||||
continue;
|
||||
}
|
||||
if (XParseColor(dpy, cmap, xpm.colorTable[i].c_color, &xcolor)) {
|
||||
color_table[0][i] = xcolor.red>>8;
|
||||
color_table[1][i] = xcolor.green>>8;
|
||||
color_table[2][i] = xcolor.blue>>8;
|
||||
} else {
|
||||
color_table[0][i]=0xbe;
|
||||
color_table[1][i]=0xbe;
|
||||
color_table[2][i]=0xbe;
|
||||
}
|
||||
}
|
||||
memset(image->data[3], 255, xpm.width*xpm.height);
|
||||
/* convert pixmap to RImage */
|
||||
p = (int*)xpm.data;
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
for (i=0; i<xpm.width*xpm.height; i++) {
|
||||
if (*p==transp)
|
||||
*a=0;
|
||||
a++;
|
||||
*(r++)=color_table[0][*p];
|
||||
*(g++)=color_table[1][*p];
|
||||
*(b++)=color_table[2][*p];
|
||||
p++;
|
||||
}
|
||||
for(i=0; i<3; i++) {
|
||||
free(color_table[i]);
|
||||
}
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_XPM */
|
||||
199
wrlib/xutil.c
Normal file
199
wrlib/xutil.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/* xutil.c - utility functions for X
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef XSHM
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif /* XSHM */
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
#ifdef XSHM
|
||||
static int shmError;
|
||||
|
||||
static int (*oldErrorHandler)();
|
||||
|
||||
static int
|
||||
errorHandler(Display *dpy, XErrorEvent *err)
|
||||
{
|
||||
shmError=1;
|
||||
if(err->error_code!=BadAccess)
|
||||
(*oldErrorHandler)(dpy, err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
RXImage*
|
||||
RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
||||
{
|
||||
RXImage *rximg;
|
||||
|
||||
rximg = malloc(sizeof(RXImage));
|
||||
if (!rximg) {
|
||||
sprintf(RErrorString, "out of memory trying to create XImage");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef XSHM
|
||||
rximg->image = XCreateImage(context->dpy, context->visual, depth,
|
||||
ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "error creating XImage");
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "out of memory trying to create XImage");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* XSHM */
|
||||
if (!context->attribs->use_shared_memory) {
|
||||
retry_without_shm:
|
||||
rximg->is_shared = 0;
|
||||
rximg->image = XCreateImage(context->dpy, context->visual, depth,
|
||||
ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "error creating XImage");
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "out of memory trying to create XImage");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
rximg->is_shared = 1;
|
||||
|
||||
rximg->image = XShmCreateImage(context->dpy, context->visual, depth,
|
||||
ZPixmap, NULL, &rximg->info, width,
|
||||
height);
|
||||
|
||||
rximg->info.shmid = shmget(IPC_PRIVATE,
|
||||
rximg->image->bytes_per_line*height,
|
||||
IPC_CREAT|0770);
|
||||
if (rximg->info.shmid < 0) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
perror("wrlib:could not allocate shared memory segment:");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
|
||||
if (rximg->info.shmaddr == (void*)-1) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl:");
|
||||
perror("wrlib:could not allocate shared memory");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
shmError = 0;
|
||||
XSync(context->dpy, False);
|
||||
oldErrorHandler = XSetErrorHandler(errorHandler);
|
||||
XShmAttach(context->dpy, &rximg->info);
|
||||
XSync(context->dpy, False);
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
|
||||
rximg->image->data = rximg->info.shmaddr;
|
||||
/* rximg->image->obdata = &(rximg->info);*/
|
||||
|
||||
if (shmError) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
XDestroyImage(rximg->image);
|
||||
if (shmdt(rximg->info.shmaddr) < 0)
|
||||
perror("wrlib:shmdt:");
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl:");
|
||||
printf("wrlib:error attaching shared memory segment to XImage\n");
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* XSHM */
|
||||
|
||||
return rximg;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RDestroyXImage(RContext *context, RXImage *rximage)
|
||||
{
|
||||
#ifndef XSHM
|
||||
XDestroyImage(rximage->image);
|
||||
#else /* XSHM */
|
||||
if (rximage->is_shared) {
|
||||
XSync(context->dpy, False);
|
||||
XShmDetach(context->dpy, &rximage->info);
|
||||
XDestroyImage(rximage->image);
|
||||
if (shmdt(rximage->info.shmaddr) < 0)
|
||||
perror("wrlib:shmdt:");
|
||||
if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl:");
|
||||
} else {
|
||||
XDestroyImage(rximage->image);
|
||||
}
|
||||
#endif
|
||||
free(rximage);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
|
||||
int src_y, int dest_x, int dest_y,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
#ifndef XSHM
|
||||
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
|
||||
dest_y, width, height);
|
||||
#else
|
||||
if (ximage->is_shared) {
|
||||
XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
|
||||
dest_x, dest_y, width, height, False);
|
||||
} else {
|
||||
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
|
||||
dest_y, width, height);
|
||||
}
|
||||
XFlush(context->dpy);
|
||||
#endif /* XSHM */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user