mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
Compare commits
514 Commits
62821736fb
...
GIMP_2_2_1
Author | SHA1 | Date | |
---|---|---|---|
|
b89435a229 | ||
|
5a8de4ba60 | ||
|
844a25bef5 | ||
|
c1549fc492 | ||
|
fbabb4707d | ||
|
6b34b3fc5f | ||
|
79ec8c51f7 | ||
|
a6171e6095 | ||
|
accc4eb905 | ||
|
f7130af65e | ||
|
7597d3fab7 | ||
|
f9a440e94b | ||
|
35f6bb5c04 | ||
|
8302687f19 | ||
|
1eb648fb9e | ||
|
dd854d73d2 | ||
|
4478dee1af | ||
|
c7f33169d8 | ||
|
cdadb18354 | ||
|
0b2c347d50 | ||
|
f59fb4b7cb | ||
|
8f32fb1458 | ||
|
daf1949334 | ||
|
f559f8d29e | ||
|
3d1ce6a6f9 | ||
|
dad21d02bc | ||
|
9be6db24ce | ||
|
a332dce332 | ||
|
3de455e594 | ||
|
591285a83e | ||
|
4e81ce7fac | ||
|
68a83e01ad | ||
|
f32322932a | ||
|
6b2eef1328 | ||
|
af75d4c42c | ||
|
928cae73d8 | ||
|
15ec879692 | ||
|
3f0533388b | ||
|
789bd4e254 | ||
|
98a5c7e949 | ||
|
34bea2c7ca | ||
|
020313928f | ||
|
21c7130bd2 | ||
|
60866b3be2 | ||
|
8679544f4a | ||
|
a7f0ae2c85 | ||
|
352f4105dd | ||
|
0d05f03fc3 | ||
|
eccd4eabc6 | ||
|
31321f80b9 | ||
|
ca17c59069 | ||
|
2adba6aa82 | ||
|
20a2291b0a | ||
|
001f349358 | ||
|
e2c8e18392 | ||
|
b625e19a38 | ||
|
0203859997 | ||
|
de4ae4b2ac | ||
|
82c6b9c1cc | ||
|
682ab0404c | ||
|
7d58de4727 | ||
|
c52257d1e0 | ||
|
624900d5e6 | ||
|
0a3ae75df4 | ||
|
594c88fe21 | ||
|
d101b58ec1 | ||
|
b985b93e01 | ||
|
32f934e77e | ||
|
7cc700ca44 | ||
|
f2b65341fa | ||
|
6fd884f02d | ||
|
f2f3ccc334 | ||
|
93bfc30c88 | ||
|
e2b4fd1711 | ||
|
095e967909 | ||
|
6be1fa16a9 | ||
|
7a69091f90 | ||
|
e4d181d640 | ||
|
09242892bd | ||
|
e3626fe8fa | ||
|
f16ffd26b7 | ||
|
55b11f248b | ||
|
d875469bd2 | ||
|
296ba1da10 | ||
|
207538ea69 | ||
|
ec83ad8971 | ||
|
d5eb98c9ad | ||
|
260de8e5d7 | ||
|
ea1c479a43 | ||
|
bf919591ed | ||
|
e4e380af08 | ||
|
9183aaf414 | ||
|
3ccd79dd47 | ||
|
0a4bd8bde7 | ||
|
e2aa0d8f9d | ||
|
c9b87d04c7 | ||
|
cb4d60c4be | ||
|
c40e198b9a | ||
|
875bcf2881 | ||
|
953298a9cf | ||
|
520405657b | ||
|
9a439f986a | ||
|
5ccf672e97 | ||
|
fd3d04bef2 | ||
|
f6ab36f5ec | ||
|
187cf35107 | ||
|
f2f20b9316 | ||
|
1e9a573684 | ||
|
cbc2563ba3 | ||
|
8d479d5932 | ||
|
0adfb71572 | ||
|
2e2c69036e | ||
|
1ca6d30004 | ||
|
0530f2951f | ||
|
d725520e2b | ||
|
4ad9485ef7 | ||
|
c308a1c932 | ||
|
af21e3ee9f | ||
|
d38c79cc3a | ||
|
eabfacd5df | ||
|
8c9100d2b3 | ||
|
a6ffb322b9 | ||
|
79baff5456 | ||
|
8dc61605c2 | ||
|
c59086f70a | ||
|
a21dd52027 | ||
|
f8b4adabd8 | ||
|
f3daead0ee | ||
|
be6e2b3c4f | ||
|
ffce809108 | ||
|
9853887c92 | ||
|
c3776d3380 | ||
|
a3d25cb3bc | ||
|
08e6241c22 | ||
|
656f92c013 | ||
|
48d799bea4 | ||
|
14f6b4895b | ||
|
5340ff3d79 | ||
|
72675dd7f2 | ||
|
f145ddae21 | ||
|
359bc1e981 | ||
|
fa72fd4b5f | ||
|
8aa44c2ded | ||
|
7403c3fc87 | ||
|
89dde7ddab | ||
|
b4903c8bb8 | ||
|
95b9ceca84 | ||
|
b68ac9480e | ||
|
916812ed87 | ||
|
9ed1c9b4cf | ||
|
f5f59ec71f | ||
|
6441c632eb | ||
|
f019ba7ac6 | ||
|
a710f1211c | ||
|
3a185139b7 | ||
|
85c47d7f42 | ||
|
7b2126beac | ||
|
6b1a0ea7e4 | ||
|
7c627321d5 | ||
|
6637f93a97 | ||
|
5aa0a7a06c | ||
|
15a2334d44 | ||
|
8144d78ca3 | ||
|
319f21cc00 | ||
|
af357cd695 | ||
|
b0db6c4ea6 | ||
|
75e902004c | ||
|
da563a696e | ||
|
af0c9dc198 | ||
|
8b5d8cd974 | ||
|
f83901aa3f | ||
|
1401727ee3 | ||
|
deb9587b10 | ||
|
c883d735a0 | ||
|
56ae945a0a | ||
|
83d916570b | ||
|
366556dde2 | ||
|
9760516b03 | ||
|
cd5a8d34ce | ||
|
4a3ba16c2a | ||
|
184fda928b | ||
|
d552f08d46 | ||
|
3f38dac3d5 | ||
|
1466ad9eb1 | ||
|
2d0f932b20 | ||
|
37fb6994d2 | ||
|
fad8759521 | ||
|
d50e9e8b90 | ||
|
57db6ec8e2 | ||
|
364f775aaa | ||
|
0de0e8ad4e | ||
|
f01be98ba1 | ||
|
645e6a7b1c | ||
|
f00a2e7477 | ||
|
a01d48b195 | ||
|
dcf324f1a6 | ||
|
af12e35504 | ||
|
39402c68f4 | ||
|
eb082074f2 | ||
|
193fbc4e80 | ||
|
1293e78a67 | ||
|
8c7fdf2157 | ||
|
3aedadf462 | ||
|
8938c3737d | ||
|
87cdf69786 | ||
|
7c19fa6e74 | ||
|
5bf6c3c1bf | ||
|
9cc952baac | ||
|
ea74d83f19 | ||
|
770f4a3b84 | ||
|
d1c1a93a0b | ||
|
f59b6fe473 | ||
|
7b2276fb8d | ||
|
ceba721eb3 | ||
|
d2a3278827 | ||
|
7baebf7ec2 | ||
|
86d34fabf3 | ||
|
507faf7f28 | ||
|
e8bc9214f8 | ||
|
c33624d86c | ||
|
b355ab7008 | ||
|
09b663fe70 | ||
|
b082f3197e | ||
|
88a3456a29 | ||
|
0579d2d361 | ||
|
efc1b54727 | ||
|
b42c67d06f | ||
|
ca2dbf109f | ||
|
f286de2805 | ||
|
641fea3772 | ||
|
cdbd8ca5d7 | ||
|
48c653540c | ||
|
7d53336fe9 | ||
|
afbf378c73 | ||
|
437ede8ff9 | ||
|
9a35cd912e | ||
|
21e090f63c | ||
|
22e8d1543d | ||
|
845226cc89 | ||
|
2363344318 | ||
|
1e44e2326f | ||
|
51cb989c4c | ||
|
d84bcaca4a | ||
|
3c1154f835 | ||
|
494750b815 | ||
|
c459becec8 | ||
|
2a8e4a82e8 | ||
|
c994a08843 | ||
|
4510e68102 | ||
|
90f232fe51 | ||
|
6ddeff0a80 | ||
|
97c5038054 | ||
|
0fbbed49a6 | ||
|
75149a0294 | ||
|
6cbdd96808 | ||
|
2f334ee42f | ||
|
d0d63c11d2 | ||
|
3445cc286d | ||
|
6720b00204 | ||
|
376de4b173 | ||
|
0662242ae1 | ||
|
3f9e165696 | ||
|
79a36287bf | ||
|
268c18fd3e | ||
|
9cf0604d13 | ||
|
7a307cd5a3 | ||
|
df9333eb76 | ||
|
90f6cdbce7 | ||
|
643b13587a | ||
|
c1490f8c03 | ||
|
1cc7eb4845 | ||
|
c761756217 | ||
|
7b64d714e0 | ||
|
eb8cb546ae | ||
|
5da54083fb | ||
|
ae93b75e62 | ||
|
9a490d3da2 | ||
|
c174fb5a70 | ||
|
f6ebde014a | ||
|
e15d500ba4 | ||
|
8c6622bbf2 | ||
|
7464438741 | ||
|
fbd577183a | ||
|
11f28c93bc | ||
|
809dfc1843 | ||
|
4ebab399d0 | ||
|
3005882fd7 | ||
|
3f4e0df0ad | ||
|
d924f29ef5 | ||
|
6db0bb625e | ||
|
709f665d51 | ||
|
1fb0435c1a | ||
|
38bc647197 | ||
|
28ecf7836e | ||
|
e1e7925488 | ||
|
17b50156aa | ||
|
206cbc2c25 | ||
|
f1cacf9768 | ||
|
e39744aa34 | ||
|
87f015c15c | ||
|
a612da1b47 | ||
|
700aa7c92e | ||
|
b050836771 | ||
|
b301460d65 | ||
|
597d9acb96 | ||
|
9233bb583b | ||
|
2e9c8b04de | ||
|
78121d58ee | ||
|
9ea19ebcc9 | ||
|
115c09babf | ||
|
5fcd8a7261 | ||
|
75f6abacc6 | ||
|
ffc8cfd045 | ||
|
db6db434e5 | ||
|
c666e6b4b5 | ||
|
2b5f5714a8 | ||
|
6d31dc8775 | ||
|
f9f8a487fe | ||
|
15825d2c81 | ||
|
7e453190bd | ||
|
1653f48a12 | ||
|
00e50e205a | ||
|
d6ed244cc2 | ||
|
caba2acb9b | ||
|
8d704378ac | ||
|
45efa2f7c6 | ||
|
6b864723fe | ||
|
a2895970bd | ||
|
e447e75534 | ||
|
1888463bef | ||
|
d5187fa597 | ||
|
7dc9f9dcbc | ||
|
13d610f856 | ||
|
20c51fdcdb | ||
|
33bf5e0975 | ||
|
b91bc5a0f7 | ||
|
79d07f84fd | ||
|
e53e635980 | ||
|
431f958947 | ||
|
58af5fc180 | ||
|
d268151bc5 | ||
|
53ff3cf688 | ||
|
b6fe96abb0 | ||
|
ce2dffe141 | ||
|
d1fd07e56e | ||
|
4b0ad1f4b3 | ||
|
2ef770cd52 | ||
|
6012ff2305 | ||
|
a926121565 | ||
|
a7d8d18868 | ||
|
1220aa81b6 | ||
|
0070785231 | ||
|
60aeab1caa | ||
|
ead788d9b2 | ||
|
39bb0a38bc | ||
|
0f2cd40231 | ||
|
ae63be0ac4 | ||
|
ca8bf21fde | ||
|
a62680c81f | ||
|
b2b9401dd6 | ||
|
94649fd797 | ||
|
65b129df03 | ||
|
2d619f35ba | ||
|
9029ff4415 | ||
|
1e13246362 | ||
|
a91c39aca1 | ||
|
78632aac86 | ||
|
3721aea58f | ||
|
b5f8c129ae | ||
|
f11458f8c1 | ||
|
0c9292b1fc | ||
|
7bdc0b80e6 | ||
|
f77110641a | ||
|
a72c45efd4 | ||
|
fd9f144e4d | ||
|
6af024fba3 | ||
|
784ce7d0ac | ||
|
242e3fae17 | ||
|
90a4f52d55 | ||
|
2f4d16375e | ||
|
aa3befd64a | ||
|
708a48c867 | ||
|
866399971f | ||
|
63e9531f58 | ||
|
2b20e93df7 | ||
|
a7f409861b | ||
|
12a7391ae6 | ||
|
464f1423fa | ||
|
df50486006 | ||
|
3dd780ab7e | ||
|
19fae8c649 | ||
|
18b3f4e4bd | ||
|
36eaa88a6d | ||
|
a86ac2b129 | ||
|
202b370725 | ||
|
40080b1d3f | ||
|
9e93d1e605 | ||
|
7bd30e4c80 | ||
|
b7a1d41ec6 | ||
|
d31b2e20ee | ||
|
d5274aea23 | ||
|
149c283f95 | ||
|
3b64bbb975 | ||
|
41c698c54a | ||
|
450706b482 | ||
|
9d2b5bcaab | ||
|
16d22f4f47 | ||
|
8fc277d64f | ||
|
dfc4c296b7 | ||
|
77b6a8c5f4 | ||
|
133e350ec6 | ||
|
93cb959bfc | ||
|
b82de8ac7e | ||
|
9041299076 | ||
|
cdf7d54387 | ||
|
db01595cf2 | ||
|
1a6cb99eb0 | ||
|
1dec77ca31 | ||
|
cd021f711d | ||
|
e5b9d8d53a | ||
|
eeae809f5d | ||
|
507a009407 | ||
|
9d44271641 | ||
|
4269faf530 | ||
|
93effa0cca | ||
|
aa0054bc22 | ||
|
20bb067bbe | ||
|
1155c5004a | ||
|
c9aec80db6 | ||
|
3635296719 | ||
|
0fa8c4534a | ||
|
e9118bde0e | ||
|
902621e3ab | ||
|
726b0699a9 | ||
|
9d770f7051 | ||
|
afd6c2b469 | ||
|
0ea8fcf76b | ||
|
c4bc54c68c | ||
|
32440eccfb | ||
|
a413f3fa31 | ||
|
a02db2c7b8 | ||
|
6685a80479 | ||
|
e8c9656440 | ||
|
cc599127a7 | ||
|
cc37cf78ff | ||
|
99ddaf298c | ||
|
008966460f | ||
|
49ef8d8b83 | ||
|
d405dba237 | ||
|
5a7a02974f | ||
|
3db9509c12 | ||
|
53af771197 | ||
|
8632c4e9f4 | ||
|
5649dd557e | ||
|
77b2a421f0 | ||
|
20986ef746 | ||
|
f023a087f4 | ||
|
8af216e31d | ||
|
8c96fff260 | ||
|
62fa2b0dcc | ||
|
559276d4af | ||
|
f386036463 | ||
|
58b4220bf0 | ||
|
34bf50b054 | ||
|
11fd2a9817 | ||
|
285dbd9a79 | ||
|
a5bd90afe4 | ||
|
75497a88ae | ||
|
26bfc70adb | ||
|
cf4743c86d | ||
|
d5063b7381 | ||
|
11e5748a54 | ||
|
2e9dfbf497 | ||
|
da082212d4 | ||
|
529baa0319 | ||
|
2ba3f403fb | ||
|
59454ab882 | ||
|
c662d931f7 | ||
|
e53c1dc594 | ||
|
79112fe5dd | ||
|
8b0cc5afb5 | ||
|
2961ab77cf | ||
|
5957e9af2a | ||
|
54483737a0 | ||
|
b279dbc156 | ||
|
d7ea29d9b5 | ||
|
816939aa13 | ||
|
f9dfa75b05 | ||
|
91321ad40f | ||
|
088954fbc8 | ||
|
d03384998c | ||
|
f1779c533a | ||
|
ca7786e2e2 | ||
|
0269a53089 | ||
|
8beb39c8fa | ||
|
74f7135459 | ||
|
42438ec11e | ||
|
97e044f0e0 | ||
|
e635e7b7a4 | ||
|
57cc047fec | ||
|
b8eca42f07 | ||
|
7058dd5bfe | ||
|
8880c9ac1e | ||
|
b0710f76a5 | ||
|
f9c6c6f0c1 | ||
|
f50e63cac4 | ||
|
c6254ce51e | ||
|
0dbdc65494 | ||
|
e1dfff940e | ||
|
a23a0ab740 | ||
|
8fea4ec817 | ||
|
b30989c334 | ||
|
cc2eaae6f6 | ||
|
dfa016b6a3 |
9
HACKING
9
HACKING
@@ -5,7 +5,7 @@ to have the following packages (or newer versions) installed:
|
||||
|
||||
* GNU autoconf 2.54
|
||||
- ftp://ftp.gnu.org/gnu/autoconf/
|
||||
* GNU automake 1.7 (1.9, 1.8 and 1.6 will also work)
|
||||
* GNU automake 1.8 or newer
|
||||
- ftp://ftp.gnu.org/gnu/automake/
|
||||
* GNU libtool 1.4 (1.5 if you are compiling on Win32)
|
||||
- ftp://ftp.gnu.org/gnu/libtool/
|
||||
@@ -39,7 +39,7 @@ by running:
|
||||
|
||||
Basically this does the following for you:
|
||||
|
||||
cvsroot/gimp$ aclocal-1.7; libtoolize; automake-1.7 -a;
|
||||
cvsroot/gimp$ aclocal-1.9; libtoolize; automake-1.9 -a;
|
||||
cvsroot/gimp$ autoconf; glib-gettextize; intltoolize
|
||||
|
||||
The above commands create the "configure" script. Now you can run the
|
||||
@@ -63,6 +63,11 @@ the GIMP API reference manuals, you can set AUTOGEN_CONFIGURE_ARGS to
|
||||
"--enable-gtk-doc". Please note that you will then need a recent
|
||||
version of gtk-doc as well as a working setup for handling DocBook/XML.
|
||||
|
||||
If you do not have a recent version of gtk-doc, you can pass the
|
||||
option "--disable-gtk-doc" to autogen.sh. This will completely
|
||||
disable the support for gtk-doc so you will not be able to generate
|
||||
the API documentation.
|
||||
|
||||
|
||||
CVS
|
||||
---
|
||||
|
10
INSTALL
10
INSTALL
@@ -126,6 +126,16 @@ These are:
|
||||
use --without-mng to disable it expliticely. The same switch exists
|
||||
for aalib, use --without-aa if you run into problems.
|
||||
|
||||
--without-gtkhtml2. If for some reason you don't want to build the
|
||||
helpbrowser plug-in, you can use --without-gtkhtml2 to disable
|
||||
it explicitly.
|
||||
|
||||
--without-svg. If for some reason you want to build GIMP without
|
||||
SVG support, you can build --without-svg.
|
||||
|
||||
--without-lcms. If for some reason you want to build GIMP without
|
||||
using lcms for color support, you can build with --without-lcms.
|
||||
|
||||
--with-gif-compression=[lzw|rle|none]. Allows to tune the compression
|
||||
algorithm used by the GIF plug-in. If you are afraid of Unisys' LZW
|
||||
patent (which should have expired in most countries by now), you
|
||||
|
50
Makefile.am
50
Makefile.am
@@ -1,30 +1,30 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = \
|
||||
m4macros \
|
||||
tools \
|
||||
regexrepl \
|
||||
cursors \
|
||||
themes \
|
||||
po \
|
||||
po-libgimp \
|
||||
po-plug-ins \
|
||||
po-script-fu \
|
||||
data \
|
||||
menus \
|
||||
tips \
|
||||
libgimpbase \
|
||||
libgimpcolor \
|
||||
libgimpmath \
|
||||
libgimpmodule \
|
||||
libgimpthumb \
|
||||
libgimpwidgets \
|
||||
libgimp \
|
||||
app \
|
||||
$(GIMP_MODULES) \
|
||||
$(GIMP_PLUGINS) \
|
||||
etc \
|
||||
$(GIMP_DEVEL_DOCS) \
|
||||
m4macros \
|
||||
tools \
|
||||
regexrepl \
|
||||
cursors \
|
||||
themes \
|
||||
po \
|
||||
po-libgimp \
|
||||
po-plug-ins \
|
||||
po-script-fu \
|
||||
data \
|
||||
menus \
|
||||
tips \
|
||||
libgimpbase \
|
||||
libgimpcolor \
|
||||
libgimpmath \
|
||||
libgimpmodule \
|
||||
libgimpthumb \
|
||||
libgimpwidgets \
|
||||
libgimp \
|
||||
app \
|
||||
$(GIMP_MODULES) \
|
||||
$(GIMP_PLUGINS) \
|
||||
etc \
|
||||
devel-docs \
|
||||
docs
|
||||
|
||||
bin_SCRIPTS = gimptool-@GIMP_TOOL_VERSION@ @GIMPINSTALL@
|
||||
@@ -76,7 +76,7 @@ EXTRA_DIST = \
|
||||
po-script-fu/update.sh
|
||||
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gimp-console
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gimp-console --disable-print
|
||||
|
||||
DISTCLEANFILES = \
|
||||
intltool-extract \
|
||||
|
273
NEWS
273
NEWS
@@ -2,8 +2,277 @@ The GNU Image Manipulation Program Version 2.2
|
||||
----------------------------------------------
|
||||
|
||||
This is the stable branch of GIMP 2.2. Only bug-fixes are applied
|
||||
here. New features are being added in the HEAD branch that will lead
|
||||
to GIMP version 2.4.
|
||||
here. New features are being added in the HEAD branch that will be
|
||||
released as GIMP version 2.4.
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.13
|
||||
=========================
|
||||
|
||||
- avoid endless looping when loading a corrupt XCF file (bug #345802)
|
||||
- fixed regression in file dialogs (bug #347544)
|
||||
- fixed right-to-left layout in layers dialog (bug #348347)
|
||||
- avoid a crash when loading a corrupt gradient file (bug #349996)
|
||||
- fixed segfault in Warp plug-in on 64bit architectures (bug #327479)
|
||||
- fixed crash in GimpDrawablePreview (bug #350760)
|
||||
- fixed error in Winicon load plug-in (bug #172503)
|
||||
- fixed errors in Autocrop plug-in (bug #337888)
|
||||
- fixed compile errors in regression tests on OS X (bug #352221)
|
||||
- fixed regression in Gaussian Blur plug-in (bug #343047)
|
||||
- fixed crash when opening an RGB image in an indexed image (bug #345051)
|
||||
- fixed a possible crash in the Save dialog (bug #329001)
|
||||
- fixed Lighten Only layer mode on SSE2 platforms (bug #164061)
|
||||
- work with newer versions of autoconf
|
||||
- protect against bogus values returned from GDK (bug #340056)
|
||||
- fixed handling of indexed images in the Winicon save plug-in (bug #342883)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.12
|
||||
=========================
|
||||
|
||||
- fixed display problem in the Animation Playback plug-in (bug #338378)
|
||||
- fixed misbehaviour of the user installation dialog (bug #324254)
|
||||
- make sure that session-managed windows are mapped completely inside a
|
||||
monitor (bug #339099, bug #324254)
|
||||
- don't use long deprecated libpng API (bug #339402)
|
||||
- fixed possible segfault when closing image while saving it (bug #322978)
|
||||
- halt tools when the image mode changes (bug #330083)
|
||||
- fixed problem in Scale and Resize widgets (bug #336259)
|
||||
- fixed wrong offset in transform PDB functions (bug #342548)
|
||||
- fixed bugs in the Dicom load plug-in (bug #163256)
|
||||
- make sure text widgets get all key events first (bug #301006)
|
||||
- fixed problems with default values in the PNG save plug-in (bug #343284)
|
||||
- fixed Save As dialog not displaying the filename (bug #343284)
|
||||
- fixed compilation problem with gcc 4.1 (bug #345473)
|
||||
- plugged a possible buffer overrun in the XCF parser (bug #346742)
|
||||
- don't save image parasites twice in XCF files (bug #346754)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.11
|
||||
=========================
|
||||
|
||||
- fixed handling of EXIF data in JPEG plug-in (bug #303383)
|
||||
- let gimptool use pkg-config to determine compiler and linker flags at
|
||||
run-time (bug #324761)
|
||||
- added GTK+ category in gimp.desktop file (bug #328012)
|
||||
- fixed guides scripts to allow guides at the right and bottom (bug #328320)
|
||||
- fixed icons in color picker buttons in Levels tool (bug #325745)
|
||||
- fixed parameter check in Compressor plug-in
|
||||
- made the internal help browser the default for all platforms (bug #329888)
|
||||
- fixed handling of alpha channel in Gaussian Blur plug-in (bug #331051)
|
||||
- fixed incorrect bitshifts in Win Icon plug-in (bug #330692)
|
||||
- fixed a potential crash in the Animation Playback plug-in (bug #328919)
|
||||
- corrected tile cache size in Unsharp Mask plug-in (bug #331344)
|
||||
- fixed the import of SVG circles
|
||||
- fixed rounding of resolution in BMP plug-in (bug #332501)
|
||||
- fixed resolution handling in PSD load plug-in
|
||||
- store resolution when saving in the PSD file format (bug #310426)
|
||||
- fixed crash in Revert function (bug #333568)
|
||||
- flush the projection before reading from it (bug #332933)
|
||||
- fixed MMX instructions on Pentium II machines (bug #162778)
|
||||
- fixed possible crash on closing a dockable (bug #338286)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.10
|
||||
=========================
|
||||
|
||||
- fixed build error on Sun C compiler (bug #319811)
|
||||
- fixed issue with Guides scripts (bug #320933)
|
||||
- corrected selection display problem (bug #319029)
|
||||
- fixed potential wget issue (bug #322977)
|
||||
- fixed non-interactive use of gimp-edit-stroke (bug #323778)
|
||||
- fixed Script-Fu crash in some locales such as Chinese (bug #163212)
|
||||
- fixed build of librsvg plug-in (bug #314400)
|
||||
- fixed parameter type in "plug-in-unsharp-mask" procedure (bug #325007).
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.9
|
||||
========================
|
||||
|
||||
- fixed minor problem in JPEG plug-in (bug #309091)
|
||||
- allow to disable build of gtkhtml2, svg, and lcms features (bug #307704)
|
||||
- fixed bug in Imagemap plug-in (bug #169698)
|
||||
- handle PSD files with untitled channels (bug #312963)
|
||||
- fixed build of MMX/SSE assembly code on gcc 4.0 (bug #308412)
|
||||
- fixed crash in image preview code (bug #312144)
|
||||
- fixed redraw of previews in Rotate Colormap plug-in (bug #172284)
|
||||
- fixed redraw of previews in Filterpack plug-in (bug #160032)
|
||||
- cross-compilation fixes and build fixes for Cygwin (bug #314893)
|
||||
- fixed character placement in Text Circle script (bug #144588)
|
||||
- made GIMP more robust against strange characters in directory names
|
||||
- fixed minor issue in Dicom plug-in (bug #313008)
|
||||
- deal with API change in librsvg >= 2.11.0 (bug #314400)
|
||||
- fixed bug in ellipse selection (bug #315417)
|
||||
- fixed build issue on Cygwin (bug #314893)
|
||||
- fixed problem in ellipse selection (bug #315417)
|
||||
- ease closing of iscissors outline (bug #134250)
|
||||
- fixed handling of Tab key if NumLock is active (bug #317118)
|
||||
- fixed problem with random number generator in QBist plug-in (bug #317355)
|
||||
- raise palettes grid instead of creating a new one (bug #317435)
|
||||
- fixed problem with environment maps in Lighting plug-in (bug #313872)
|
||||
- fixed Gaussian Blur for small radii (bug #315953)
|
||||
- fixed Select By Color tool on grayscale layers (bug #319683)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.8
|
||||
========================
|
||||
|
||||
- fixed possible crash in plug-ins-query PDB function
|
||||
- fixes to Script-Fu server mode on Win32
|
||||
- fixed possible crash in win32 gimptool variant
|
||||
- plugged a tiny memleak in the image display code
|
||||
- plugged a tiny memleak in libgimpwidgets
|
||||
- attempt to fix calling the web-browser on win32 (bug #171200)
|
||||
- fixed loading of images in help-browser plug-in on win32
|
||||
- fixed zoom offsets if dot-for-dot mode is disabled (bug #306476)
|
||||
- fixes to Gfig parasite loading
|
||||
- disabled buggy gimprc option stingy-memory-use (bug #306617)
|
||||
- don't try to create a preview for a non-existant image file (bug #307672)
|
||||
- fixed bug in Retinex plug-in (bug #157915)
|
||||
- fixed bug in Newsprint plug-in (bug #161573)
|
||||
- fixed bug in Shift plug-in (bug #308748)
|
||||
- fixed bug in Grid plug-in (bug #308754)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.7
|
||||
========================
|
||||
|
||||
- update layer previews on colormap changes (bug #301033)
|
||||
- fixed loading of text layers from XCF files (bug #301028)
|
||||
- when loading a PDF, honor CropBox over MediaBox (bug #301432)
|
||||
- fixed incompatibility of GimpIntStore with GTK+ 2.6 (bug #301524)
|
||||
- fixed navigation popup in plug-in previews (bug #301523)
|
||||
- fixed handling of compression types in TIFF plug-in (bug #301557)
|
||||
- fixed bug in Lighting Effects plug-in (bug #302075)
|
||||
- fixed focus issues in message dialogs (bug #302400)
|
||||
- fixed bug in SSE2 assembly for Lighten Only layer mode (bug #164061)
|
||||
- fixed resize-window-on-zoom feature (bug #164281)
|
||||
- corrected upper limit of tile-cache-size (bug #303371)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.6
|
||||
========================
|
||||
|
||||
- reverted change to the print plug-in (see bug #169909)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.5
|
||||
========================
|
||||
|
||||
- fixed double-click behaviour of GimpButton
|
||||
- properly handle 302 redirect output from wget in URL plug-in (bug #168322)
|
||||
- fixed loading of layer masks in PSD plug-in (bug #166976)
|
||||
- fixed bugs in PSD save plug-in (bugs #167139 and #121871)
|
||||
- fixed Reset in Scale and Resize dialogs (bug #169011)
|
||||
- fixed filename encoding issues when loading Script-Fu scripts (bug #165002)
|
||||
- fixed i18n build quirks (bug #169274)
|
||||
- improve autoscrolling with tablets in Windows (bug #167960)
|
||||
- fixed setup of size entries in tool-options (bug #169066)
|
||||
- when opening images as layers, do it interactively (bug #168936)
|
||||
- fixed precondition checks in gimp_drawable_transform_scale (bug #170195)
|
||||
- fixed handling of resolution unit in Print Size dialog (bug #170200)
|
||||
- disable "gtk-alternative-button-order" setting because our code
|
||||
doesn't honor it (bug #170543)
|
||||
- fixed behaviour of selection tool when dragging from top-right (bug #143887)
|
||||
- speed up conversion of grayscale images to indexed colors (bug #170801)
|
||||
- fixed bug in grayscale to indexed color conversion (bug #170825)
|
||||
- don't offer empty palettes for conversion to indexed color (bug #170973)
|
||||
- disable search in container tree-views since it interferes with global
|
||||
accelerators (bug #169339)
|
||||
- corrected mousewheel section of default controllerrc (bug #171083)
|
||||
- fixed build on amd64/gcc-4.0 (bug #300227)
|
||||
- unset Keep Transparency from Color to Alpha plug-in.
|
||||
- fixed crash caused by Histogram dockable in RGB mode (bug #170116)
|
||||
- fixed statusbar display for negative moves (bug #171497)
|
||||
- fixed a couple of problems in the BMP plug-in (bug #171306, bug #171453
|
||||
and bug #171562)
|
||||
- fixed bug in Resize dialog if previews are turned off (bug #171827)
|
||||
- fixed disappearing previews in Rotate Colormap plug-in (bug #172284)
|
||||
- fixed deletion of fractals in Fractal Explorer plug-in (bug #172347)
|
||||
- fixed preview in Deinterlace plug-in (bug #172589)
|
||||
- fixed crashes on exit in some locales (bug #172581)
|
||||
- fixed installation directories for message catalogs (bug #169274)
|
||||
- handle deletion of layers and channels that have a floating selection
|
||||
attached (bug #168582)
|
||||
- plugged some smaller memory leaks
|
||||
- fixed preview in Gaussian Blur plug-in for zero radii (bug #173039)
|
||||
- fixed a couple of problems in the Winicon plug-in
|
||||
- fixed bug in GIF loader that was triggered with a broken GIF (bug #173119)
|
||||
- fixed crash in Ink tool (bug #164272)
|
||||
- let the text tool remember the last-used font (bug #171024)
|
||||
- quote the print command used in the Print plug-in (bug #169909)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.4
|
||||
========================
|
||||
|
||||
- fixed an out-of-bounds read access in the Edge plug-in (bug #164963)
|
||||
- limit aspect ratio in crop tool to sane values (bug #164827)
|
||||
- fixed indexed conversion on floating selections (bug #165342)
|
||||
- fixed button order in resize and scale dialogs
|
||||
- improved handling of UNC paths on Windows
|
||||
- fixed crash in winicon save plug-in (bug #162742)
|
||||
- fixed image types registration for some python plug-ins (bug #1666650)
|
||||
- workaround problems with font names ending in numbers (bug #166540)
|
||||
- show clone source when cloning from a different image (bug #167002)
|
||||
- corrected coordinate limits in New Guide script (bug #167529)
|
||||
- fixed crash in gradient editor (bug #167604)
|
||||
- don't give keyboard focus to combo boxes in image window (bug #167809)
|
||||
- fixed saving of MNG files with negative layer offsets (bug #166059)
|
||||
- fixed use of the text tool on floating selections (bug #166829)
|
||||
- don't create duplicate templates when migrating user settings (bug #167893)
|
||||
- let the py-slice script ignore out-of-bounds guides (bug #167843)
|
||||
- store thumbnails in temporary folder if no valid home directory exists
|
||||
(bug #167973)
|
||||
- fixed Emboss plug-in for small images (bug #168022)
|
||||
- avoid crashes in toolbox size allocation code (bug #162500)
|
||||
- switch from display-wide grab to application-wide grab while tool
|
||||
actions are being performed (bug #162823)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.3
|
||||
========================
|
||||
|
||||
- fixed build problem in MIDI input controller (bug #163593)
|
||||
- remember last used directory in file open and save dialogs (bug #162385)
|
||||
- fixed crashed in DND of indexed drawables (bug #163879)
|
||||
- removed bumpmap artifacts in Lighting Effects plug-in (bug #163877)
|
||||
- fixed non-interactive mode of Retinex plug-in
|
||||
- fixed undo of ink strokes (bug #163670)
|
||||
- fixed expose event handling in Curve Bend plug-in (bug #164207)
|
||||
- added a missing pressure sensitivity toggle to Airbrush tool (bug #164237)
|
||||
- fixed loading of XJT images files from read-only folders (bug #164116)
|
||||
- fixed bug in the Info dialog that crashed the Crop tool (bug #163617)
|
||||
- fixed yet another entry problem in the Scale Image dialog (bug #163951)
|
||||
- fixed serialization of binary parasites (bug #163131)
|
||||
- correctly initialize the preview in the Bumpmap plug-in (bug #162285)
|
||||
- give visual feedback if a dialog is already opened (bug #164156)
|
||||
- fixed saving of JPEG images with large quality settings (bug #164087)
|
||||
- update the menus when selecting a component in the Channels dialog
|
||||
(bug #164195)
|
||||
- fixed issues with the save dialog in the Imagemap plug-in (bug #164864)
|
||||
- update filesize in JPEG dialog if size of EXIF data changes (bug #164914)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.2
|
||||
========================
|
||||
|
||||
- let Decompose plug-in create layers with alpha channel
|
||||
- fixed crash in save dialog (bug #162443)
|
||||
- fixed misbehaviour in Scale and Resize dialogs (bug #162387)
|
||||
- fixed preview in Imagemap plug-in (bug #162592)
|
||||
- fixed handling of broken menu path translations (bug #162590)
|
||||
- fixed bugs in the Sparkle plug-in and the Frosty Logo script (bug #132145)
|
||||
- fixed two broken Python scripts (bug #162707)
|
||||
- changed default response in Close dialog (bug #162872)
|
||||
- flush the display when plug-in dialogs are disposed (bug #163084)
|
||||
- fixed build problem on amd64 with gcc-4.0 (bug #163041)
|
||||
- fixed problem in locales that are rendered right-to-left (bug #162663)
|
||||
- fixed bug in Frosty Logo Script-Fu (bug #132145)
|
||||
- raise the toolbox when it is selected from the Tools menu (bug #163381)
|
||||
- improved usability of Keyboard Shortcuts editor (bug #163385)
|
||||
- fixed gradient selection widget in libgimpui (bug #163427)
|
||||
- workaround a problem in the MMX code (bug #162778)
|
||||
|
||||
|
||||
Bugs fixed in GIMP 2.2.1
|
||||
|
7
README
7
README
@@ -87,10 +87,13 @@ end. But if you are absolutely allergic to ads, don't subscribe.
|
||||
======
|
||||
|
||||
And finally, for the real junkies, there is an IRC channel devoted to
|
||||
the GIMP. On Byxnet (a private mostly-GIMP network) there is #gimp.
|
||||
Many of the developers hang out there. One of the Byxnet servers are:
|
||||
the GIMP. On GIMPNet (a private free software oriented network) there is
|
||||
#gimp. Many of the developers hang out there. Some of the GIMPNet
|
||||
servers are:
|
||||
|
||||
irc.gimp.org:6667
|
||||
irc.us.gimp.org:6667
|
||||
irc.eu.gimp.org:6667
|
||||
|
||||
|
||||
4. Customizing
|
||||
|
10
README.win32
10
README.win32
@@ -1,6 +1,10 @@
|
||||
For pre-built binary packages of GLib, GTK etc, see
|
||||
http://www.gimp.org/win32/downloads.html . No pre-built GIMP 1.3
|
||||
packages, though.
|
||||
For pre-built binary packages of GIMP, see
|
||||
http://gimp-win.sourceforge.net.
|
||||
|
||||
GIMP 2.2.x should be built against GLib 2.4. Building against GLib 2.6
|
||||
or later will result in a GIMP that doesn't handle non-ASCII filenames
|
||||
correctly. It is fine to *run* GIMP 2.2.x against GLib 2.6 or later,
|
||||
though.
|
||||
|
||||
Building GIMP on Win32
|
||||
======================
|
||||
|
73
acinclude.m4
73
acinclude.m4
@@ -364,3 +364,76 @@ dnl That should be it. Now just export out symbols:
|
||||
AC_SUBST(ALSA_CFLAGS)
|
||||
AC_SUBST(ALSA_LIBS)
|
||||
])
|
||||
|
||||
dnl The following lines were copied from gtk-doc.m4
|
||||
|
||||
dnl Usage:
|
||||
dnl GTK_DOC_CHECK([minimum-gtk-doc-version])
|
||||
AC_DEFUN([GTK_DOC_CHECK],
|
||||
[
|
||||
AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
|
||||
AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
|
||||
dnl for overriding the documentation installation directory
|
||||
AC_ARG_WITH(html-dir,
|
||||
AC_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),,
|
||||
[with_html_dir='${datadir}/gtk-doc/html'])
|
||||
HTML_DIR="$with_html_dir"
|
||||
AC_SUBST(HTML_DIR)
|
||||
|
||||
dnl enable/disable documentation building
|
||||
AC_ARG_ENABLE(gtk-doc,
|
||||
AC_HELP_STRING([--enable-gtk-doc],
|
||||
[use gtk-doc to build documentation (default=no)]),,
|
||||
enable_gtk_doc=no)
|
||||
|
||||
have_gtk_doc=no
|
||||
if test x$enable_gtk_doc = xyes; then
|
||||
if test -z "$PKG_CONFIG"; then
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
fi
|
||||
if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists gtk-doc; then
|
||||
have_gtk_doc=yes
|
||||
fi
|
||||
|
||||
dnl do we want to do a version check?
|
||||
ifelse([$1],[],,
|
||||
[gtk_doc_min_version=$1
|
||||
if test "$have_gtk_doc" = yes; then
|
||||
AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version])
|
||||
if $PKG_CONFIG --atleast-version $gtk_doc_min_version gtk-doc; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
have_gtk_doc=no
|
||||
fi
|
||||
fi
|
||||
])
|
||||
if test "$have_gtk_doc" != yes; then
|
||||
enable_gtk_doc=no
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes)
|
||||
AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL")
|
||||
])
|
||||
|
||||
dnl GIMP_DETECT_CFLAGS(RESULT, FLAGSET)
|
||||
dnl Detect if the compiler supports a set of flags
|
||||
|
||||
AC_DEFUN([GIMP_DETECT_CFLAGS],
|
||||
[
|
||||
$1=
|
||||
for flag in $2; do
|
||||
if test -z "[$]$1"; then
|
||||
$1_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $flag"
|
||||
AC_MSG_CHECKING([whether [$]CC understands [$]flag])
|
||||
AC_TRY_COMPILE([], [], [$1_works=yes], [$1_works=no])
|
||||
AC_MSG_RESULT([$]$1_works)
|
||||
CFLAGS="[$]$1_save_CFLAGS"
|
||||
if test "x[$]$1_works" = "xyes"; then
|
||||
$1="$flag"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
])
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "core/gimpimage.h"
|
||||
|
||||
#include "widgets/gimpactionfactory.h"
|
||||
#include "widgets/gimpactiongroup.h"
|
||||
#include "widgets/gimpcontainereditor.h"
|
||||
#include "widgets/gimpcontainerview.h"
|
||||
#include "widgets/gimpdock.h"
|
||||
@@ -162,7 +163,7 @@ static GimpActionFactoryEntry action_groups[] =
|
||||
{ "plug-in", N_("Plug-Ins"), GIMP_STOCK_PLUGIN,
|
||||
plug_in_actions_setup,
|
||||
plug_in_actions_update },
|
||||
{ "qmask", N_("QuickMask"), GIMP_STOCK_QMASK_ON,
|
||||
{ "qmask", N_("Quick Mask"), GIMP_STOCK_QMASK_ON,
|
||||
qmask_actions_setup,
|
||||
qmask_actions_update },
|
||||
{ "select", N_("Select"), GIMP_STOCK_SELECTION,
|
||||
|
@@ -133,7 +133,7 @@ GimpStringActionEntry dialogs_dockable_actions[] =
|
||||
|
||||
{ "dialogs-palettes", GIMP_STOCK_PALETTE,
|
||||
N_("Pal_ettes"), "<control>P", NULL,
|
||||
"gimp-palette-list|gimp-palette-list",
|
||||
"gimp-palette-list|gimp-palette-grid",
|
||||
GIMP_HELP_PALETTE_DIALOG },
|
||||
|
||||
{ "dialogs-fonts", GIMP_STOCK_FONT,
|
||||
|
@@ -20,6 +20,11 @@
|
||||
#define __DIALOGS_ACTIONS_H__
|
||||
|
||||
|
||||
/* this check is needed for the extern declaration below to be correct */
|
||||
#ifndef __GIMP_ACTION_GROUP_H__
|
||||
#error "widgets/gimpactiongroup.h must be included prior to dialog-actions.h"
|
||||
#endif
|
||||
|
||||
extern GimpStringActionEntry dialogs_dockable_actions[];
|
||||
extern gint n_dialogs_dockable_actions;
|
||||
|
||||
|
@@ -253,6 +253,8 @@ dockable_actions_update (GimpActionGroup *group,
|
||||
#define SET_SENSITIVE(action,sensitive) \
|
||||
gimp_action_group_set_action_sensitive (group, action, (sensitive) != 0)
|
||||
|
||||
SET_SENSITIVE ("dockable-detach-tab", n_pages > 1);
|
||||
|
||||
SET_VISIBLE ("dockable-preview-size-menu", preview_size != -1);
|
||||
|
||||
if (preview_size != -1)
|
||||
|
@@ -94,10 +94,17 @@ void
|
||||
file_open_from_image_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GimpImage *image;
|
||||
GtkWidget *widget;
|
||||
const gchar *uri = NULL;
|
||||
return_if_no_widget (widget, data);
|
||||
|
||||
file_open_dialog_show (widget, action_data_get_image (data), NULL, FALSE);
|
||||
image = action_data_get_image (data);
|
||||
|
||||
if (image)
|
||||
uri = gimp_object_get_name (GIMP_OBJECT (image));
|
||||
|
||||
file_open_dialog_show (widget, NULL, uri, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -365,7 +372,8 @@ file_open_dialog_show (GtkWidget *parent,
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
gimp_file_dialog_set_uri (GIMP_FILE_DIALOG (dialog), gimage, uri);
|
||||
if (uri)
|
||||
gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), uri);
|
||||
|
||||
if (open_as_layer)
|
||||
{
|
||||
@@ -410,7 +418,6 @@ file_save_dialog_show (GimpImage *gimage,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
gtk_window_set_title (GTK_WINDOW (dialog), title);
|
||||
|
@@ -219,11 +219,12 @@ plug_in_actions_add_proc (GimpActionGroup *group,
|
||||
path_original = proc_def->menu_paths->data;
|
||||
path_translated = dgettext (locale_domain, path_original);
|
||||
|
||||
if (! plug_in_actions_check_translation (path_original, path_translated))
|
||||
return;
|
||||
path_original = g_strdup (path_original);
|
||||
|
||||
path_original = g_strdup (path_original);
|
||||
path_translated = g_strdup (path_translated);
|
||||
if (plug_in_actions_check_translation (path_original, path_translated))
|
||||
path_translated = g_strdup (path_translated);
|
||||
else
|
||||
path_translated = g_strdup (path_original);
|
||||
|
||||
p1 = strrchr (path_original, '/');
|
||||
p2 = strrchr (path_translated, '/');
|
||||
@@ -263,6 +264,8 @@ plug_in_actions_add_proc (GimpActionGroup *group,
|
||||
|
||||
if (plug_in_actions_check_translation (original, translated))
|
||||
plug_in_actions_build_path (group, original, translated);
|
||||
else
|
||||
plug_in_actions_build_path (group, original, original);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -295,6 +298,8 @@ plug_in_actions_add_path (GimpActionGroup *group,
|
||||
|
||||
if (plug_in_actions_check_translation (menu_path, path_translated))
|
||||
plug_in_actions_build_path (group, menu_path, path_translated);
|
||||
else
|
||||
plug_in_actions_build_path (group, menu_path, menu_path);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -61,14 +61,13 @@ plug_in_run_cmd_callback (GtkAction *action,
|
||||
PlugInProcDef *proc_def,
|
||||
gpointer data)
|
||||
{
|
||||
Gimp *gimp;
|
||||
ProcRecord *proc_rec;
|
||||
Argument *args;
|
||||
GimpDisplay *gdisp = NULL;
|
||||
gint gdisp_ID = -1;
|
||||
gint i;
|
||||
gint argc;
|
||||
GimpImageType drawable_type = GIMP_RGB_IMAGE;
|
||||
Gimp *gimp;
|
||||
ProcRecord *proc_rec;
|
||||
Argument *args;
|
||||
GimpDisplay *gdisp = NULL;
|
||||
gint gdisp_ID = -1;
|
||||
gint i;
|
||||
gint argc;
|
||||
|
||||
gimp = action_data_get_gimp (data);
|
||||
if (! gimp)
|
||||
@@ -115,8 +114,6 @@ plug_in_run_cmd_callback (GtkAction *action,
|
||||
|
||||
if (drawable)
|
||||
{
|
||||
drawable_type = gimp_drawable_type (drawable);
|
||||
|
||||
args[2].value.pdb_int =
|
||||
gimp_item_get_ID (GIMP_ITEM (drawable));
|
||||
argc++;
|
||||
@@ -145,7 +142,7 @@ plug_in_run_cmd_callback (GtkAction *action,
|
||||
|
||||
/* remember only "standard" plug-ins */
|
||||
if (proc_rec->proc_type == GIMP_PLUGIN &&
|
||||
proc_rec->num_args >= 2 &&
|
||||
proc_rec->num_args >= 3 &&
|
||||
proc_rec->args[1].arg_type == GIMP_PDB_IMAGE &&
|
||||
proc_rec->args[2].arg_type == GIMP_PDB_DRAWABLE)
|
||||
{
|
||||
|
@@ -1,146 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "actions-types.h"
|
||||
|
||||
#include "core/gimpimage.h"
|
||||
|
||||
#include "widgets/gimpactiongroup.h"
|
||||
#include "widgets/gimphelp-ids.h"
|
||||
|
||||
#include "actions.h"
|
||||
#include "qmask-actions.h"
|
||||
#include "qmask-commands.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static GimpActionEntry qmask_actions[] =
|
||||
{
|
||||
{ "qmask-popup", NULL,
|
||||
N_("Quick Mask Menu"), NULL, NULL, NULL,
|
||||
GIMP_HELP_QMASK },
|
||||
|
||||
{ "qmask-configure", NULL,
|
||||
N_("_Configure Color and Opacity..."), NULL, NULL,
|
||||
G_CALLBACK (qmask_configure_cmd_callback),
|
||||
GIMP_HELP_QMASK_EDIT }
|
||||
};
|
||||
|
||||
static GimpToggleActionEntry qmask_toggle_actions[] =
|
||||
{
|
||||
{ "qmask-active", NULL,
|
||||
N_("_Quick Mask Active"), NULL, NULL,
|
||||
G_CALLBACK (qmask_toggle_cmd_callback),
|
||||
FALSE,
|
||||
GIMP_HELP_QMASK_TOGGLE },
|
||||
|
||||
{ "qmask-toggle", GIMP_STOCK_QMASK_ON,
|
||||
N_("Toggle _Quick Mask"), "<shift>Q", NULL,
|
||||
G_CALLBACK (qmask_toggle_cmd_callback),
|
||||
FALSE,
|
||||
GIMP_HELP_QMASK_TOGGLE }
|
||||
|
||||
};
|
||||
|
||||
static GimpRadioActionEntry qmask_invert_actions[] =
|
||||
{
|
||||
{ "qmask-invert-on", NULL,
|
||||
N_("Mask _Selected Areas"), NULL, NULL,
|
||||
TRUE,
|
||||
GIMP_HELP_QMASK_INVERT },
|
||||
|
||||
{ "qmask-invert-off", NULL,
|
||||
N_("Mask _Unselected Areas"), NULL, NULL,
|
||||
FALSE,
|
||||
GIMP_HELP_QMASK_INVERT }
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
qmask_actions_setup (GimpActionGroup *group)
|
||||
{
|
||||
GtkAction *action;
|
||||
|
||||
gimp_action_group_add_actions (group,
|
||||
qmask_actions,
|
||||
G_N_ELEMENTS (qmask_actions));
|
||||
|
||||
gimp_action_group_add_toggle_actions (group,
|
||||
qmask_toggle_actions,
|
||||
G_N_ELEMENTS (qmask_toggle_actions));
|
||||
|
||||
gimp_action_group_add_radio_actions (group,
|
||||
qmask_invert_actions,
|
||||
G_N_ELEMENTS (qmask_invert_actions),
|
||||
FALSE,
|
||||
G_CALLBACK (qmask_invert_cmd_callback));
|
||||
|
||||
action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
|
||||
"qmask-active");
|
||||
gtk_action_set_accel_path (action, "<Actions>/qmask/qmask-toggle");
|
||||
|
||||
#ifdef __GNUC__
|
||||
#warning FIXME: remove accel_path hack
|
||||
#endif
|
||||
g_object_set_data (G_OBJECT (action), "gimp-accel-path",
|
||||
"<Actions>/qmask/qmask-toggle");
|
||||
}
|
||||
|
||||
void
|
||||
qmask_actions_update (GimpActionGroup *group,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *gimage = action_data_get_image (data);
|
||||
|
||||
#define SET_SENSITIVE(action,sensitive) \
|
||||
gimp_action_group_set_action_sensitive (group, action, (sensitive) != 0)
|
||||
#define SET_ACTIVE(action,active) \
|
||||
gimp_action_group_set_action_active (group, action, (active) != 0)
|
||||
#define SET_COLOR(action,color) \
|
||||
gimp_action_group_set_action_color (group, action, (color), FALSE)
|
||||
|
||||
SET_SENSITIVE ("qmask-active", gimage);
|
||||
SET_SENSITIVE ("qmask-toggle", gimage);
|
||||
|
||||
SET_ACTIVE ("qmask-active", gimage && gimage->qmask_state);
|
||||
SET_ACTIVE ("qmask-toggle", gimage && gimage->qmask_state);
|
||||
|
||||
SET_SENSITIVE ("qmask-invert-on", gimage);
|
||||
SET_SENSITIVE ("qmask-invert-off", gimage);
|
||||
|
||||
if (gimage && gimage->qmask_inverted)
|
||||
SET_ACTIVE ("qmask-invert-on", TRUE);
|
||||
else
|
||||
SET_ACTIVE ("qmask-invert-off", TRUE);
|
||||
|
||||
SET_SENSITIVE ("qmask-configure", gimage);
|
||||
|
||||
if (gimage)
|
||||
SET_COLOR ("qmask-configure", &gimage->qmask_color);
|
||||
|
||||
#undef SET_SENSITIVE
|
||||
#undef SET_ACTIVE
|
||||
#undef SET_COLOR
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __QMASK_ACTIONS_H__
|
||||
#define __QMASK_ACTIONS_H__
|
||||
|
||||
|
||||
void qmask_actions_setup (GimpActionGroup *group);
|
||||
void qmask_actions_update (GimpActionGroup *group,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#endif /* __QMASK_ACTIONS_H__ */
|
@@ -1,147 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "actions-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpchannel.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-qmask.h"
|
||||
|
||||
#include "widgets/gimphelp-ids.h"
|
||||
|
||||
#include "dialogs/channel-options-dialog.h"
|
||||
|
||||
#include "actions.h"
|
||||
#include "qmask-commands.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void qmask_configure_response (GtkWidget *widget,
|
||||
gint response_id,
|
||||
ChannelOptionsDialog *options);
|
||||
|
||||
|
||||
/* public functionss */
|
||||
|
||||
void
|
||||
qmask_toggle_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *gimage;
|
||||
gboolean active;
|
||||
return_if_no_image (gimage, data);
|
||||
|
||||
active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
|
||||
|
||||
if (active != gimp_image_get_qmask_state (gimage))
|
||||
{
|
||||
gimp_image_set_qmask_state (gimage, active);
|
||||
gimp_image_flush (gimage);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
qmask_invert_cmd_callback (GtkAction *action,
|
||||
GtkAction *current,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *gimage;
|
||||
gint value;
|
||||
return_if_no_image (gimage, data);
|
||||
|
||||
value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
|
||||
|
||||
if (value != gimage->qmask_inverted)
|
||||
{
|
||||
gimp_image_qmask_invert (gimage);
|
||||
gimp_image_flush (gimage);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
qmask_configure_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
{
|
||||
ChannelOptionsDialog *options;
|
||||
GimpImage *gimage;
|
||||
GtkWidget *widget;
|
||||
GimpRGB color;
|
||||
return_if_no_image (gimage, data);
|
||||
return_if_no_widget (widget, data);
|
||||
|
||||
gimp_image_get_qmask_color (gimage, &color);
|
||||
|
||||
options = channel_options_dialog_new (gimage,
|
||||
action_data_get_context (data),
|
||||
NULL,
|
||||
widget,
|
||||
&color,
|
||||
NULL,
|
||||
_("Quick Mask Attributes"),
|
||||
"gimp-qmask-edit",
|
||||
GIMP_STOCK_QMASK_ON,
|
||||
_("Edit Quick Mask Attributes"),
|
||||
GIMP_HELP_QMASK_EDIT,
|
||||
_("Edit Quick Mask Color"),
|
||||
_("Mask Opacity:"));
|
||||
|
||||
g_signal_connect (options->dialog, "response",
|
||||
G_CALLBACK (qmask_configure_response),
|
||||
options);
|
||||
|
||||
gtk_widget_show (options->dialog);
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
qmask_configure_response (GtkWidget *widget,
|
||||
gint response_id,
|
||||
ChannelOptionsDialog *options)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
{
|
||||
GimpRGB old_color;
|
||||
GimpRGB new_color;
|
||||
|
||||
gimp_image_get_qmask_color (options->gimage, &old_color);
|
||||
gimp_color_button_get_color (GIMP_COLOR_BUTTON (options->color_panel),
|
||||
&new_color);
|
||||
|
||||
if (gimp_rgba_distance (&old_color, &new_color) > 0.0001)
|
||||
{
|
||||
gimp_image_set_qmask_color (options->gimage, &new_color);
|
||||
|
||||
gimp_image_flush (options->gimage);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy (options->dialog);
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __QMASK_COMMANDS_H__
|
||||
#define __QMASK_COMMANDS_H__
|
||||
|
||||
|
||||
void qmask_toggle_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
void qmask_invert_cmd_callback (GtkAction *action,
|
||||
GtkAction *current,
|
||||
gpointer data);
|
||||
void qmask_configure_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#endif /* __QMASK_COMMANDS_H__ */
|
440
app/airbrush.c
440
app/airbrush.c
@@ -1,440 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "appenv.h"
|
||||
#include "airbrush.h"
|
||||
#include "drawable.h"
|
||||
#include "gdisplay.h"
|
||||
#include "gradient.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimpui.h"
|
||||
#include "paint_funcs.h"
|
||||
#include "paint_core.h"
|
||||
#include "paint_options.h"
|
||||
#include "selection.h"
|
||||
#include "temp_buf.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
/* The maximum amount of pressure that can be exerted */
|
||||
#define MAX_PRESSURE 0.075
|
||||
|
||||
/* Default pressure setting */
|
||||
#define AIRBRUSH_PRESSURE_DEFAULT 10.0
|
||||
#define AIRBRUSH_INCREMENTAL_DEFAULT FALSE
|
||||
|
||||
#define OFF 0
|
||||
#define ON 1
|
||||
|
||||
/* the airbrush structures */
|
||||
|
||||
typedef struct _AirbrushTimeout AirbrushTimeout;
|
||||
|
||||
struct _AirbrushTimeout
|
||||
{
|
||||
PaintCore *paint_core;
|
||||
GimpDrawable *drawable;
|
||||
};
|
||||
|
||||
typedef struct _AirbrushOptions AirbrushOptions;
|
||||
|
||||
struct _AirbrushOptions
|
||||
{
|
||||
PaintOptions paint_options;
|
||||
|
||||
gdouble rate;
|
||||
gdouble rate_d;
|
||||
GtkObject *rate_w;
|
||||
|
||||
gdouble pressure;
|
||||
gdouble pressure_d;
|
||||
GtkObject *pressure_w;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static gpointer airbrush_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state);
|
||||
static gpointer airbrush_non_gui_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state);
|
||||
|
||||
|
||||
/* the airbrush tool options */
|
||||
static AirbrushOptions *airbrush_options = NULL;
|
||||
|
||||
/* local variables */
|
||||
static gint timer; /* timer for successive paint applications */
|
||||
static gint timer_state = OFF; /* state of airbrush tool */
|
||||
static AirbrushTimeout airbrush_timeout;
|
||||
|
||||
static gdouble non_gui_pressure;
|
||||
static gboolean non_gui_incremental;
|
||||
|
||||
/* forward function declarations */
|
||||
static void airbrush_motion (PaintCore *, GimpDrawable *,
|
||||
PaintPressureOptions *,
|
||||
gdouble, PaintApplicationMode);
|
||||
static gint airbrush_time_out (gpointer);
|
||||
|
||||
|
||||
/* functions */
|
||||
|
||||
static void
|
||||
airbrush_options_reset (void)
|
||||
{
|
||||
AirbrushOptions *options = airbrush_options;
|
||||
|
||||
paint_options_reset ((PaintOptions *) options);
|
||||
|
||||
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->rate_w),
|
||||
options->rate_d);
|
||||
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->pressure_w),
|
||||
options->pressure_d);
|
||||
}
|
||||
|
||||
static AirbrushOptions *
|
||||
airbrush_options_new (void)
|
||||
{
|
||||
AirbrushOptions *options;
|
||||
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *table;
|
||||
GtkWidget *scale;
|
||||
|
||||
/* the new airbrush tool options structure */
|
||||
options = g_new (AirbrushOptions, 1);
|
||||
paint_options_init ((PaintOptions *) options,
|
||||
AIRBRUSH,
|
||||
airbrush_options_reset);
|
||||
options->rate = options->rate_d = 80.0;
|
||||
options->pressure = options->pressure_d = AIRBRUSH_PRESSURE_DEFAULT;
|
||||
|
||||
/* the main vbox */
|
||||
vbox = ((ToolOptions *) options)->main_vbox;
|
||||
|
||||
/* the rate scale */
|
||||
table = gtk_table_new (2, 2, FALSE);
|
||||
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), 1);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
||||
|
||||
options->rate_w =
|
||||
gtk_adjustment_new (options->rate_d, 0.0, 150.0, 1.0, 1.0, 0.0);
|
||||
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->rate_w));
|
||||
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
|
||||
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
||||
gtk_signal_connect (GTK_OBJECT (options->rate_w), "value_changed",
|
||||
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
|
||||
&options->rate);
|
||||
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
|
||||
_("Rate:"), 1.0, 1.0,
|
||||
scale, 1, FALSE);
|
||||
|
||||
/* the pressure scale */
|
||||
options->pressure_w =
|
||||
gtk_adjustment_new (options->pressure_d, 0.0, 100.0, 1.0, 1.0, 0.0);
|
||||
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->pressure_w));
|
||||
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
|
||||
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
||||
gtk_signal_connect (GTK_OBJECT (options->pressure_w), "value_changed",
|
||||
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
|
||||
&options->pressure);
|
||||
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
|
||||
_("Pressure:"), 1.0, 1.0,
|
||||
scale, 1, FALSE);
|
||||
|
||||
gtk_widget_show (table);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
Tool *
|
||||
tools_new_airbrush (void)
|
||||
{
|
||||
Tool * tool;
|
||||
PaintCore * private;
|
||||
|
||||
/* The tool options */
|
||||
if (! airbrush_options)
|
||||
{
|
||||
airbrush_options = airbrush_options_new ();
|
||||
tools_register (AIRBRUSH, (ToolOptions *) airbrush_options);
|
||||
}
|
||||
|
||||
tool = paint_core_new (AIRBRUSH);
|
||||
|
||||
private = (PaintCore *) tool->private;
|
||||
private->paint_func = airbrush_paint_func;
|
||||
private->pick_colors = TRUE;
|
||||
private->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
airbrush_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state)
|
||||
{
|
||||
GimpBrush *brush;
|
||||
gdouble rate;
|
||||
|
||||
if (!drawable)
|
||||
return NULL;
|
||||
|
||||
brush = gimp_context_get_brush (NULL);
|
||||
switch (state)
|
||||
{
|
||||
case INIT_PAINT :
|
||||
/* timer_state = OFF; */
|
||||
if (timer_state == ON)
|
||||
{
|
||||
g_warning ("killing stray timer, please report to lewing@gimp.org");
|
||||
gtk_timeout_remove (timer);
|
||||
}
|
||||
timer_state = OFF;
|
||||
break;
|
||||
|
||||
case MOTION_PAINT :
|
||||
if (timer_state == ON)
|
||||
gtk_timeout_remove (timer);
|
||||
timer_state = OFF;
|
||||
|
||||
airbrush_motion (paint_core, drawable,
|
||||
airbrush_options->paint_options.pressure_options,
|
||||
airbrush_options->pressure,
|
||||
airbrush_options->paint_options.incremental ?
|
||||
INCREMENTAL : CONSTANT);
|
||||
|
||||
if (airbrush_options->rate != 0.0)
|
||||
{
|
||||
airbrush_timeout.paint_core = paint_core;
|
||||
airbrush_timeout.drawable = drawable;
|
||||
rate = airbrush_options->paint_options.pressure_options->rate ?
|
||||
(10000 / (airbrush_options->rate * 2.0 * paint_core->curpressure)) :
|
||||
(10000 / airbrush_options->rate);
|
||||
timer = gtk_timeout_add (rate, airbrush_time_out, NULL);
|
||||
timer_state = ON;
|
||||
}
|
||||
break;
|
||||
|
||||
case FINISH_PAINT :
|
||||
if (timer_state == ON)
|
||||
gtk_timeout_remove (timer);
|
||||
timer_state = OFF;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tools_free_airbrush (Tool *tool)
|
||||
{
|
||||
if (timer_state == ON)
|
||||
gtk_timeout_remove (timer);
|
||||
timer_state = OFF;
|
||||
|
||||
paint_core_free (tool);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
airbrush_time_out (gpointer client_data)
|
||||
{
|
||||
/* service the timer */
|
||||
airbrush_motion (airbrush_timeout.paint_core,
|
||||
airbrush_timeout.drawable,
|
||||
airbrush_options->paint_options.pressure_options,
|
||||
airbrush_options->pressure,
|
||||
airbrush_options->paint_options.incremental ?
|
||||
INCREMENTAL : CONSTANT);
|
||||
gdisplays_flush ();
|
||||
|
||||
/* restart the timer */
|
||||
if (airbrush_options->rate != 0.0)
|
||||
{
|
||||
if (airbrush_options->paint_options.pressure_options->rate)
|
||||
{
|
||||
/* set a new timer */
|
||||
timer = gtk_timeout_add ((10000 / (airbrush_options->rate * 2.0 * airbrush_timeout.paint_core->curpressure)),
|
||||
airbrush_time_out, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
airbrush_motion (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintPressureOptions *pressure_options,
|
||||
double pressure,
|
||||
PaintApplicationMode mode)
|
||||
{
|
||||
GImage *gimage;
|
||||
TempBuf *area;
|
||||
guchar col[MAX_CHANNELS];
|
||||
gdouble scale;
|
||||
|
||||
if (!drawable)
|
||||
return;
|
||||
|
||||
if (! (gimage = gimp_drawable_gimage (drawable)))
|
||||
return;
|
||||
|
||||
if (pressure_options->size)
|
||||
scale = paint_core->curpressure;
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
if (! (area = paint_core_get_paint_area (paint_core, drawable, scale)))
|
||||
return;
|
||||
|
||||
/* color the pixels */
|
||||
if (pressure_options->color)
|
||||
{
|
||||
GimpRGB color;
|
||||
|
||||
gradient_get_color_at (gimp_context_get_gradient (NULL),
|
||||
paint_core->curpressure, &color);
|
||||
|
||||
gimp_rgba_get_uchar (&color,
|
||||
&col[RED_PIX],
|
||||
&col[GREEN_PIX],
|
||||
&col[BLUE_PIX],
|
||||
&col[ALPHA_PIX]);
|
||||
|
||||
mode = INCREMENTAL;
|
||||
color_pixels (temp_buf_data (area), col,
|
||||
area->width * area->height, area->bytes);
|
||||
}
|
||||
else if (paint_core->brush && paint_core->brush->pixmap)
|
||||
{
|
||||
mode = INCREMENTAL;
|
||||
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,
|
||||
scale, SOFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_image_get_foreground (gimage, drawable, col);
|
||||
col[area->bytes - 1] = OPAQUE_OPACITY;
|
||||
color_pixels (temp_buf_data (area), col,
|
||||
area->width * area->height, area->bytes);
|
||||
}
|
||||
|
||||
if (pressure_options->pressure)
|
||||
pressure = pressure * 2.0 * paint_core->curpressure;
|
||||
|
||||
/* paste the newly painted area to the image */
|
||||
paint_core_paste_canvas (paint_core, drawable,
|
||||
MIN (pressure, 255),
|
||||
(gint) (gimp_context_get_opacity (NULL) * 255),
|
||||
gimp_context_get_paint_mode (NULL),
|
||||
SOFT, scale, mode);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
airbrush_non_gui_paint_func (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
PaintState state)
|
||||
{
|
||||
airbrush_motion (paint_core, drawable, &non_gui_pressure_options,
|
||||
non_gui_pressure, non_gui_incremental);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
airbrush_non_gui_default (GimpDrawable *drawable,
|
||||
gint num_strokes,
|
||||
gdouble *stroke_array)
|
||||
{
|
||||
AirbrushOptions *options = airbrush_options;
|
||||
gdouble pressure = AIRBRUSH_PRESSURE_DEFAULT;
|
||||
|
||||
if(options)
|
||||
pressure = options->pressure;
|
||||
|
||||
return airbrush_non_gui (drawable, pressure, num_strokes, stroke_array);
|
||||
}
|
||||
|
||||
gboolean
|
||||
airbrush_non_gui (GimpDrawable *drawable,
|
||||
gdouble pressure,
|
||||
gint num_strokes,
|
||||
gdouble *stroke_array)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (paint_core_init (&non_gui_paint_core, drawable,
|
||||
stroke_array[0], stroke_array[1]))
|
||||
{
|
||||
/* Set the paint core's paint func */
|
||||
non_gui_paint_core.paint_func = airbrush_non_gui_paint_func;
|
||||
|
||||
non_gui_pressure = pressure;
|
||||
|
||||
non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
|
||||
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
|
||||
|
||||
airbrush_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
|
||||
|
||||
for (i = 1; i < num_strokes; i++)
|
||||
{
|
||||
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
|
||||
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
|
||||
|
||||
paint_core_interpolate (&non_gui_paint_core, drawable);
|
||||
|
||||
non_gui_paint_core.lastx = non_gui_paint_core.curx;
|
||||
non_gui_paint_core.lasty = non_gui_paint_core.cury;
|
||||
}
|
||||
|
||||
/* Finish the painting */
|
||||
paint_core_finish (&non_gui_paint_core, drawable, -1);
|
||||
|
||||
/* Cleanup */
|
||||
paint_core_cleanup ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
@@ -189,6 +189,7 @@ app_run (const gchar *full_prog_name,
|
||||
"Gimp-GUI",
|
||||
"Gimp-Menus",
|
||||
"Gimp-PDB",
|
||||
"Gimp-Paint",
|
||||
"Gimp-Paint-Funcs",
|
||||
"Gimp-Plug-In",
|
||||
"Gimp-Text",
|
||||
|
@@ -1,626 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 1999-2002 Adam D. Moss (the "Author"). All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is fur-
|
||||
nished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
|
||||
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
|
||||
NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the Author of the
|
||||
Software shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written authorization
|
||||
from the Author.
|
||||
*/
|
||||
|
||||
/*
|
||||
cpercep.c: The CPercep Functions v0.9: 2002-02-10
|
||||
Adam D. Moss: adam@gimp.org <http://www.foxbox.org/adam/code/cpercep/>
|
||||
|
||||
This code module concerns itself with conversion from a hard-coded
|
||||
RGB colour space (sRGB by default) to CIE L*a*b* and back again with
|
||||
(primarily) precision and (secondarily) speed, oriented largely
|
||||
towards the purposes of quantifying the PERCEPTUAL difference between
|
||||
two arbitrary RGB colours with a minimum of fuss.
|
||||
|
||||
Motivation One: The author is disheartened at the amount of graphics
|
||||
processing software around which uses weighted or non-weighted
|
||||
Euclidean distance between co-ordinates within a (poorly-defined) RGB
|
||||
space as the basis of what should really be an estimate of perceptual
|
||||
difference to the human eye. Certainly it's fast to do it that way,
|
||||
but please think carefully about whether your particular application
|
||||
should be tolerating sloppy results for the sake of real-time response.
|
||||
|
||||
Motivation Two: Lack of tested, re-usable and free code available
|
||||
for this purpose. The difficulty in finding something similar to
|
||||
CPercep with a free license motivated this project; I hope that this
|
||||
code also serves to illustrate how to perform the
|
||||
R'G'B'->XYZ->L*a*b*->XYZ->R'G'B' transformation correctly since I
|
||||
was distressed to note how many of the equations and code snippets
|
||||
on the net were omitting the reverse transform and/or were using
|
||||
incorrectly-derived or just plain wrong constants.
|
||||
|
||||
TODO: document functions, rename erroneously-named arguments
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef __GLIBC__
|
||||
/* cbrt() is a GNU extension */
|
||||
#define cbrt(x) (pow(x, 1.0/3.0))
|
||||
#endif
|
||||
|
||||
#ifdef GIMP_COMPILATION
|
||||
#include <glib.h> /* to get working 'inline' */
|
||||
#endif
|
||||
|
||||
/* defines:
|
||||
|
||||
SANITY: emits warnings when passed non-sane colours (and usually
|
||||
corrects them) -- useful when debugging.
|
||||
|
||||
APPROX: speeds up the conversion from RGB to the colourspace by
|
||||
assuming that the RGB values passed in are integral and definitely
|
||||
in the range 0->255
|
||||
|
||||
SRGB: assumes that the RGB values being passed in (and out) are
|
||||
destined for an sRGB-alike display device (a typical modern monitor)
|
||||
-- if you change this then you'll probably want to change ASSUMED_GAMMA,
|
||||
the phosphor colours and the white point definition.
|
||||
*/
|
||||
|
||||
/* #define SANITY */
|
||||
#define APPROX
|
||||
#define SRGB
|
||||
|
||||
|
||||
#include "cpercep.h"
|
||||
|
||||
|
||||
#ifdef SRGB
|
||||
#define ASSUMED_GAMMA (2.2F)
|
||||
#else
|
||||
/*#define ASSUMED_GAMMA (2.591F)*/
|
||||
#define ASSUMED_GAMMA (2.2F)
|
||||
#endif
|
||||
#define REV_GAMMA ((1.0F / ASSUMED_GAMMA))
|
||||
|
||||
|
||||
/* define characteristics of the source RGB space (and the space
|
||||
within which we try to behave linearly). */
|
||||
|
||||
/* Phosphor colours: */
|
||||
|
||||
/* sRGB/HDTV phosphor colours */
|
||||
static const double pxr = 0.64F;
|
||||
static const double pyr = 0.33F;
|
||||
static const double pxg = 0.30F;
|
||||
static const double pyg = 0.60F;
|
||||
static const double pxb = 0.15F;
|
||||
static const double pyb = 0.06F;
|
||||
|
||||
/* White point: */
|
||||
|
||||
/* D65 (6500K) (recommended but not a common display default) */
|
||||
static const double lxn = 0.312713F;
|
||||
static const double lyn = 0.329016F;
|
||||
|
||||
/* D50 (5000K) */
|
||||
/*static const double lxn = 0.3457F; */
|
||||
/*static const double lyn = 0.3585F; */
|
||||
|
||||
/* D55 (5500K) */
|
||||
/*static const double lxn = 0.3324F; */
|
||||
/*static const double lyn = 0.3474F; */
|
||||
|
||||
/* D93 (9300K) (a common monitor default, but poor colour reproduction) */
|
||||
/* static const double lxn = 0.2848F; */
|
||||
/* static const double lyn = 0.2932F; */
|
||||
|
||||
/* illum E (normalized) */
|
||||
/*static const double lxn = 1.0/3.0F; */
|
||||
/*static const double lyn = 1.0/3.0F; */
|
||||
|
||||
/* illum C (average sunlight) */
|
||||
/*static const double lxn = 0.3101F; */
|
||||
/*static const double lyn = 0.3162F; */
|
||||
|
||||
/* illum B (direct sunlight) */
|
||||
/*static const double lxn = 0.3484F; */
|
||||
/*static const double lyn = 0.3516F; */
|
||||
|
||||
/* illum A (tungsten lamp) */
|
||||
/*static const double lxn = 0.4476F; */
|
||||
/*static const double lyn = 0.4074F; */
|
||||
|
||||
|
||||
static const double LRAMP = 7.99959199F;
|
||||
|
||||
|
||||
static double xnn, znn;
|
||||
|
||||
static double powtable[256];
|
||||
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(x,l,u) ((x)<(l)?(l):((x)>(u)?(u):(x)))
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
init_powtable(const double gamma)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifndef SRGB
|
||||
/* pure gamma function */
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
powtable[i] = pow((i)/255.0F, gamma);
|
||||
}
|
||||
#else
|
||||
/* sRGB gamma curve */
|
||||
for (i=0; i<11 /* 0.03928 * 255 */; i++)
|
||||
{
|
||||
powtable[i] = (i) / (255.0F * 12.92F);
|
||||
}
|
||||
for (; i<256; i++)
|
||||
{
|
||||
powtable[i] = pow( (((i) / 255.0F) + 0.055F) / 1.055F, 2.4F);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
typedef double CMatrix[3][3];
|
||||
typedef double CVector[3];
|
||||
|
||||
static CMatrix Mrgb_to_xyz, Mxyz_to_rgb;
|
||||
|
||||
static int
|
||||
Minvert (CMatrix src, CMatrix dest)
|
||||
{
|
||||
double det;
|
||||
|
||||
dest[0][0] = src[1][1] * src[2][2] - src[1][2] * src[2][1];
|
||||
dest[0][1] = src[0][2] * src[2][1] - src[0][1] * src[2][2];
|
||||
dest[0][2] = src[0][1] * src[1][2] - src[0][2] * src[1][1];
|
||||
dest[1][0] = src[1][2] * src[2][0] - src[1][0] * src[2][2];
|
||||
dest[1][1] = src[0][0] * src[2][2] - src[0][2] * src[2][0];
|
||||
dest[1][2] = src[0][2] * src[1][0] - src[0][0] * src[1][2];
|
||||
dest[2][0] = src[1][0] * src[2][1] - src[1][1] * src[2][0];
|
||||
dest[2][1] = src[0][1] * src[2][0] - src[0][0] * src[2][1];
|
||||
dest[2][2] = src[0][0] * src[1][1] - src[0][1] * src[1][0];
|
||||
|
||||
det =
|
||||
src[0][0] * dest[0][0] +
|
||||
src[0][1] * dest[1][0] +
|
||||
src[0][2] * dest[2][0];
|
||||
|
||||
if (det <= 0.0F)
|
||||
{
|
||||
#ifdef SANITY
|
||||
g_printerr ("\n\007 XXXX det: %f\n", det);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
dest[0][0] /= det;
|
||||
dest[0][1] /= det;
|
||||
dest[0][2] /= det;
|
||||
dest[1][0] /= det;
|
||||
dest[1][1] /= det;
|
||||
dest[1][2] /= det;
|
||||
dest[2][0] /= det;
|
||||
dest[2][1] /= det;
|
||||
dest[2][2] /= det;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rgbxyzrgb_init(void)
|
||||
{
|
||||
init_powtable (ASSUMED_GAMMA);
|
||||
|
||||
xnn = lxn / lyn;
|
||||
/* ynn taken as 1.0 */
|
||||
znn = (1.0F - (lxn + lyn)) / lyn;
|
||||
|
||||
{
|
||||
CMatrix MRC, MRCi;
|
||||
double C1,C2,C3;
|
||||
|
||||
MRC[0][0] = pxr;
|
||||
MRC[0][1] = pxg;
|
||||
MRC[0][2] = pxb;
|
||||
MRC[1][0] = pyr;
|
||||
MRC[1][1] = pyg;
|
||||
MRC[1][2] = pyb;
|
||||
MRC[2][0] = 1.0F - (pxr + pyr);
|
||||
MRC[2][1] = 1.0F - (pxg + pyg);
|
||||
MRC[2][2] = 1.0F - (pxb + pyb);
|
||||
|
||||
Minvert (MRC, MRCi);
|
||||
|
||||
C1 = MRCi[0][0]*xnn + MRCi[0][1] + MRCi[0][2]*znn;
|
||||
C2 = MRCi[1][0]*xnn + MRCi[1][1] + MRCi[1][2]*znn;
|
||||
C3 = MRCi[2][0]*xnn + MRCi[2][1] + MRCi[2][2]*znn;
|
||||
|
||||
Mrgb_to_xyz[0][0] = MRC[0][0] * C1;
|
||||
Mrgb_to_xyz[0][1] = MRC[0][1] * C2;
|
||||
Mrgb_to_xyz[0][2] = MRC[0][2] * C3;
|
||||
Mrgb_to_xyz[1][0] = MRC[1][0] * C1;
|
||||
Mrgb_to_xyz[1][1] = MRC[1][1] * C2;
|
||||
Mrgb_to_xyz[1][2] = MRC[1][2] * C3;
|
||||
Mrgb_to_xyz[2][0] = MRC[2][0] * C1;
|
||||
Mrgb_to_xyz[2][1] = MRC[2][1] * C2;
|
||||
Mrgb_to_xyz[2][2] = MRC[2][2] * C3;
|
||||
|
||||
Minvert (Mrgb_to_xyz, Mxyz_to_rgb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xyz_to_rgb (double *inx_outr,
|
||||
double *iny_outg,
|
||||
double *inz_outb)
|
||||
{
|
||||
const double x = *inx_outr;
|
||||
const double y = *iny_outg;
|
||||
const double z = *inz_outb;
|
||||
|
||||
*inx_outr = Mxyz_to_rgb[0][0]*x + Mxyz_to_rgb[0][1]*y + Mxyz_to_rgb[0][2]*z;
|
||||
*iny_outg = Mxyz_to_rgb[1][0]*x + Mxyz_to_rgb[1][1]*y + Mxyz_to_rgb[1][2]*z;
|
||||
*inz_outb = Mxyz_to_rgb[2][0]*x + Mxyz_to_rgb[2][1]*y + Mxyz_to_rgb[2][2]*z;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rgb_to_xyz (double *inr_outx,
|
||||
double *ing_outy,
|
||||
double *inb_outz)
|
||||
{
|
||||
const double r = *inr_outx;
|
||||
const double g = *ing_outy;
|
||||
const double b = *inb_outz;
|
||||
|
||||
*inr_outx = Mrgb_to_xyz[0][0]*r + Mrgb_to_xyz[0][1]*g + Mrgb_to_xyz[0][2]*b;
|
||||
*ing_outy = Mrgb_to_xyz[1][0]*r + Mrgb_to_xyz[1][1]*g + Mrgb_to_xyz[1][2]*b;
|
||||
*inb_outz = Mrgb_to_xyz[2][0]*r + Mrgb_to_xyz[2][1]*g + Mrgb_to_xyz[2][2]*b;
|
||||
}
|
||||
|
||||
|
||||
/* call this before using the CPercep function */
|
||||
void
|
||||
cpercep_init_conversions(void)
|
||||
{
|
||||
rgbxyzrgb_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline double
|
||||
ffunc(const double t)
|
||||
{
|
||||
if (t > 0.008856F)
|
||||
{
|
||||
return (cbrt(t));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (7.787F * t + 16.0F/116.0F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline double
|
||||
ffunc_inv(const double t)
|
||||
{
|
||||
if (t > 0.206893F)
|
||||
{
|
||||
return (t * t * t);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((t - 16.0F/116.0F) / 7.787F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xyz_to_lab (double *inx,
|
||||
double *iny,
|
||||
double *inz)
|
||||
{
|
||||
double L,a,b;
|
||||
double ffuncY;
|
||||
const double X = *inx;
|
||||
const double Y = *iny;
|
||||
const double Z = *inz;
|
||||
|
||||
if (Y > 0.0F)
|
||||
{
|
||||
if (Y > 0.008856F)
|
||||
{
|
||||
L = (116.0F * cbrt(Y)) - 16.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
L = (Y * 903.3F);
|
||||
}
|
||||
|
||||
#ifdef SANITY
|
||||
if (L < 0.0F)
|
||||
{
|
||||
g_printerr (" <eek1>%f \007",(float)L);
|
||||
}
|
||||
|
||||
if (L > 100.0F)
|
||||
{
|
||||
g_printerr (" <eek2>%f \007",(float)L);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
L = 0.0;
|
||||
}
|
||||
|
||||
ffuncY = ffunc(Y);
|
||||
a = 500.0F * (ffunc(X/xnn) - ffuncY);
|
||||
b = 200.0F * (ffuncY - ffunc(Z/znn));
|
||||
|
||||
*inx = L;
|
||||
*iny = a;
|
||||
*inz = b;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lab_to_xyz (double *inl,
|
||||
double *ina,
|
||||
double *inb)
|
||||
{
|
||||
double X,Y,Z;
|
||||
double P;
|
||||
const double L = *inl;
|
||||
const double a = *ina;
|
||||
const double b = *inb;
|
||||
|
||||
if (L > LRAMP)
|
||||
{
|
||||
P = Y = (L + 16.0F) / 116.0F;
|
||||
Y = Y * Y * Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
Y = L / 903.3F;
|
||||
P = 7.787F * Y + 16.0F/116.0F;
|
||||
}
|
||||
|
||||
X = (P + a / 500.0F);
|
||||
X = xnn * ffunc_inv(X);
|
||||
Z = (P - b / 200.0F);
|
||||
Z = znn * ffunc_inv(Z);
|
||||
|
||||
#ifdef SANITY
|
||||
if (X<-0.00000F)
|
||||
{
|
||||
if (X<-0.0001F)
|
||||
g_printerr ("{badX %f {%f,%f,%f}}",X,L,a,b);
|
||||
X = 0.0F;
|
||||
}
|
||||
if (Y<-0.00000F)
|
||||
{
|
||||
if (Y<-0.0001F)
|
||||
g_printerr ("{badY %f}",Y);
|
||||
Y = 0.0F;
|
||||
}
|
||||
if (Z<-0.00000F)
|
||||
{
|
||||
if (Z<-0.1F)
|
||||
g_printerr ("{badZ %f}",Z);
|
||||
Z = 0.0F;
|
||||
}
|
||||
#endif
|
||||
|
||||
*inl = X;
|
||||
*ina = Y;
|
||||
*inb = Z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
cpercep_rgb_to_space (double inr, double ing, double inb,
|
||||
double* outr, double* outg, double* outb)
|
||||
{
|
||||
#ifdef APPROX
|
||||
#ifdef SANITY
|
||||
/* ADM extra sanity */
|
||||
if ((inr) > 255.0F ||
|
||||
(ing) > 255.0F ||
|
||||
(inb) > 255.0F ||
|
||||
(inr) < -0.0F ||
|
||||
(ing) < -0.0F ||
|
||||
(inb) < -0.0F
|
||||
)
|
||||
abort();
|
||||
#endif /* SANITY */
|
||||
inr = powtable[(int)inr];
|
||||
ing = powtable[(int)ing];
|
||||
inb = powtable[(int)inb];
|
||||
#else
|
||||
#ifdef SRGB
|
||||
/* sRGB gamma curve */
|
||||
if (inr <= (0.03928F * 255.0F))
|
||||
inr = inr / (255.0F * 12.92F);
|
||||
else
|
||||
inr = pow( (inr + (0.055F * 255.0F)) / (1.055F * 255.0F), 2.4F);
|
||||
|
||||
if (ing <= (0.03928F * 255.0F))
|
||||
ing = ing / (255.0F * 12.92F);
|
||||
else
|
||||
ing = pow( (ing + (0.055F * 255.0F)) / (1.055F * 255.0F), 2.4F);
|
||||
|
||||
if (inb <= (0.03928F * 255.0F))
|
||||
inb = inb / (255.0F * 12.92F);
|
||||
else
|
||||
inb = pow( (inb + (0.055F * 255.0F)) / (1.055F * 255.0F), 2.4F);
|
||||
#else
|
||||
/* pure gamma function */
|
||||
inr = pow((inr)/255.0F, ASSUMED_GAMMA);
|
||||
ing = pow((ing)/255.0F, ASSUMED_GAMMA);
|
||||
inb = pow((inb)/255.0F, ASSUMED_GAMMA);
|
||||
#endif /* SRGB */
|
||||
#endif /* APPROX */
|
||||
|
||||
#ifdef SANITY
|
||||
/* ADM extra sanity */
|
||||
if ((inr) > 1.0F ||
|
||||
(ing) > 1.0F ||
|
||||
(inb) > 1.0F ||
|
||||
(inr) < 0.0F ||
|
||||
(ing) < 0.0F ||
|
||||
(inb) < 0.0F
|
||||
)
|
||||
{
|
||||
g_printerr ("%%");
|
||||
/* abort(); */
|
||||
}
|
||||
#endif /* SANITY */
|
||||
|
||||
rgb_to_xyz(&inr, &ing, &inb);
|
||||
|
||||
#ifdef SANITY
|
||||
if (inr < 0.0F || ing < 0.0F || inb < 0.0F)
|
||||
{
|
||||
g_printerr (" [BAD2 XYZ: %f,%f,%f]\007 ",
|
||||
inr,ing,inb);
|
||||
}
|
||||
#endif /* SANITY */
|
||||
|
||||
xyz_to_lab(&inr, &ing, &inb);
|
||||
|
||||
*outr = inr;
|
||||
*outg = ing;
|
||||
*outb = inb;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cpercep_space_to_rgb (double inr, double ing, double inb,
|
||||
double* outr, double* outg, double* outb)
|
||||
{
|
||||
lab_to_xyz(&inr, &ing, &inb);
|
||||
|
||||
#ifdef SANITY
|
||||
if (inr<-0.0F || ing<-0.0F || inb<-0.0F)
|
||||
{
|
||||
g_printerr (" [BAD1 XYZ: %f,%f,%f]\007 ",
|
||||
inr,ing,inb);
|
||||
}
|
||||
#endif
|
||||
|
||||
xyz_to_rgb(&inr, &ing, &inb);
|
||||
|
||||
/* yes, essential. :( */
|
||||
inr = CLAMP(inr,0.0F,1.0F);
|
||||
ing = CLAMP(ing,0.0F,1.0F);
|
||||
inb = CLAMP(inb,0.0F,1.0F);
|
||||
|
||||
#ifdef SRGB
|
||||
if (inr <= 0.0030402477F)
|
||||
inr = inr * (12.92F * 255.0F);
|
||||
else
|
||||
inr = pow(inr, 1.0F/2.4F) * (1.055F * 255.0F) - (0.055F * 255.0F);
|
||||
|
||||
if (ing <= 0.0030402477F)
|
||||
ing = ing * (12.92F * 255.0F);
|
||||
else
|
||||
ing = pow(ing, 1.0F/2.4F) * (1.055F * 255.0F) - (0.055F * 255.0F);
|
||||
|
||||
if (inb <= 0.0030402477F)
|
||||
inb = inb * (12.92F * 255.0F);
|
||||
else
|
||||
inb = pow(inb, 1.0F/2.4F) * (1.055F * 255.0F) - (0.055F * 255.0F);
|
||||
#else
|
||||
inr = 255.0F * pow(inr, REV_GAMMA);
|
||||
ing = 255.0F * pow(ing, REV_GAMMA);
|
||||
inb = 255.0F * pow(inb, REV_GAMMA);
|
||||
#endif
|
||||
|
||||
*outr = inr;
|
||||
*outg = ing;
|
||||
*outb = inb;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* EXPERIMENTAL SECTION */
|
||||
|
||||
const double
|
||||
xscaler(const double start, const double end,
|
||||
const double me, const double him)
|
||||
{
|
||||
return start + ((end-start) * him) / (me + him);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mix_colours (const double L1, const double a1, const double b1,
|
||||
const double L2, const double a2, const double b2,
|
||||
double *rtnL, double *rtna, double *rtnb,
|
||||
double mass1, double mass2)
|
||||
{
|
||||
double w1, w2;
|
||||
|
||||
#if 0
|
||||
*rtnL = xscaler (L1, L2, mass1, mass2);
|
||||
*rtna = xscaler (a1, a2, mass1, mass2);
|
||||
*rtnb = xscaler (b1, b2, mass1, mass2);
|
||||
#else
|
||||
|
||||
#if 1
|
||||
w1 = mass1 * L1;
|
||||
w2 = mass2 * L2;
|
||||
#else
|
||||
w1 = mass1 * (L1*L1*L1);
|
||||
w2 = mass2 * (L2*L2*L2);
|
||||
#endif
|
||||
|
||||
*rtnL = xscaler (L1, L2, mass1, mass2);
|
||||
|
||||
if (w1 <= 0.0 &&
|
||||
w2 <= 0.0)
|
||||
{
|
||||
*rtna =
|
||||
*rtnb = 0.0;
|
||||
#ifdef SANITY
|
||||
/* g_printerr ("\007OUCH. "); */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
*rtna = xscaler(a1, a2, w1, w2);
|
||||
*rtnb = xscaler(b1, b2, w1, w2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* EXPERIMENTAL SECTION */
|
@@ -1,76 +0,0 @@
|
||||
#ifndef __CPERCEP_H__
|
||||
#define __CPERCEP_H__
|
||||
/*
|
||||
Copyright (C) 1997-2002 Adam D. Moss (the "Author"). All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is fur-
|
||||
nished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
|
||||
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
|
||||
NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the Author of the
|
||||
Software shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written authorization
|
||||
from the Author.
|
||||
*/
|
||||
|
||||
/*
|
||||
cpercep.c: The CPercep Functions v0.9: 2002-02-10
|
||||
Adam D. Moss: adam@gimp.org <http://www.foxbox.org/adam/code/cpercep/>
|
||||
|
||||
TODO: document functions, rename erroneously-named arguments
|
||||
*/
|
||||
|
||||
void
|
||||
cpercep_init_conversions(void);
|
||||
|
||||
void
|
||||
cpercep_rgb_to_space (double inr, double ing, double inb,
|
||||
double* outr, double* outg, double* outb);
|
||||
|
||||
void
|
||||
cpercep_space_to_rgb (double inr, double ing, double inb,
|
||||
double* outr, double* outg, double* outb);
|
||||
|
||||
#if 0
|
||||
/* This is in the header so that it can potentially be inlined. */
|
||||
static const double
|
||||
cpercep_distance_space (const double L1, const double a1, const double b1,
|
||||
const double L2, const double a2, const double b2)
|
||||
{
|
||||
const double Ld = L1 - L2;
|
||||
const double ad = a1 - a2;
|
||||
const double bd = b1 - b2;
|
||||
return (Ld*Ld + ad*ad + bd*bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* EXPERIMENTAL */
|
||||
#if 0
|
||||
void
|
||||
mix_colours (const double L1, const double a1, const double b1,
|
||||
const double L2, const double a2, const double b2,
|
||||
double *rtnL, double *rtna, double *rtnb,
|
||||
double mass1, double mass2);
|
||||
/* util function */
|
||||
const double
|
||||
xscaler(const double start, const double end,
|
||||
const double me, const double him);
|
||||
#define MF(L) ((L)<=0.0 ? 0.0 : 1.0)
|
||||
#endif /* EXPERIMENTAL */
|
||||
|
||||
|
||||
#endif /* __CPERCEP_H__ */
|
@@ -74,7 +74,7 @@ enum
|
||||
ARCH_X86_CYRIX_FEATURE_MMXEXT = 1 << 24
|
||||
};
|
||||
|
||||
#if !defined(ARCH_X86_64) && defined(PIC)
|
||||
#if !defined(ARCH_X86_64) && (defined(PIC) || defined(__PIC__))
|
||||
#define cpuid(op,eax,ebx,ecx,edx) \
|
||||
__asm__ ("movl %%ebx, %%esi\n\t" \
|
||||
"cpuid\n\t" \
|
||||
|
@@ -24,6 +24,8 @@
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base-types.h"
|
||||
|
@@ -7,40 +7,61 @@ AM_CPPFLAGS = \
|
||||
@GIMP_THREAD_FLAGS@ \
|
||||
@GIMP_MP_FLAGS@
|
||||
|
||||
AM_CCASFLAGS = \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/app
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/app \
|
||||
$(GLIB_CFLAGS) \
|
||||
-I$(includedir)
|
||||
|
||||
noinst_LIBRARIES = libappcomposite.a
|
||||
composite_libraries = \
|
||||
libcomposite3dnow.a \
|
||||
libcompositealtivec.a \
|
||||
libcompositemmx.a \
|
||||
libcompositesse.a \
|
||||
libcompositesse2.a \
|
||||
libcompositevis.a
|
||||
|
||||
libappcomposite_a_sources = \
|
||||
noinst_LIBRARIES = $(composite_libraries) libcomposite.a
|
||||
|
||||
libcomposite3dnow_a_SOURCES = \
|
||||
gimp-composite-3dnow.c \
|
||||
gimp-composite-3dnow.h \
|
||||
gimp-composite-3dnow.h
|
||||
|
||||
libcompositealtivec_a_SOURCES = \
|
||||
gimp-composite-altivec.c \
|
||||
gimp-composite-altivec.h \
|
||||
gimp-composite-altivec.h
|
||||
|
||||
libcompositemmx_a_CFLAGS = $(MMX_EXTRA_CFLAGS)
|
||||
|
||||
libcompositemmx_a_SOURCES = \
|
||||
gimp-composite-mmx.c \
|
||||
gimp-composite-mmx.h
|
||||
|
||||
libcompositesse_a_CFLAGS = $(SSE_EXTRA_CFLAGS)
|
||||
|
||||
libcompositesse_a_SOURCES = \
|
||||
gimp-composite-sse.c \
|
||||
gimp-composite-sse.h
|
||||
|
||||
libcompositesse2_a_CFLAGS = $(SSE_EXTRA_CFLAGS)
|
||||
|
||||
libcompositesse2_a_SOURCES = \
|
||||
gimp-composite-sse2.c \
|
||||
gimp-composite-sse2.h
|
||||
|
||||
libcompositevis_a_SOURCES = \
|
||||
gimp-composite-vis.c \
|
||||
gimp-composite-vis.h
|
||||
|
||||
libcomposite_a_sources = \
|
||||
gimp-composite-generic.c \
|
||||
gimp-composite-generic.h \
|
||||
gimp-composite-mmx.c \
|
||||
gimp-composite-mmx.h \
|
||||
gimp-composite-sse.c \
|
||||
gimp-composite-sse.h \
|
||||
gimp-composite-sse2.c \
|
||||
gimp-composite-sse2.h \
|
||||
gimp-composite-util.h \
|
||||
gimp-composite-vis.c \
|
||||
gimp-composite-vis.h \
|
||||
gimp-composite-x86.h \
|
||||
gimp-composite.c \
|
||||
gimp-composite.h
|
||||
|
||||
libappcomposite_a_built_sources = \
|
||||
libcomposite_a_built_sources = \
|
||||
gimp-composite-3dnow-installer.c \
|
||||
gimp-composite-altivec-installer.c \
|
||||
gimp-composite-generic-installer.c \
|
||||
@@ -49,18 +70,34 @@ libappcomposite_a_built_sources = \
|
||||
gimp-composite-sse2-installer.c \
|
||||
gimp-composite-vis-installer.c
|
||||
|
||||
libappcomposite_a_SOURCES = \
|
||||
$(libappcomposite_a_built_sources) \
|
||||
$(libappcomposite_a_sources)
|
||||
libcomposite_a_SOURCES = \
|
||||
$(libcomposite_a_built_sources) \
|
||||
$(libcomposite_a_sources)
|
||||
|
||||
regenerate: gimp-composite-generic.o gimp-composite-mmx.o gimp-composite-sse.o gimp-composite-sse2.o gimp-composite-3dnow.o gimp-composite-altivec.o gimp-composite-vis.o
|
||||
$(srcdir)/make-installer.py -f gimp-composite-generic.o
|
||||
$(srcdir)/make-installer.py -t -r 'defined(COMPILE_MMX_IS_OKAY)' -f gimp-composite-mmx.o
|
||||
$(srcdir)/make-installer.py -t -r 'defined(COMPILE_SSE_IS_OKAY)' -f gimp-composite-sse.o
|
||||
$(srcdir)/make-installer.py -t -r 'defined(COMPILE_SSE2_IS_OKAY)' -f gimp-composite-sse2.o
|
||||
$(srcdir)/make-installer.py -t -r 'defined(COMPILE_3DNOW_IS_OKAY)' -f gimp-composite-3dnow.o
|
||||
$(srcdir)/make-installer.py -t -r 'defined(COMPILE_ALTIVEC_IS_OKAY)' -f gimp-composite-altivec.o
|
||||
$(srcdir)/make-installer.py -t -r 'defined(COMPILE_VIS_IS_OKAY)' -f gimp-composite-vis.o
|
||||
## This is a huge hack
|
||||
libappcomposite.a: $(noinst_LIBRARIES)
|
||||
-rm -f libappcomposite.a
|
||||
$(AR) $(ARFLAGS) libappcomposite.a $(libcomposite_a_OBJECTS) \
|
||||
$(libcomposite3dnow_a_OBJECTS) \
|
||||
$(libcompositealtivec_a_OBJECTS) \
|
||||
$(libcompositemmx_a_OBJECTS) \
|
||||
$(libcompositesse_a_OBJECTS) \
|
||||
$(libcompositesse2_a_OBJECTS) \
|
||||
$(libcompositevis_a_OBJECTS)
|
||||
$(RANLIB) libappcomposite.a
|
||||
|
||||
all-local: libappcomposite.a
|
||||
|
||||
clean_libs = libappcomposite.a
|
||||
|
||||
regenerate: gimp-composite-generic.o $(libcomposite3dnow_a_OBJECTS) $(libcompositealtivec_a_OBJECTS) $(libcompositemmx_a_OBJECTS) $(libcompositesse_a_OBJECTS) $(libcompositesse2_a_OBJECTS) $(libcompositevis_a_OBJECTS)
|
||||
$(srcdir)/make-installer.py -f gimp-composite-generic.o
|
||||
$(srcdir)/make-installer.py -f $(libcompositemmx_a_OBJECTS) -t -r 'defined(COMPILE_MMX_IS_OKAY)' -c 'X86_MMX'
|
||||
$(srcdir)/make-installer.py -f $(libcompositesse_a_OBJECTS) -t -r 'defined(COMPILE_SSE_IS_OKAY)' -c 'X86_SSE' -c 'X86_MMXEXT'
|
||||
$(srcdir)/make-installer.py -f $(libcompositesse2_a_OBJECTS) -t -r 'defined(COMPILE_SSE2_IS_OKAY)' -c 'X86_SSE2'
|
||||
$(srcdir)/make-installer.py -f $(libcomposite3dnow_a_OBJECTS) -t -r 'defined(COMPILE_3DNOW_IS_OKAY)' -c 'X86_3DNOW'
|
||||
$(srcdir)/make-installer.py -f $(libcompositealtivec_a_OBJECTS) -t -r 'defined(COMPILE_ALTIVEC_IS_OKAY)' -c 'PPC_ALTIVEC'
|
||||
$(srcdir)/make-installer.py -f $(libcompositevis_a_OBJECTS) -t -r 'defined(COMPILE_VIS_IS_OKAY)'
|
||||
|
||||
EXTRA_DIST = \
|
||||
make-installer.py \
|
||||
@@ -82,7 +119,7 @@ TESTS = \
|
||||
|
||||
EXTRA_PROGRAMS = gimp-composite-test $(TESTS)
|
||||
|
||||
CLEANFILES = $(EXTRA_PROGRAMS)
|
||||
CLEANFILES = $(EXTRA_PROGRAMS) $(clean_libs)
|
||||
|
||||
gimp_composite_test_SOURCES = \
|
||||
gimp-composite-regression.c \
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
#include "gimp-composite.h"
|
||||
|
||||
#include "gimp-composite-3dnow.h"
|
||||
@@ -17,3 +18,16 @@ gimp_composite_3dnow_install (void)
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_composite_3dnow_init (void)
|
||||
{
|
||||
#if defined(COMPILE_3DNOW_IS_OKAY)
|
||||
if (cpu_accel () & CPU_ACCEL_X86_3DNOW)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -28,7 +28,6 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
|
||||
#include "gimp-composite.h"
|
||||
|
||||
@@ -37,15 +36,3 @@
|
||||
#ifdef COMPILE_3DNOW_IS_OKAY
|
||||
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
gimp_composite_3dnow_init (void)
|
||||
{
|
||||
#ifdef COMPILE_3DNOW_IS_OKAY
|
||||
if (cpu_accel () & CPU_ACCEL_X86_3DNOW)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -13,12 +13,12 @@ extern gboolean gimp_composite_3dnow_install (void);
|
||||
#if defined(USE_MMX)
|
||||
#if defined(ARCH_X86)
|
||||
#if __GNUC__ >= 3
|
||||
#if defined(ARCH_X86_64) || !defined(PIC)
|
||||
#if defined(ARCH_X86_64) || (!defined(PIC) && !defined(__PIC__))
|
||||
#define COMPILE_3DNOW_IS_OKAY (1)
|
||||
#endif /* ARCH_X86_64 || !PIC */
|
||||
#endif /* ARCH_X86_64 || (!defined(PIC) && !defined(__PIC__)) */
|
||||
#endif /* __GNUC__ > 3 */
|
||||
#endif /* ARCH_X86 */
|
||||
#endif /* USE_MMX */
|
||||
#endif /* USE_MMX */
|
||||
#endif /* !defined(__INTEL_COMPILER) */
|
||||
|
||||
#endif
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
#include "gimp-composite.h"
|
||||
|
||||
#include "gimp-composite-altivec.h"
|
||||
@@ -17,3 +18,16 @@ gimp_composite_altivec_install (void)
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_composite_altivec_init (void)
|
||||
{
|
||||
#if defined(COMPILE_ALTIVEC_IS_OKAY)
|
||||
if (cpu_accel () & CPU_ACCEL_PPC_ALTIVEC)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
|
||||
#include "gimp-composite.h"
|
||||
#include "gimp-composite-altivec.h"
|
||||
@@ -33,16 +32,3 @@
|
||||
#ifdef COMPILE_ALTIVEC_IS_OKAY
|
||||
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
gimp_composite_altivec_init (void)
|
||||
{
|
||||
#ifdef COMPILE_ALTIVEC_IS_OKAY
|
||||
if (cpu_accel () & CPU_ACCEL_PPC_ALTIVEC)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -69,6 +69,7 @@
|
||||
|
||||
static guchar add_lut[511];
|
||||
static gint32 random_table[RANDOM_TABLE_SIZE];
|
||||
static guchar burn_lut[256][256];
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -873,18 +874,10 @@ gimp_composite_burn_any_any_any_generic (GimpCompositeContext * ctx)
|
||||
const guint alpha = (has_alpha1 || has_alpha2) ? MAX(bytes1, bytes2) - 1 : bytes1;
|
||||
guint b;
|
||||
|
||||
/* FIXME: Is the burn effect supposed to be dependant on the sign of this
|
||||
* temporary variable? */
|
||||
gint tmp;
|
||||
|
||||
while (length--)
|
||||
{
|
||||
for (b = 0; b < alpha; b++)
|
||||
{
|
||||
tmp = (255 - src1[b]) << 8;
|
||||
tmp /= src2[b] + 1;
|
||||
dest[b] = (guchar) CLAMP(255 - tmp, 0, 255);
|
||||
}
|
||||
dest[b] = burn_lut[src1[b]][src2[b]];
|
||||
if (has_alpha1 && has_alpha2)
|
||||
dest[alpha] = MIN(src1[alpha], src2[alpha]);
|
||||
else if (has_alpha2)
|
||||
@@ -1444,6 +1437,7 @@ gimp_composite_generic_init (void)
|
||||
{
|
||||
GRand *gr;
|
||||
guint i;
|
||||
gint a, b;
|
||||
|
||||
#define RANDOM_SEED 314159265
|
||||
|
||||
@@ -1455,11 +1449,28 @@ gimp_composite_generic_init (void)
|
||||
|
||||
g_rand_free (gr);
|
||||
|
||||
/* generate a table for burn compositing */
|
||||
for (a = 0; a < 256; a++)
|
||||
for (b = 0; b < 256; b++)
|
||||
{
|
||||
/* FIXME: Is the burn effect supposed to be dependant on the sign
|
||||
* of this temporary variable?
|
||||
*/
|
||||
gint tmp;
|
||||
|
||||
tmp = (255 - a) << 8;
|
||||
tmp /= b + 1;
|
||||
tmp = (255 - tmp);
|
||||
|
||||
burn_lut[a][b] = CLAMP (tmp, 0, 255);
|
||||
}
|
||||
|
||||
/* generate a table for saturate add */
|
||||
for (i = 0; i < 256; i++)
|
||||
add_lut[i] = i;
|
||||
|
||||
for (i = 256; i <= 510; i++)
|
||||
add_lut[i] = 255;
|
||||
|
||||
return (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
#include "gimp-composite.h"
|
||||
|
||||
#include "gimp-composite-mmx.h"
|
||||
@@ -25,7 +26,6 @@ static struct install_table {
|
||||
{ GIMP_COMPOSITE_SUBTRACT, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_subtract_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_darken_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_LIGHTEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_lighten_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_BURN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_burn_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_GRAIN_EXTRACT, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_grain_extract_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_GRAIN_MERGE, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_grain_merge_rgba8_rgba8_rgba8_mmx },
|
||||
{ GIMP_COMPOSITE_SWAP, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_swap_rgba8_rgba8_rgba8_mmx },
|
||||
@@ -50,3 +50,16 @@ gimp_composite_mmx_install (void)
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_composite_mmx_init (void)
|
||||
{
|
||||
#if defined(COMPILE_MMX_IS_OKAY)
|
||||
if (cpu_accel () & CPU_ACCEL_X86_MMX)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -87,17 +87,6 @@ gimp_composite_mmx_test (int iterations, int n_pixels)
|
||||
}
|
||||
gimp_composite_regression_timer_report ("addition_rgba8_rgba8_rgba8", ft0, ft1);
|
||||
|
||||
gimp_composite_context_init (&special_ctx, GIMP_COMPOSITE_BURN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D2);
|
||||
gimp_composite_context_init (&generic_ctx, GIMP_COMPOSITE_BURN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D1);
|
||||
ft0 = gimp_composite_regression_time_function (iterations, gimp_composite_dispatch, &generic_ctx);
|
||||
ft1 = gimp_composite_regression_time_function (iterations, gimp_composite_burn_rgba8_rgba8_rgba8_mmx, &special_ctx);
|
||||
if (gimp_composite_regression_compare_contexts ("burn", &generic_ctx, &special_ctx))
|
||||
{
|
||||
printf("burn_rgba8_rgba8_rgba8 failed\n");
|
||||
return (1);
|
||||
}
|
||||
gimp_composite_regression_timer_report ("burn_rgba8_rgba8_rgba8", ft0, ft1);
|
||||
|
||||
gimp_composite_context_init (&special_ctx, GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D2);
|
||||
gimp_composite_context_init (&generic_ctx, GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D1);
|
||||
ft0 = gimp_composite_regression_time_function (iterations, gimp_composite_dispatch, &generic_ctx);
|
||||
|
@@ -36,7 +36,6 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
|
||||
#include "gimp-composite.h"
|
||||
#include "gimp-composite-mmx.h"
|
||||
@@ -136,123 +135,6 @@ gimp_composite_addition_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
void
|
||||
gimp_composite_burn_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
|
||||
{
|
||||
uint64 *d = (uint64 *) _op->D;
|
||||
uint64 *a = (uint64 *) _op->A;
|
||||
uint64 *b = (uint64 *) _op->B;
|
||||
gulong n_pixels = _op->n_pixels;
|
||||
|
||||
for (; n_pixels >= 2; n_pixels -= 2)
|
||||
{
|
||||
asm volatile (" movq %1,%%mm0\n"
|
||||
"\tmovq %2,%%mm1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n" /* mm6 = rgba8_alpha_mask_64 */
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovq %%mm7,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b), "m" (*rgba8_b255_64), "m" (*rgba8_w1_64), "m" (*rgba8_w255_64), "m" (*rgba8_alpha_mask_64)
|
||||
: pdivwqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
d++;
|
||||
b++;
|
||||
a++;
|
||||
}
|
||||
|
||||
if (n_pixels > 0)
|
||||
{
|
||||
asm volatile (" movd %1,%%mm0\n"
|
||||
"\tmovd %2,%%mm1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n"
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovd %%mm7,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b), "m" (*rgba8_b255_64), "m" (*rgba8_w1_64), "m" (*rgba8_w255_64), "m" (*rgba8_alpha_mask_64)
|
||||
: pdivwqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
}
|
||||
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gimp_composite_darken_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -1289,7 +1171,6 @@ gimp_composite_swap_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *_op)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -1314,11 +1195,7 @@ gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
"\t" pminub(mm3, mm2, mm4) "\n"
|
||||
"\tpand %%mm0, %%mm2\n"
|
||||
"\tpor %%mm2, %%mm1\n"
|
||||
#if 0
|
||||
"\tmovq %%mm1, %0\n"
|
||||
#else
|
||||
"\tmovntq %%mm1, %0\n"
|
||||
#endif
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm0", "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
@@ -1381,123 +1258,6 @@ gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
gimp_composite_burn_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
{
|
||||
GimpCompositeContext op = *_op;
|
||||
|
||||
asm("movq %0,%%mm1"
|
||||
:
|
||||
: "m" (*va8_alpha_mask)
|
||||
: "%mm1");
|
||||
|
||||
for (; op.n_pixels >= 4; op.n_pixels -= 4)
|
||||
{
|
||||
asm volatile (" movq %0,%%mm0\n"
|
||||
"\tmovq %1,%%mm1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n"
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovq %%mm7,%2\n"
|
||||
: /* empty */
|
||||
: "+m" (*op.A), "+m" (*op.B), "+m" (*op.D), "m" (*va8_b255), "m" (*va8_w1), "m" (*va8_w255_64), "m" (*va8_alpha_mask)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
op.A += 8;
|
||||
op.B += 8;
|
||||
op.D += 8;
|
||||
}
|
||||
|
||||
if (op.n_pixels)
|
||||
{
|
||||
asm volatile (" movd %0,%%mm0\n"
|
||||
"\tmovd %1,%%mm1\n"
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n"
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovd %%mm7,%2\n"
|
||||
: /* empty */
|
||||
: "m" (*op.A), "m" (*op.B), "m" (*op.D), "m" (*va8_b255), "m" (*va8_w1), "m" (*va8_w255_64), "m" (*va8_alpha_mask)
|
||||
: "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
}
|
||||
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
void
|
||||
xxxgimp_composite_coloronly_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -2278,15 +2038,3 @@ xxxgimp_composite_valueonly_va8_va8_va8_mmx (GimpCompositeContext *_op)
|
||||
#endif
|
||||
|
||||
#endif /* COMPILE_IS_OKAY */
|
||||
|
||||
gboolean
|
||||
gimp_composite_mmx_init (void)
|
||||
{
|
||||
#ifdef COMPILE_MMX_IS_OKAY
|
||||
if (cpu_accel () & CPU_ACCEL_X86_MMX)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -19,9 +19,9 @@ extern gboolean gimp_composite_mmx_install (void);
|
||||
#if defined(USE_MMX)
|
||||
#if defined(ARCH_X86)
|
||||
#if __GNUC__ >= 3
|
||||
#if defined(ARCH_X86_64) || !defined(PIC)
|
||||
#if defined(ARCH_X86_64) || (!defined(PIC) && !defined(__PIC__))
|
||||
#define COMPILE_MMX_IS_OKAY (1)
|
||||
#endif /* defined(ARCH_X86_64) || !defined(PIC) */
|
||||
#endif /* defined(ARCH_X86_64) || (!defined(PIC) && !defined(__PIC__)) */
|
||||
#endif /* __GNUC__ >= 3 */
|
||||
#endif /* defined(ARCH_X86) */
|
||||
#endif /* defined(USE_MMX) */
|
||||
@@ -33,7 +33,6 @@ extern gboolean gimp_composite_mmx_install (void);
|
||||
*
|
||||
*/
|
||||
extern void gimp_composite_addition_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_burn_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_coloronly_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_darken_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_difference_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
@@ -55,7 +54,6 @@ extern void gimp_composite_softlight_rgba8_rgba8_rgba8_mmx (GimpCompositeContext
|
||||
extern void gimp_composite_subtract_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_swap_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_valueonly_rgba8_rgba8_rgba8_mmx (GimpCompositeContext *ctx);
|
||||
|
||||
extern void gimp_composite_addition_va8_va8_va8_mmx (GimpCompositeContext *ctx);
|
||||
#endif /* COMPILE_IS_OKAY */
|
||||
#endif
|
||||
|
@@ -318,9 +318,9 @@ gimp_composite_regression_compare_contexts (char *operation, GimpCompositeContex
|
||||
* Return value:
|
||||
**/
|
||||
int
|
||||
gimp_composite_regression_comp_rgba8 (char *str, gimp_rgba8_t *rgba8A, gimp_rgba8_t *rgba8B, gimp_rgba8_t *expected, gimp_rgba8_t *actual, u_long length)
|
||||
gimp_composite_regression_comp_rgba8 (char *str, gimp_rgba8_t *rgba8A, gimp_rgba8_t *rgba8B, gimp_rgba8_t *expected, gimp_rgba8_t *actual, gulong length)
|
||||
{
|
||||
u_long i;
|
||||
gulong i;
|
||||
int failed;
|
||||
int fail_count;
|
||||
|
||||
@@ -366,7 +366,7 @@ gimp_composite_regression_comp_rgba8 (char *str, gimp_rgba8_t *rgba8A, gimp_rgba
|
||||
* Return value:
|
||||
**/
|
||||
int
|
||||
gimp_composite_regression_comp_va8 (char *str, gimp_va8_t *va8A, gimp_va8_t *va8B, gimp_va8_t *expected, gimp_va8_t *actual, u_long length)
|
||||
gimp_composite_regression_comp_va8 (char *str, gimp_va8_t *va8A, gimp_va8_t *va8B, gimp_va8_t *expected, gimp_va8_t *actual, gulong length)
|
||||
{
|
||||
int i;
|
||||
int failed;
|
||||
@@ -406,7 +406,7 @@ gimp_composite_regression_comp_va8 (char *str, gimp_va8_t *va8A, gimp_va8_t *va8
|
||||
*
|
||||
**/
|
||||
void
|
||||
gimp_composite_regression_dump_rgba8 (char *str, gimp_rgba8_t *rgba, u_long n_pixels)
|
||||
gimp_composite_regression_dump_rgba8 (char *str, gimp_rgba8_t *rgba, gulong n_pixels)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -447,12 +447,12 @@ gimp_composite_regression_timer_report (char *name, double t1, double t2)
|
||||
* Return value:
|
||||
**/
|
||||
double
|
||||
gimp_composite_regression_time_function (u_long iterations, void (*func)(), GimpCompositeContext *ctx)
|
||||
gimp_composite_regression_time_function (gulong iterations, void (*func)(), GimpCompositeContext *ctx)
|
||||
{
|
||||
struct timeval t0;
|
||||
struct timeval t1;
|
||||
struct timeval tv_elapsed;
|
||||
u_long i;
|
||||
gulong i;
|
||||
|
||||
gettimeofday (&t0, NULL);
|
||||
for (i = 0; i < iterations; i++) { (*func)(ctx); }
|
||||
@@ -471,10 +471,10 @@ gimp_composite_regression_time_function (u_long iterations, void (*func)(), Gimp
|
||||
* Return value:
|
||||
**/
|
||||
gimp_rgba8_t *
|
||||
gimp_composite_regression_random_rgba8 (u_long n_pixels)
|
||||
gimp_composite_regression_random_rgba8 (gulong n_pixels)
|
||||
{
|
||||
gimp_rgba8_t *rgba8;
|
||||
u_long i;
|
||||
gulong i;
|
||||
|
||||
if ((rgba8 = (gimp_rgba8_t *) calloc (sizeof(gimp_rgba8_t), n_pixels))) {
|
||||
for (i = 0; i < n_pixels; i++) {
|
||||
@@ -497,11 +497,11 @@ gimp_composite_regression_random_rgba8 (u_long n_pixels)
|
||||
* Return value:
|
||||
**/
|
||||
gimp_rgba8_t *
|
||||
gimp_composite_regression_fixed_rgba8 (u_long n_pixels)
|
||||
gimp_composite_regression_fixed_rgba8 (gulong n_pixels)
|
||||
{
|
||||
gimp_rgba8_t *rgba8;
|
||||
u_long i;
|
||||
u_long v;
|
||||
gulong i;
|
||||
gulong v;
|
||||
|
||||
if ((rgba8 = (gimp_rgba8_t *) calloc(sizeof(gimp_rgba8_t), n_pixels))) {
|
||||
for (i = 0; i < n_pixels; i++) {
|
||||
|
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
guint8 v;
|
||||
guint8 v;
|
||||
} gimp_v8_t;
|
||||
|
||||
typedef struct
|
||||
@@ -102,7 +102,7 @@ extern void gimp_composite_regression_print_vector_rgba8 (gimp_rgba8_t v[],
|
||||
unsigned int n_pixels);
|
||||
|
||||
|
||||
extern double gimp_composite_regression_time_function (u_long iterations,
|
||||
extern double gimp_composite_regression_time_function (gulong iterations,
|
||||
void (*func)(),
|
||||
GimpCompositeContext *ctx);
|
||||
extern int gimp_composite_regression_comp_rgba8 (char *str,
|
||||
@@ -110,27 +110,27 @@ extern int gimp_composite_regression_comp_rgba8 (char *str,
|
||||
gimp_rgba8_t *rgba8B,
|
||||
gimp_rgba8_t *expected,
|
||||
gimp_rgba8_t *actual,
|
||||
u_long length);
|
||||
gulong length);
|
||||
extern int gimp_composite_regression_comp_va8 (char *str,
|
||||
gimp_va8_t *va8A,
|
||||
gimp_va8_t *va8B,
|
||||
gimp_va8_t *expected,
|
||||
gimp_va8_t *actual,
|
||||
u_long length);
|
||||
gulong length);
|
||||
extern int gimp_composite_regression_compare_contexts (char *,
|
||||
GimpCompositeContext *ctx1,
|
||||
GimpCompositeContext *ctx2);
|
||||
extern void gimp_composite_regression_dump_rgba8 (char *str,
|
||||
gimp_rgba8_t *rgba,
|
||||
u_long n_pixels);
|
||||
gulong n_pixels);
|
||||
extern void gimp_composite_regression_print_rgba8 (gimp_rgba8_t *rgba8);
|
||||
extern void gimp_composite_regression_print_va8 (gimp_va8_t *va8);
|
||||
extern void gimp_composite_regression_timer_report (char *name,
|
||||
double t1,
|
||||
double t2);
|
||||
|
||||
extern gimp_rgba8_t *gimp_composite_regression_random_rgba8 (u_long n_pixels);
|
||||
extern gimp_rgba8_t *gimp_composite_regression_fixed_rgba8 (u_long n_pixels);
|
||||
extern gimp_rgba8_t *gimp_composite_regression_random_rgba8 (gulong n_pixels);
|
||||
extern gimp_rgba8_t *gimp_composite_regression_fixed_rgba8 (gulong n_pixels);
|
||||
extern GimpCompositeContext *gimp_composite_context_init (GimpCompositeContext *ctx,
|
||||
GimpCompositeOperation op,
|
||||
GimpPixelFormat a_format,
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
#include "gimp-composite.h"
|
||||
|
||||
#include "gimp-composite-sse.h"
|
||||
@@ -24,7 +25,6 @@ static struct install_table {
|
||||
{ GIMP_COMPOSITE_SUBTRACT, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_subtract_rgba8_rgba8_rgba8_sse },
|
||||
{ GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_darken_rgba8_rgba8_rgba8_sse },
|
||||
{ GIMP_COMPOSITE_LIGHTEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_lighten_rgba8_rgba8_rgba8_sse },
|
||||
{ GIMP_COMPOSITE_BURN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_burn_rgba8_rgba8_rgba8_sse },
|
||||
{ GIMP_COMPOSITE_GRAIN_EXTRACT, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_grain_extract_rgba8_rgba8_rgba8_sse },
|
||||
{ GIMP_COMPOSITE_GRAIN_MERGE, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_grain_merge_rgba8_rgba8_rgba8_sse },
|
||||
{ GIMP_COMPOSITE_SWAP, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, gimp_composite_swap_rgba8_rgba8_rgba8_sse },
|
||||
@@ -49,3 +49,18 @@ gimp_composite_sse_install (void)
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_composite_sse_init (void)
|
||||
{
|
||||
#if defined(COMPILE_SSE_IS_OKAY)
|
||||
guint32 cpu = cpu_accel ();
|
||||
|
||||
if (cpu & CPU_ACCEL_X86_SSE || cpu & CPU_ACCEL_X86_MMXEXT)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -76,17 +76,6 @@ gimp_composite_sse_test (int iterations, int n_pixels)
|
||||
}
|
||||
gimp_composite_regression_timer_report ("addition_rgba8_rgba8_rgba8", ft0, ft1);
|
||||
|
||||
gimp_composite_context_init (&special_ctx, GIMP_COMPOSITE_BURN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D2);
|
||||
gimp_composite_context_init (&generic_ctx, GIMP_COMPOSITE_BURN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D1);
|
||||
ft0 = gimp_composite_regression_time_function (iterations, gimp_composite_dispatch, &generic_ctx);
|
||||
ft1 = gimp_composite_regression_time_function (iterations, gimp_composite_burn_rgba8_rgba8_rgba8_sse, &special_ctx);
|
||||
if (gimp_composite_regression_compare_contexts ("burn", &generic_ctx, &special_ctx))
|
||||
{
|
||||
printf("burn_rgba8_rgba8_rgba8 failed\n");
|
||||
return (1);
|
||||
}
|
||||
gimp_composite_regression_timer_report ("burn_rgba8_rgba8_rgba8", ft0, ft1);
|
||||
|
||||
gimp_composite_context_init (&special_ctx, GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D2);
|
||||
gimp_composite_context_init (&generic_ctx, GIMP_COMPOSITE_DARKEN, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, GIMP_PIXELFORMAT_RGBA8, n_pixels, (unsigned char *) rgba8A, (unsigned char *) rgba8B, (unsigned char *) rgba8B, (unsigned char *) rgba8D1);
|
||||
ft0 = gimp_composite_regression_time_function (iterations, gimp_composite_dispatch, &generic_ctx);
|
||||
|
@@ -36,7 +36,6 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
|
||||
#include "gimp-composite.h"
|
||||
#include "gimp-composite-sse.h"
|
||||
@@ -48,6 +47,16 @@
|
||||
#define pminub(src,dst,tmp) "pminub " "%%" #src ", %%" #dst
|
||||
#define pmaxub(src,dst,tmp) "pmaxub " "%%" #src ", %%" #dst
|
||||
|
||||
extern const guint32 rgba8_alpha_mask_64[2];
|
||||
extern const guint32 rgba8_b1_64[2];
|
||||
extern const guint32 rgba8_b255_64[2];
|
||||
extern const guint32 rgba8_w1_64[2];
|
||||
extern const guint32 rgba8_w2_64[2];
|
||||
extern const guint32 rgba8_w128_64[2];
|
||||
extern const guint32 rgba8_w256_64[2];
|
||||
extern const guint32 rgba8_w255_64[2];
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@@ -104,124 +113,6 @@ gimp_composite_addition_rgba8_rgba8_rgba8_sse (GimpCompositeContext *_op)
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gimp_composite_burn_rgba8_rgba8_rgba8_sse (GimpCompositeContext *_op)
|
||||
{
|
||||
uint64 *d = (uint64 *) _op->D;
|
||||
uint64 *a = (uint64 *) _op->A;
|
||||
uint64 *b = (uint64 *) _op->B;
|
||||
gulong n_pixels = _op->n_pixels;
|
||||
|
||||
for (; n_pixels >= 2; n_pixels -= 2)
|
||||
{
|
||||
asm volatile (" movq %1,%%mm0\n"
|
||||
"\tmovq %2,%%mm1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n" /* mm6 = rgba8_alpha_mask_64 */
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovq %%mm7,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b), "m" (*rgba8_b255_64), "m" (*rgba8_w1_64), "m" (*rgba8_w255_64), "m" (*rgba8_alpha_mask_64)
|
||||
: pdivwqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
d++;
|
||||
b++;
|
||||
a++;
|
||||
}
|
||||
|
||||
if (n_pixels > 0)
|
||||
{
|
||||
asm volatile (" movd %1,%%mm0\n"
|
||||
"\tmovd %2,%%mm1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n"
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovd %%mm7,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b), "m" (*rgba8_b255_64), "m" (*rgba8_w1_64), "m" (*rgba8_w255_64), "m" (*rgba8_alpha_mask_64)
|
||||
: pdivwqX_clobber, "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
}
|
||||
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gimp_composite_darken_rgba8_rgba8_rgba8_sse (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -1322,121 +1213,6 @@ xxxgimp_composite_addition_va8_va8_va8_sse (GimpCompositeContext *_op)
|
||||
asm("popl %edi");
|
||||
}
|
||||
|
||||
void
|
||||
xxxgimp_composite_burn_va8_va8_va8_sse (GimpCompositeContext *_op)
|
||||
{
|
||||
GimpCompositeContext op = *_op;
|
||||
|
||||
asm("movq %0,%%mm1"
|
||||
:
|
||||
: "m" (*va8_alpha_mask)
|
||||
: "%mm1");
|
||||
|
||||
for (; op.n_pixels >= 4; op.n_pixels -= 4)
|
||||
{
|
||||
asm volatile (" movq (%0),%%mm0; addl $8,%0\n"
|
||||
"\tmovq (%1),%%mm1; addl $8,%1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n"
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovq %%mm7,(%2); addl $8,%2\n"
|
||||
: "+r" (op.A), "+r" (op.B), "+r" (op.D)
|
||||
: "m" (*va8_b255), "m" (*va8_w1), "m" (*va8_w255), "m" (*va8_alpha_mask)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
}
|
||||
|
||||
if (op.n_pixels)
|
||||
{
|
||||
asm volatile (" movd (%0),%%mm0\n"
|
||||
"\tmovd (%1),%%mm1\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpcklbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpcklbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
|
||||
"\t" pdivwqX(mm4,mm5,mm7) "\n"
|
||||
|
||||
"\tmovq %3,%%mm2\n"
|
||||
"\tpsubb %%mm0,%%mm2\n" /* mm2 = 255 - A */
|
||||
"\tpxor %%mm4,%%mm4\n"
|
||||
"\tpunpckhbw %%mm2,%%mm4\n" /* mm4 = (255- A) * 256 */
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm5,%%mm5\n"
|
||||
"\tpunpckhbw %%mm5,%%mm3\n"
|
||||
"\tmovq %4,%%mm5\n"
|
||||
"\tpaddusw %%mm3,%%mm5\n" /* mm5 = B + 1 */
|
||||
"\t" pdivwqX(mm4,mm5,mm6) "\n"
|
||||
|
||||
"\tmovq %5,%%mm4\n"
|
||||
"\tmovq %%mm4,%%mm5\n"
|
||||
"\tpsubusw %%mm6,%%mm4\n"
|
||||
"\tpsubusw %%mm7,%%mm5\n"
|
||||
|
||||
"\tpackuswb %%mm4,%%mm5\n"
|
||||
|
||||
"\t" pminub(mm0,mm1,mm3) "\n" /* mm1 = min(mm0,mm1) clobber mm3 */
|
||||
|
||||
"\tmovq %6,%%mm7\n"
|
||||
"\tpand %%mm7,%%mm1\n" /* mm1 = mm7 & alpha_mask */
|
||||
|
||||
"\tpandn %%mm5,%%mm7\n" /* mm7 = ~mm7 & mm5 */
|
||||
"\tpor %%mm1,%%mm7\n" /* mm7 = mm7 | mm1 */
|
||||
|
||||
"\tmovd %%mm7,(%2)\n"
|
||||
: /* empty */
|
||||
: "r" (op.A), "r" (op.B), "r" (op.D), "m" (*va8_b255), "m" (*va8_w1), "m" (*va8_w255), "m" (*va8_alpha_mask)
|
||||
: "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
}
|
||||
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
void
|
||||
xxxgimp_composite_coloronly_va8_va8_va8_sse (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -2217,18 +1993,3 @@ xxxgimp_composite_valueonly_va8_va8_va8_sse (GimpCompositeContext *_op)
|
||||
#endif
|
||||
|
||||
#endif /* COMPILE_SSE_IS_OKAY */
|
||||
|
||||
gboolean
|
||||
gimp_composite_sse_init (void)
|
||||
{
|
||||
#ifdef COMPILE_SSE_IS_OKAY
|
||||
guint32 cpu = cpu_accel ();
|
||||
|
||||
if (cpu & CPU_ACCEL_X86_SSE || cpu & CPU_ACCEL_X86_MMXEXT)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -13,12 +13,12 @@ extern gboolean gimp_composite_sse_install (void);
|
||||
#if defined(USE_SSE)
|
||||
#if defined(ARCH_X86)
|
||||
#if __GNUC__ >= 3
|
||||
#if defined(ARCH_X86_64) || !defined(PIC)
|
||||
#if defined(ARCH_X86_64) || (!defined(PIC) && !defined(__PIC__))
|
||||
#define COMPILE_SSE_IS_OKAY
|
||||
#endif /* defined(ARCH_X86_64) || !defined(PIC) */
|
||||
#endif /* __GNUC__ >= 3 */
|
||||
#endif /* */
|
||||
#endif /* */
|
||||
#endif /* defined(ARCH_X86_64) || !defined(PIC) */
|
||||
#endif /* __GNUC__ >= 3 */
|
||||
#endif /* defined(ARCH_X86) */
|
||||
#endif /* defined(USE_SSE) */
|
||||
#endif /* */
|
||||
|
||||
#ifdef COMPILE_SSE_IS_OKAY
|
||||
@@ -26,7 +26,6 @@ extern gboolean gimp_composite_sse_install (void);
|
||||
*
|
||||
*/
|
||||
extern void gimp_composite_addition_rgba8_rgba8_rgba8_sse (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_burn_rgba8_rgba8_rgba8_sse (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_coloronly_rgba8_rgba8_rgba8_sse (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_darken_rgba8_rgba8_rgba8_sse (GimpCompositeContext *ctx);
|
||||
extern void gimp_composite_difference_rgba8_rgba8_rgba8_sse (GimpCompositeContext *ctx);
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
#include "gimp-composite.h"
|
||||
|
||||
#include "gimp-composite-sse2.h"
|
||||
@@ -44,3 +45,16 @@ gimp_composite_sse2_install (void)
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_composite_sse2_init (void)
|
||||
{
|
||||
#if defined(COMPILE_SSE2_IS_OKAY)
|
||||
if (cpu_accel () & CPU_ACCEL_X86_SSE2)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
|
||||
#include "gimp-composite.h"
|
||||
#include "gimp-composite-sse2.h"
|
||||
@@ -138,7 +137,7 @@ gimp_composite_addition_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tpminub %%mm3,%%mm2\n"
|
||||
"\tpand %%mm0,%%mm2\n"
|
||||
"\tpor %%mm2,%%mm1\n"
|
||||
"\tmovq %%mm1,%0\n"
|
||||
"\tmovntq %%mm1,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
@@ -167,15 +166,6 @@ gimp_composite_addition_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
asm("emms");
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
xxxgimp_composite_burn_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
gimp_composite_darken_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -209,7 +199,7 @@ gimp_composite_darken_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
{
|
||||
asm volatile (" movq %1, %%mm2\n"
|
||||
"\tpminub %2, %%mm2\n"
|
||||
"\tmovq %%mm2, %0\n"
|
||||
"\tmovntq %%mm2, %0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
@@ -290,7 +280,7 @@ gimp_composite_difference_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tpminub %%mm3, %%mm2\n"
|
||||
"\tpand %%mm0, %%mm2\n"
|
||||
"\tpor %%mm2, %%mm1\n"
|
||||
"\tmovq %%mm1, %0\n"
|
||||
"\tmovntq %%mm1, %0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
|
||||
@@ -323,142 +313,6 @@ gimp_composite_difference_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
xxxgimp_composite_dodge_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
{
|
||||
GimpCompositeContext op = *_op;
|
||||
|
||||
for (; op.n_pixels >= 4; op.n_pixels -= 4)
|
||||
{
|
||||
asm volatile (" movdqu %1,%%xmm0\n"
|
||||
"\tmovdqu %2,%%xmm1\n"
|
||||
"\tmovdqu %%xmm1,%%xmm3\n"
|
||||
"\tpxor %%xmm2,%%xmm2\n"
|
||||
"\tpunpcklbw %%xmm2,%%xmm3\n"
|
||||
"\tpunpcklbw %%xmm0,%%xmm2\n"
|
||||
|
||||
"\tmovdqu %3,%%xmm4\n"
|
||||
"\tpsubw %%xmm3,%%xmm4\n"
|
||||
|
||||
"\t" xmm_pdivwuqX(xmm2,xmm4,xmm5,xmm6) "\n"
|
||||
|
||||
"\tmovdqu %%xmm1,%%xmm3\n"
|
||||
"\tpxor %%xmm2,%%xmm2\n"
|
||||
"\tpunpckhbw %%xmm2,%%xmm3\n"
|
||||
"\tpunpckhbw %%xmm0,%%xmm2\n"
|
||||
|
||||
"\tmovdqu %3,%%xmm4\n"
|
||||
"\tpsubw %%xmm3,%%xmm4\n"
|
||||
|
||||
"\t" xmm_pdivwuqX(xmm2,xmm4,xmm6,xmm7) "\n"
|
||||
|
||||
"\tpackuswb %%xmm6,%%xmm5\n"
|
||||
|
||||
"\tmovdqu %4,%%xmm6\n"
|
||||
"\tmovdqu %%xmm1,%%xmm7\n"
|
||||
"\tpminub %%xmm0,%%xmm7\n"
|
||||
"\tpand %%xmm6,%%xmm7\n"
|
||||
"\tpandn %%xmm5,%%xmm6\n"
|
||||
|
||||
"\tpor %%xmm6,%%xmm7\n"
|
||||
|
||||
"\tmovdqu %%xmm7,%0\n"
|
||||
: "=m" (*op.D)
|
||||
: "m" (*op.A), "m" (*op.B), "m" (*rgba8_w256_128), "m" (*rgba8_alpha_mask_128)
|
||||
: "%eax", "%ecx", "%edx", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7");
|
||||
op.A += 16;
|
||||
op.B += 16;
|
||||
op.D += 16;
|
||||
}
|
||||
|
||||
for (; op.n_pixels >= 2; op.n_pixels -= 2)
|
||||
{
|
||||
asm volatile (" movq %1,%%mm0\n"
|
||||
"\tmovq %2,%%mm1\n"
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm2,%%mm2\n"
|
||||
"\tpunpcklbw %%mm2,%%mm3\n"
|
||||
"\tpunpcklbw %%mm0,%%mm2\n"
|
||||
|
||||
"\tmovq %3,%%mm4\n"
|
||||
"\tpsubw %%mm3,%%mm4\n"
|
||||
|
||||
"\t" pdivwuqX(mm2,mm4,mm5) "\n"
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm2,%%mm2\n"
|
||||
"\tpunpckhbw %%mm2,%%mm3\n"
|
||||
"\tpunpckhbw %%mm0,%%mm2\n"
|
||||
|
||||
"\tmovq %3,%%mm4\n"
|
||||
"\tpsubw %%mm3,%%mm4\n"
|
||||
|
||||
"\t" pdivwuqX(mm2,mm4,mm6) "\n"
|
||||
|
||||
"\tpackuswb %%mm6,%%mm5\n"
|
||||
|
||||
"\tmovq %4,%%mm6\n"
|
||||
"\tmovq %%mm1,%%mm7\n"
|
||||
"\tpminub %%mm0,%%mm7\n"
|
||||
"\tpand %%mm6,%%mm7\n"
|
||||
"\tpandn %%mm5,%%mm6\n"
|
||||
|
||||
"\tpor %%mm6,%%mm7\n"
|
||||
|
||||
"\tmovq %%mm7,%0\n"
|
||||
: (*op.D)
|
||||
: "m" (*op.A), "m" (*op.B), "m" (*rgba8_w256_64), "m" (*rgba8_alpha_mask_64)
|
||||
: "%eax", "%ecx", "%edx", "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7");
|
||||
op.A += 8;
|
||||
op.B += 8;
|
||||
op.D += 8;
|
||||
}
|
||||
|
||||
if (op.n_pixels)
|
||||
{
|
||||
asm volatile (" movd %1,%%mm0\n"
|
||||
"\tmovq %2,%%mm1\n"
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm2,%%mm2\n"
|
||||
"\tpunpcklbw %%mm2,%%mm3\n"
|
||||
"\tpunpcklbw %%mm0,%%mm2\n"
|
||||
|
||||
"\tmovq %3,%%mm4\n"
|
||||
"\tpsubw %%mm3,%%mm4\n"
|
||||
|
||||
"\t" pdivwuqX(mm2,mm4,mm5) "\n"
|
||||
|
||||
"\tmovq %%mm1,%%mm3\n"
|
||||
"\tpxor %%mm2,%%mm2\n"
|
||||
"\tpunpckhbw %%mm2,%%mm3\n"
|
||||
"\tpunpckhbw %%mm0,%%mm2\n"
|
||||
|
||||
"\tmovq %3,%%mm4\n"
|
||||
"\tpsubw %%mm3,%%mm4\n"
|
||||
|
||||
"\t" pdivwuqX(mm2,mm4,mm6) "\n"
|
||||
|
||||
"\tpackuswb %%mm6,%%mm5\n"
|
||||
|
||||
"\tmovq %4,%%mm6\n"
|
||||
"\tmovq %%mm1,%%mm7\n"
|
||||
"\tpminub %%mm0,%%mm7\n"
|
||||
"\tpand %%mm6,%%mm7\n"
|
||||
"\tpandn %%mm5,%%mm6\n"
|
||||
|
||||
"\tpor %%mm6,%%mm7\n"
|
||||
|
||||
"\tmovd %%mm7,%0\n"
|
||||
: "=m" (*op.D)
|
||||
: "m" (*op.A), "m" (*op.B), "m" (*rgba8_w256_64), "m" (*rgba8_alpha_mask_64)
|
||||
: "%eax", "%ecx", "%edx", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
|
||||
}
|
||||
|
||||
asm("emms");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
gimp_composite_grain_extract_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
{
|
||||
@@ -509,7 +363,7 @@ gimp_composite_grain_extract_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tmovdqu %%xmm1,%0\n"
|
||||
: "=m" (*D)
|
||||
: "m" (*A), "m" (*B)
|
||||
: "%xmm1", "%xmm2", "%xmm3", "%xmm4");
|
||||
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5");
|
||||
A++;
|
||||
B++;
|
||||
D++;
|
||||
@@ -545,10 +399,10 @@ gimp_composite_grain_extract_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tpand %%mm0,%%mm2\n"
|
||||
|
||||
"\tpor %%mm2,%%mm1\n"
|
||||
"\tmovq %%mm1,%0\n"
|
||||
"\tmovntq %%mm1,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
|
||||
a++;
|
||||
b++;
|
||||
d++;
|
||||
@@ -573,7 +427,7 @@ gimp_composite_grain_extract_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tmovd %%mm1, %0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4", "%mm5");
|
||||
}
|
||||
|
||||
asm("emms");
|
||||
@@ -590,7 +444,12 @@ gimp_composite_lighten_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
uint128 *B = (uint128 *) _op->B;
|
||||
gulong n_pixels = _op->n_pixels;
|
||||
|
||||
asm volatile ("movq %0,%%mm0" : : "m" (*rgba8_alpha_mask_64) : "%mm0");
|
||||
asm volatile (" movdqu %0,%%xmm0\n"
|
||||
"\tmovq %1,%%mm0"
|
||||
: /* empty */
|
||||
: "m" (*rgba8_alpha_mask_128), "m" (*rgba8_alpha_mask_64)
|
||||
: "%xmm0", "%mm0");
|
||||
|
||||
|
||||
for (; n_pixels >= 4; n_pixels -= 4)
|
||||
{
|
||||
@@ -627,7 +486,7 @@ gimp_composite_lighten_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tpminub %%mm2, %%mm3\n"
|
||||
"\tpand %%mm0, %%mm3\n"
|
||||
"\tpor %%mm3, %%mm1\n"
|
||||
"\tmovq %%mm1, %0\n"
|
||||
"\tmovntq %%mm1, %0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
@@ -644,7 +503,7 @@ gimp_composite_lighten_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tpmaxub %%mm3, %%mm4\n"
|
||||
"\tmovq %%mm0, %%mm1\n"
|
||||
"\tpandn %%mm4, %%mm1\n"
|
||||
"\tpminub %%mm2,%%mm3\n"
|
||||
"\tpminub %%mm2, %%mm3\n"
|
||||
"\tpand %%mm0, %%mm3\n"
|
||||
"\tpor %%mm3, %%mm1\n"
|
||||
"\tmovd %%mm1, %0\n"
|
||||
@@ -709,7 +568,7 @@ gimp_composite_subtract_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
"\tpminub %%mm3,%%mm2\n"
|
||||
"\tpand %%mm0,%%mm2\n"
|
||||
"\tpor %%mm2,%%mm1\n"
|
||||
"\tmovq %%mm1,%0\n"
|
||||
"\tmovntq %%mm1,%0\n"
|
||||
: "=m" (*d)
|
||||
: "m" (*a), "m" (*b)
|
||||
: "%mm1", "%mm2", "%mm3", "%mm4");
|
||||
@@ -838,7 +697,7 @@ gimp_composite_swap_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
asm volatile (" movq %0,%%mm2\n"
|
||||
"\tmovq %1,%%mm3\n"
|
||||
"\tmovq %%mm3,%0\n"
|
||||
"\tmovq %%mm2,%1\n"
|
||||
"\tmovntq %%mm2,%1\n"
|
||||
: "+m" (*op.A), "+m" (*op.B)
|
||||
: /* empty */
|
||||
: "%mm2", "%mm3");
|
||||
@@ -861,17 +720,3 @@ gimp_composite_swap_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *_op)
|
||||
}
|
||||
|
||||
#endif /* COMPILE_SSE2_IS_OKAY */
|
||||
|
||||
gboolean
|
||||
gimp_composite_sse2_init (void)
|
||||
{
|
||||
#ifdef COMPILE_SSE2_IS_OKAY
|
||||
guint32 cpu = cpu_accel ();
|
||||
|
||||
if (cpu & CPU_ACCEL_X86_SSE2)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
#endif
|
||||
return (FALSE);
|
||||
}
|
||||
|
@@ -13,13 +13,13 @@ extern gboolean gimp_composite_sse2_install (void);
|
||||
#if defined(USE_SSE)
|
||||
#if defined(ARCH_X86)
|
||||
#if __GNUC__ >= 3
|
||||
#if defined(ARCH_X86_64) || !defined(PIC)
|
||||
#if defined(ARCH_X86_64) || (!defined(PIC) && !defined(__PIC__))
|
||||
#define COMPILE_SSE2_IS_OKAY (1)
|
||||
#endif /* defined(ARCH_X86_64) || !defined(PIC) */
|
||||
#endif /* __GNUC__ >= 3*/
|
||||
#endif /* defined(ARCH_X86) */
|
||||
#endif /* defined(USE_SSE) */
|
||||
#endif /* !defined(__INTEL_COMPILER) */
|
||||
#endif /* defined(ARCH_X86_64) || (!defined(PIC) && !defined(__PIC__)) */
|
||||
#endif /* __GNUC__ >= 3*/
|
||||
#endif /* defined(ARCH_X86) */
|
||||
#endif /* defined(USE_SSE) */
|
||||
#endif /* !defined(__INTEL_COMPILER) */
|
||||
|
||||
#ifdef COMPILE_SSE2_IS_OKAY
|
||||
extern void gimp_composite_addition_rgba8_rgba8_rgba8_sse2 (GimpCompositeContext *ctx);
|
||||
|
@@ -17,3 +17,13 @@ gimp_composite_vis_install (void)
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_composite_vis_init (void)
|
||||
{
|
||||
#if defined(COMPILE_VIS_IS_OKAY)
|
||||
return (TRUE);
|
||||
#else
|
||||
return (FALSE);
|
||||
#endif
|
||||
}
|
||||
|
@@ -35,13 +35,3 @@
|
||||
#ifdef COMPILE_VIS_IS_OKAY
|
||||
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
gimp_composite_vis_init (void)
|
||||
{
|
||||
#ifdef COMPILE_VIS_IS_OKAY
|
||||
return (TRUE);
|
||||
#else
|
||||
return (FALSE);
|
||||
#endif
|
||||
}
|
||||
|
@@ -241,15 +241,6 @@ typedef unsigned long uint32;
|
||||
typedef unsigned long long uint64;
|
||||
typedef struct { uint64 __uint64[2]; } uint128;
|
||||
|
||||
extern const guint32 rgba8_alpha_mask_64[2];
|
||||
extern const guint32 rgba8_b1_64[2];
|
||||
extern const guint32 rgba8_b255_64[2];
|
||||
extern const guint32 rgba8_w1_64[2];
|
||||
extern const guint32 rgba8_w2_64[2];
|
||||
extern const guint32 rgba8_w128_64[2];
|
||||
extern const guint32 rgba8_w256_64[2];
|
||||
extern const guint32 rgba8_w255_64[2];
|
||||
|
||||
extern const guint32 va8_alpha_mask[2];
|
||||
extern const guint32 va8_b255[2];
|
||||
extern const guint32 va8_w1[2];
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "base/base-types.h"
|
||||
#include "base/cpu-accel.h"
|
||||
|
||||
#include "gimp-composite.h"
|
||||
|
||||
|
@@ -25,6 +25,7 @@ import ns
|
||||
import pprint
|
||||
import optparse
|
||||
import copy
|
||||
import re
|
||||
|
||||
#
|
||||
# This programme creates C code for gluing a collection of compositing
|
||||
@@ -111,8 +112,12 @@ def pixel_depth_name(pixel_format):
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
|
||||
def sanitize_filename(filename):
|
||||
return re.sub('^lib[^-]+-', '', filename)
|
||||
|
||||
def functionnameify(filename):
|
||||
f = os.path.basename(filename)
|
||||
f = sanitize_filename(f)
|
||||
f = string.replace(f, ".o", "")
|
||||
f = string.replace(f, ".c", "")
|
||||
f = string.replace(f, ".h", "")
|
||||
@@ -121,6 +126,7 @@ def functionnameify(filename):
|
||||
|
||||
def filenameify(filename):
|
||||
f = os.path.basename(filename)
|
||||
f = sanitize_filename(f)
|
||||
f = string.replace(f, ".o", "")
|
||||
f = string.replace(f, ".c", "")
|
||||
f = string.replace(f, ".h", "")
|
||||
@@ -415,7 +421,7 @@ def gimp_composite_installer_install2(fpout, name, function_table, requirements=
|
||||
print >>fpout, '%s_install (void)' % (functionnameify(name))
|
||||
print >>fpout, '{'
|
||||
|
||||
if len(function_table) > 1:
|
||||
if len(function_table) >= 1:
|
||||
print >>fpout, ' static struct install_table *t = _%s;' % (functionnameify(name))
|
||||
print >>fpout, ''
|
||||
print >>fpout, ' if (%s_init ())' % functionnameify(name)
|
||||
@@ -435,6 +441,58 @@ def gimp_composite_installer_install2(fpout, name, function_table, requirements=
|
||||
print >>fpout, '}'
|
||||
pass
|
||||
|
||||
def gimp_composite_installer_install3(fpout, name, requirements=[], cpu_feature=[]):
|
||||
if not requirements and not cpu_feature:
|
||||
return
|
||||
|
||||
print >>fpout, ''
|
||||
print >>fpout, 'gboolean'
|
||||
print >>fpout, '%s_init (void)' % (functionnameify(name))
|
||||
print >>fpout, '{'
|
||||
|
||||
need_endif = False
|
||||
|
||||
for r in requirements:
|
||||
print >>fpout, '#if %s' % (r)
|
||||
pass
|
||||
|
||||
if cpu_feature:
|
||||
if len(cpu_feature) >= 2:
|
||||
features = []
|
||||
for f in cpu_feature:
|
||||
features.append('cpu & CPU_ACCEL_%s' % f)
|
||||
feature_test = ' || '.join(features)
|
||||
|
||||
print >>fpout, ' guint32 cpu = cpu_accel ();'
|
||||
print >>fpout, ''
|
||||
else:
|
||||
feature_test = 'cpu_accel () & CPU_ACCEL_%s' % cpu_feature[0]
|
||||
|
||||
print >>fpout, ' if (%s)' % feature_test
|
||||
print >>fpout, ' {'
|
||||
print >>fpout, ' return (TRUE);'
|
||||
print >>fpout, ' }'
|
||||
|
||||
if requirements:
|
||||
print >>fpout, '#endif'
|
||||
print >>fpout, ''
|
||||
else:
|
||||
print >>fpout, ' return (TRUE);'
|
||||
|
||||
if requirements:
|
||||
print >>fpout, '#else'
|
||||
need_endif = True
|
||||
|
||||
if requirements or cpu_feature:
|
||||
print >>fpout, ' return (FALSE);'
|
||||
|
||||
if need_endif:
|
||||
print >>fpout, '#endif'
|
||||
|
||||
print >>fpout, '}'
|
||||
pass
|
||||
|
||||
|
||||
def gimp_composite_hfile(fpout, name, function_table):
|
||||
print >>fpout, '/* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT */'
|
||||
print >>fpout, '/* REGENERATE BY USING make-installer.py */'
|
||||
@@ -445,7 +503,7 @@ def gimp_composite_hfile(fpout, name, function_table):
|
||||
|
||||
return
|
||||
|
||||
def gimp_composite_cfile(fpout, name, function_table, requirements=[]):
|
||||
def gimp_composite_cfile(fpout, name, function_table, requirements=[], cpu_feature=[]):
|
||||
print >>fpout, '/* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT */'
|
||||
print >>fpout, '/* REGENERATE BY USING make-installer.py */'
|
||||
print >>fpout, '#include "config.h"'
|
||||
@@ -453,6 +511,8 @@ def gimp_composite_cfile(fpout, name, function_table, requirements=[]):
|
||||
print >>fpout, '#include <stdlib.h>'
|
||||
print >>fpout, '#include <stdio.h>'
|
||||
print >>fpout, '#include "base/base-types.h"'
|
||||
if cpu_feature:
|
||||
print >>fpout, '#include "base/cpu-accel.h"'
|
||||
print >>fpout, '#include "gimp-composite.h"'
|
||||
print >>fpout, ''
|
||||
print >>fpout, '#include "%s.h"' % (filenameify(name))
|
||||
@@ -462,26 +522,31 @@ def gimp_composite_cfile(fpout, name, function_table, requirements=[]):
|
||||
|
||||
gimp_composite_installer_install2(fpout, name, function_table, requirements)
|
||||
|
||||
gimp_composite_installer_install3(fpout, name, requirements, cpu_feature)
|
||||
|
||||
return
|
||||
|
||||
###########################################
|
||||
|
||||
op = optparse.OptionParser(version="$Revision$")
|
||||
op.add_option('-f', '--file', action='store', type='string', dest='file', default=None,
|
||||
op.add_option('-f', '--file', action='store', type='string', dest='file', default=None,
|
||||
help='the input object file')
|
||||
op.add_option('-t', '--test', action='store_true', dest='test', default=False,
|
||||
op.add_option('-t', '--test', action='store_true', dest='test', default=False,
|
||||
help='generate regression testing code')
|
||||
op.add_option('-i', '--iterations', action='store', type='int', dest='iterations', default=10,
|
||||
op.add_option('-i', '--iterations', action='store', type='int', dest='iterations', default=10,
|
||||
help='number of iterations in regression tests')
|
||||
op.add_option('-n', '--n-pixels', action='store', type="int", dest='n_pixels', default=1024*8192+16+1,
|
||||
op.add_option('-n', '--n-pixels', action='store', type="int", dest='n_pixels', default=1024*8192+16+1,
|
||||
help='number of pixels in each regression test iteration')
|
||||
op.add_option('-r', '--requires', action='append', type='string', dest='requires', default=[],
|
||||
op.add_option('-r', '--requires', action='append', type='string', dest='requires', default=[],
|
||||
help='cpp #if conditionals')
|
||||
op.add_option('-c', '--cpu-feature', action='append', type='string', dest='cpu_feature', default=[],
|
||||
help='cpu_accel feature tests')
|
||||
|
||||
options, args = op.parse_args()
|
||||
|
||||
table = load_function_table(options.file)
|
||||
|
||||
gimp_composite_cfile(open(filenameify(options.file) + "-installer.c", "w"), options.file, table, options.requires)
|
||||
gimp_composite_cfile(open(filenameify(options.file) + "-installer.c", "w"), options.file, table, options.requires, options.cpu_feature)
|
||||
|
||||
if options.test == True:
|
||||
gimp_composite_regression(open(filenameify(options.file) + "-test.c", "w"), table, options)
|
||||
|
@@ -49,13 +49,18 @@ class nmx:
|
||||
|
||||
return (None)
|
||||
|
||||
def split_(self, line):
|
||||
tmp=string.split(line)[0:2]
|
||||
tmp.reverse()
|
||||
return tmp
|
||||
|
||||
def update(self, objfile):
|
||||
self.filename = objfile
|
||||
|
||||
(sysname, nodename, release, version, machine) = os.uname()
|
||||
if sysname == "Linux":
|
||||
fp = os.popen("nm -B " + objfile, "r")
|
||||
symbols = map(lambda l: string.split(l[8:]), fp.readlines())
|
||||
fp = os.popen("nm -P " + objfile, "r")
|
||||
symbols = map(self.split_, fp.readlines())
|
||||
elif sysname == "SunOS":
|
||||
fp = os.popen("nm -p " + objfile, "r")
|
||||
symbols = map(lambda l: string.split(l[12:]), fp.readlines())
|
||||
|
@@ -114,14 +114,15 @@ gimp_base_config_class_init (GimpBaseConfigClass *klass)
|
||||
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_STINGY_MEMORY_USE,
|
||||
"stingy-memory-use", STINGY_MEMORY_USE_BLURB,
|
||||
FALSE,
|
||||
GIMP_PARAM_RESTART);
|
||||
GIMP_PARAM_IGNORE);
|
||||
GIMP_CONFIG_INSTALL_PROP_UINT (object_class, PROP_NUM_PROCESSORS,
|
||||
"num-processors", NUM_PROCESSORS_BLURB,
|
||||
1, 30, 1,
|
||||
0);
|
||||
GIMP_CONFIG_INSTALL_PROP_MEMSIZE (object_class, PROP_TILE_CACHE_SIZE,
|
||||
"tile-cache-size", TILE_CACHE_SIZE_BLURB,
|
||||
0, GIMP_MAX_MEMSIZE, 1 << 27, /* 128MB */
|
||||
0, MIN (G_MAXULONG, GIMP_MAX_MEMSIZE),
|
||||
1 << 27, /* 128MB */
|
||||
GIMP_PARAM_CONFIRM);
|
||||
}
|
||||
|
||||
|
@@ -136,6 +136,9 @@ dump_gimprc_system (GimpConfig *rc,
|
||||
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
|
||||
continue;
|
||||
|
||||
if (prop_spec->flags & GIMP_PARAM_IGNORE)
|
||||
continue;
|
||||
|
||||
comment = dump_describe_param (prop_spec);
|
||||
if (comment)
|
||||
{
|
||||
@@ -165,7 +168,7 @@ static const gchar *man_page_header =
|
||||
".SH DESCRIPTION\n"
|
||||
"The\n"
|
||||
".B gimprc\n"
|
||||
"file is a configuation file read by the GIMP when it starts up. There\n"
|
||||
"file is a configuration file read by the GIMP when it starts up. There\n"
|
||||
"are two of these: one system-wide one stored in\n"
|
||||
"@gimpsysconfdir@/gimprc and a per-user \\fB$HOME\\fP/@gimpdir@/gimprc\n"
|
||||
"which may override system settings.\n"
|
||||
@@ -212,7 +215,7 @@ static const gchar *man_page_path =
|
||||
"variable GIMP2_DIRECTORY or to ~/@gimpdir@.\n"
|
||||
".TP\n"
|
||||
".I gimp_data_dir\n"
|
||||
"Nase for paths to shareable data, which is set to the value of the\n"
|
||||
"Base for paths to shareable data, which is set to the value of the\n"
|
||||
"environment variable GIMP2_DATADIR or to the compiled-in default value\n"
|
||||
"@gimpdatadir@.\n"
|
||||
".TP\n"
|
||||
@@ -265,6 +268,9 @@ dump_gimprc_manpage (GimpConfig *rc,
|
||||
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
|
||||
continue;
|
||||
|
||||
if (prop_spec->flags & GIMP_PARAM_IGNORE)
|
||||
continue;
|
||||
|
||||
write (fd, ".TP\n", strlen (".TP\n"));
|
||||
|
||||
if (gimp_config_serialize_property (rc, prop_spec, writer))
|
||||
|
@@ -37,6 +37,16 @@
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
#define DEFAULT_GIMP_HELP_BROWSER GIMP_HELP_BROWSER_WEB_BROWSER
|
||||
#define DEFAULT_THEME "Default"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
# define DEFAULT_WEB_BROWSER "not used on Windows"
|
||||
#else
|
||||
# define DEFAULT_WEB_BROWSER "mozilla %s"
|
||||
#endif
|
||||
|
||||
|
||||
static void gimp_gui_config_class_init (GimpGuiConfigClass *klass);
|
||||
static void gimp_gui_config_finalize (GObject *object);
|
||||
static void gimp_gui_config_set_property (GObject *object,
|
||||
@@ -48,17 +58,6 @@ static void gimp_gui_config_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
#define DEFAULT_THEME "Default"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
# define DEFAULT_GIMP_HELP_BROWSER GIMP_HELP_BROWSER_WEB_BROWSER
|
||||
# define DEFAULT_WEB_BROWSER "not used on Windows"
|
||||
#else
|
||||
# define DEFAULT_GIMP_HELP_BROWSER GIMP_HELP_BROWSER_GIMP
|
||||
# define DEFAULT_WEB_BROWSER "mozilla %s"
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@@ -952,6 +952,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ROTATE, "GIMP_UNDO_GROUP_IMAGE_ROTATE", "group-image-rotate" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CROP, "GIMP_UNDO_GROUP_IMAGE_CROP", "group-image-crop" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CONVERT, "GIMP_UNDO_GROUP_IMAGE_CONVERT", "group-image-convert" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE, "GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE", "group-image-item-remove" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, "GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE", "group-image-layers-merge" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE, "GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE", "group-image-vectors-merge" },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_QMASK, "GIMP_UNDO_GROUP_IMAGE_QMASK", "group-image-qmask" },
|
||||
@@ -1017,6 +1018,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_FS_RELAX, "GIMP_UNDO_FS_RELAX", "fs-relax" },
|
||||
{ GIMP_UNDO_TRANSFORM, "GIMP_UNDO_TRANSFORM", "transform" },
|
||||
{ GIMP_UNDO_PAINT, "GIMP_UNDO_PAINT", "paint" },
|
||||
{ GIMP_UNDO_INK, "GIMP_UNDO_INK", "ink" },
|
||||
{ GIMP_UNDO_PARASITE_ATTACH, "GIMP_UNDO_PARASITE_ATTACH", "parasite-attach" },
|
||||
{ GIMP_UNDO_PARASITE_REMOVE, "GIMP_UNDO_PARASITE_REMOVE", "parasite-remove" },
|
||||
{ GIMP_UNDO_CANT, "GIMP_UNDO_CANT", "cant" },
|
||||
@@ -1032,6 +1034,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ROTATE, N_("Rotate image"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CROP, N_("Crop image"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_CONVERT, N_("Convert image"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE, N_("Remove item"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, N_("Merge layers"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE, N_("Merge vectors"), NULL },
|
||||
{ GIMP_UNDO_GROUP_IMAGE_QMASK, N_("Quick Mask"), NULL },
|
||||
@@ -1097,6 +1100,7 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_FS_RELAX, N_("FS relax"), NULL },
|
||||
{ GIMP_UNDO_TRANSFORM, N_("Transform"), NULL },
|
||||
{ GIMP_UNDO_PAINT, N_("Paint"), NULL },
|
||||
{ GIMP_UNDO_INK, N_("Ink"), NULL },
|
||||
{ GIMP_UNDO_PARASITE_ATTACH, N_("Attach parasite"), NULL },
|
||||
{ GIMP_UNDO_PARASITE_REMOVE, N_("Remove parasite"), NULL },
|
||||
{ GIMP_UNDO_CANT, N_("EEK: can't undo"), NULL },
|
||||
|
@@ -439,6 +439,7 @@ typedef enum /*< pdb-skip >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_ROTATE, /*< desc="Rotate image" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_CROP, /*< desc="Crop image" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_CONVERT, /*< desc="Convert image" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE, /*< desc="Remove item" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, /*< desc="Merge layers" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE,/*< desc="Merge vectors" >*/
|
||||
GIMP_UNDO_GROUP_IMAGE_QMASK, /*< desc="Quick Mask" >*/
|
||||
@@ -509,6 +510,7 @@ typedef enum /*< pdb-skip >*/
|
||||
GIMP_UNDO_FS_RELAX, /*< desc="FS relax" >*/
|
||||
GIMP_UNDO_TRANSFORM, /*< desc="Transform" >*/
|
||||
GIMP_UNDO_PAINT, /*< desc="Paint" >*/
|
||||
GIMP_UNDO_INK, /*< desc="Ink" >*/
|
||||
GIMP_UNDO_PARASITE_ATTACH, /*< desc="Attach parasite" >*/
|
||||
GIMP_UNDO_PARASITE_REMOVE, /*< desc="Remove parasite" >*/
|
||||
|
||||
|
@@ -111,6 +111,9 @@ gimp_edit_copy_visible (GimpImage *gimage,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gimp_projection_finish_draw (gimage->projection);
|
||||
gimp_projection_flush_now (gimage->projection);
|
||||
|
||||
tiles = tile_manager_new (x2 - x1, y2 - y1,
|
||||
gimp_projection_get_bytes (gimage->projection));
|
||||
tile_manager_set_offsets (tiles, x1, y1);
|
||||
|
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
@@ -107,8 +109,28 @@ gimp_templates_save (Gimp *gimp)
|
||||
}
|
||||
|
||||
|
||||
/* just like gimp_list_get_child_by_name() but matches case-insensitive */
|
||||
static GimpObject *
|
||||
gimp_templates_migrate_get_child_by_name (const GimpContainer *container,
|
||||
const gchar *name)
|
||||
{
|
||||
GimpList *list = GIMP_LIST (container);
|
||||
GList *glist;
|
||||
|
||||
for (glist = list->list; glist; glist = g_list_next (glist))
|
||||
{
|
||||
GimpObject *object = glist->data;
|
||||
|
||||
if (! g_ascii_strcasecmp (object->name, name))
|
||||
return object;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_templates_migrate:
|
||||
* @olddir: the old user directory
|
||||
*
|
||||
* Migrating the templaterc from GIMP 2.0 to GIMP 2.2 needs this special
|
||||
* hack since we changed the way that units are handled. This function
|
||||
@@ -116,7 +138,7 @@ gimp_templates_save (Gimp *gimp)
|
||||
* is to replace the unit for a couple of default templates with "pixels".
|
||||
**/
|
||||
void
|
||||
gimp_templates_migrate (void)
|
||||
gimp_templates_migrate (const gchar *olddir)
|
||||
{
|
||||
GimpContainer *templates = gimp_list_new (GIMP_TYPE_TEMPLATE, TRUE);
|
||||
gchar *filename = gimp_personal_rc_file ("templaterc");
|
||||
@@ -127,7 +149,26 @@ gimp_templates_migrate (void)
|
||||
gchar *tmp = g_build_filename (gimp_sysconf_directory (),
|
||||
"templaterc", NULL);
|
||||
|
||||
gimp_config_deserialize_file (GIMP_CONFIG (templates), tmp, NULL, NULL);
|
||||
if (olddir && strstr (olddir, "2.0"))
|
||||
{
|
||||
/* We changed the spelling of a couple of template names
|
||||
* from upper to lower case between 2.0 and 2.2.
|
||||
*/
|
||||
GimpContainerClass *class = GIMP_CONTAINER_GET_CLASS (templates);
|
||||
gpointer func = class->get_child_by_name;
|
||||
|
||||
class->get_child_by_name = gimp_templates_migrate_get_child_by_name;
|
||||
|
||||
gimp_config_deserialize_file (GIMP_CONFIG (templates),
|
||||
tmp, NULL, NULL);
|
||||
|
||||
class->get_child_by_name = func;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_config_deserialize_file (GIMP_CONFIG (templates),
|
||||
tmp, NULL, NULL);
|
||||
}
|
||||
|
||||
g_free (tmp);
|
||||
|
||||
|
@@ -20,10 +20,10 @@
|
||||
#define __GIMP_TEMPLATES_H__
|
||||
|
||||
|
||||
void gimp_templates_load (Gimp *gimp);
|
||||
void gimp_templates_save (Gimp *gimp);
|
||||
void gimp_templates_load (Gimp *gimp);
|
||||
void gimp_templates_save (Gimp *gimp);
|
||||
|
||||
void gimp_templates_migrate (void);
|
||||
void gimp_templates_migrate (const gchar *olddir);
|
||||
|
||||
|
||||
#endif /* __GIMP_TEMPLATES_H__ */
|
||||
|
@@ -1,758 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32 /* gets defined by glib.h */
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifndef _O_BINARY
|
||||
#define _O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "base/brush-scale.h"
|
||||
#include "base/temp-buf.h"
|
||||
|
||||
#include "config/gimpbaseconfig.h"
|
||||
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpbrush-header.h"
|
||||
#include "gimpbrushgenerated.h"
|
||||
#include "gimpmarshal.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
SPACING_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
static void gimp_brush_class_init (GimpBrushClass *klass);
|
||||
static void gimp_brush_init (GimpBrush *brush);
|
||||
|
||||
static void gimp_brush_finalize (GObject *object);
|
||||
|
||||
static gint64 gimp_brush_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
|
||||
static gboolean gimp_brush_get_popup_size (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height,
|
||||
gboolean dot_for_dot,
|
||||
gint *popup_width,
|
||||
gint *popup_height);
|
||||
static TempBuf * gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height);
|
||||
static gchar * gimp_brush_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip);
|
||||
static gchar * gimp_brush_get_extension (GimpData *data);
|
||||
|
||||
static GimpBrush * gimp_brush_real_select_brush (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords);
|
||||
static gboolean gimp_brush_real_want_null_motion (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords);
|
||||
|
||||
|
||||
static guint brush_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static GimpDataClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
gimp_brush_get_type (void)
|
||||
{
|
||||
static GType brush_type = 0;
|
||||
|
||||
if (! brush_type)
|
||||
{
|
||||
static const GTypeInfo brush_info =
|
||||
{
|
||||
sizeof (GimpBrushClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gimp_brush_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GimpBrush),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gimp_brush_init,
|
||||
};
|
||||
|
||||
brush_type = g_type_register_static (GIMP_TYPE_DATA,
|
||||
"GimpBrush",
|
||||
&brush_info, 0);
|
||||
}
|
||||
|
||||
return brush_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_brush_class_init (GimpBrushClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
||||
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
||||
GimpDataClass *data_class = GIMP_DATA_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
brush_signals[SPACING_CHANGED] =
|
||||
g_signal_new ("spacing_changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpBrushClass, spacing_changed),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
object_class->finalize = gimp_brush_finalize;
|
||||
|
||||
gimp_object_class->get_memsize = gimp_brush_get_memsize;
|
||||
|
||||
viewable_class->default_stock_id = "gimp-tool-paintbrush";
|
||||
viewable_class->get_popup_size = gimp_brush_get_popup_size;
|
||||
viewable_class->get_new_preview = gimp_brush_get_new_preview;
|
||||
viewable_class->get_description = gimp_brush_get_description;
|
||||
|
||||
data_class->get_extension = gimp_brush_get_extension;
|
||||
|
||||
klass->select_brush = gimp_brush_real_select_brush;
|
||||
klass->want_null_motion = gimp_brush_real_want_null_motion;
|
||||
klass->spacing_changed = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_brush_init (GimpBrush *brush)
|
||||
{
|
||||
brush->mask = NULL;
|
||||
brush->pixmap = NULL;
|
||||
|
||||
brush->spacing = 20;
|
||||
brush->x_axis.x = 15.0;
|
||||
brush->x_axis.y = 0.0;
|
||||
brush->y_axis.x = 0.0;
|
||||
brush->y_axis.y = 15.0;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_brush_finalize (GObject *object)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (object);
|
||||
|
||||
if (brush->mask)
|
||||
{
|
||||
temp_buf_free (brush->mask);
|
||||
brush->mask = NULL;
|
||||
}
|
||||
|
||||
if (brush->pixmap)
|
||||
{
|
||||
temp_buf_free (brush->pixmap);
|
||||
brush->pixmap = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint64
|
||||
gimp_brush_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (object);
|
||||
gint64 memsize = 0;
|
||||
|
||||
if (brush->mask)
|
||||
memsize += temp_buf_get_memsize (brush->mask);
|
||||
|
||||
if (brush->pixmap)
|
||||
memsize += temp_buf_get_memsize (brush->pixmap);
|
||||
|
||||
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
|
||||
gui_size);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_brush_get_popup_size (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height,
|
||||
gboolean dot_for_dot,
|
||||
gint *popup_width,
|
||||
gint *popup_height)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
|
||||
if (brush->mask->width > width || brush->mask->height > height)
|
||||
{
|
||||
*popup_width = brush->mask->width;
|
||||
*popup_height = brush->mask->height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static TempBuf *
|
||||
gimp_brush_get_new_preview (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
gint brush_width;
|
||||
gint brush_height;
|
||||
TempBuf *mask_buf = NULL;
|
||||
TempBuf *pixmap_buf = NULL;
|
||||
TempBuf *return_buf = NULL;
|
||||
guchar transp[4] = { 0, 0, 0, 0 };
|
||||
guchar *mask;
|
||||
guchar *buf;
|
||||
gint x, y;
|
||||
gboolean scale = FALSE;
|
||||
|
||||
mask_buf = gimp_brush_get_mask (brush);
|
||||
pixmap_buf = gimp_brush_get_pixmap (brush);
|
||||
|
||||
brush_width = mask_buf->width;
|
||||
brush_height = mask_buf->height;
|
||||
|
||||
if (brush_width > width || brush_height > height)
|
||||
{
|
||||
gdouble ratio_x = (gdouble) brush_width / width;
|
||||
gdouble ratio_y = (gdouble) brush_height / height;
|
||||
|
||||
brush_width = (gdouble) brush_width / MAX (ratio_x, ratio_y) + 0.5;
|
||||
brush_height = (gdouble) brush_height / MAX (ratio_x, ratio_y) + 0.5;
|
||||
|
||||
if (brush_width <= 0) brush_width = 1;
|
||||
if (brush_height <= 0) brush_height = 1;
|
||||
|
||||
mask_buf = brush_scale_mask (mask_buf, brush_width, brush_height);
|
||||
|
||||
if (pixmap_buf)
|
||||
{
|
||||
/* TODO: the scale function should scale the pixmap and the
|
||||
* mask in one run
|
||||
*/
|
||||
pixmap_buf =
|
||||
brush_scale_pixmap (pixmap_buf, brush_width, brush_height);
|
||||
}
|
||||
|
||||
scale = TRUE;
|
||||
}
|
||||
|
||||
return_buf = temp_buf_new (brush_width, brush_height, 4, 0, 0, transp);
|
||||
|
||||
mask = temp_buf_data (mask_buf);
|
||||
buf = temp_buf_data (return_buf);
|
||||
|
||||
if (pixmap_buf)
|
||||
{
|
||||
guchar *pixmap = temp_buf_data (pixmap_buf);
|
||||
|
||||
for (y = 0; y < brush_height; y++)
|
||||
{
|
||||
for (x = 0; x < brush_width ; x++)
|
||||
{
|
||||
*buf++ = *pixmap++;
|
||||
*buf++ = *pixmap++;
|
||||
*buf++ = *pixmap++;
|
||||
*buf++ = *mask++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < brush_height; y++)
|
||||
{
|
||||
for (x = 0; x < brush_width ; x++)
|
||||
{
|
||||
*buf++ = 0;
|
||||
*buf++ = 0;
|
||||
*buf++ = 0;
|
||||
*buf++ = *mask++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scale)
|
||||
{
|
||||
temp_buf_free (mask_buf);
|
||||
|
||||
if (pixmap_buf)
|
||||
temp_buf_free (pixmap_buf);
|
||||
}
|
||||
|
||||
return return_buf;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_brush_get_description (GimpViewable *viewable,
|
||||
gchar **tooltip)
|
||||
{
|
||||
GimpBrush *brush = GIMP_BRUSH (viewable);
|
||||
|
||||
if (tooltip)
|
||||
*tooltip = NULL;
|
||||
|
||||
return g_strdup_printf ("%s (%d x %d)",
|
||||
GIMP_OBJECT (brush)->name,
|
||||
brush->mask->width,
|
||||
brush->mask->height);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_brush_get_extension (GimpData *data)
|
||||
{
|
||||
return GIMP_BRUSH_FILE_EXTENSION;
|
||||
}
|
||||
|
||||
GimpData *
|
||||
gimp_brush_new (const gchar *name,
|
||||
gboolean stingy_memory_use)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
return gimp_brush_generated_new (name,
|
||||
GIMP_BRUSH_GENERATED_CIRCLE,
|
||||
5.0, 2, 0.5, 1.0, 0.0,
|
||||
stingy_memory_use);
|
||||
}
|
||||
|
||||
GimpData *
|
||||
gimp_brush_get_standard (void)
|
||||
{
|
||||
static GimpData *standard_brush = NULL;
|
||||
|
||||
if (! standard_brush)
|
||||
{
|
||||
standard_brush = gimp_brush_new ("Standard", FALSE);
|
||||
|
||||
standard_brush->dirty = FALSE;
|
||||
gimp_data_make_internal (standard_brush);
|
||||
|
||||
/* set ref_count to 2 --> never swap the standard brush */
|
||||
g_object_ref (standard_brush);
|
||||
}
|
||||
|
||||
return standard_brush;
|
||||
}
|
||||
|
||||
GList *
|
||||
gimp_brush_load (const gchar *filename,
|
||||
gboolean stingy_memory_use,
|
||||
GError **error)
|
||||
{
|
||||
GimpBrush *brush;
|
||||
gint fd;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (g_path_is_absolute (filename), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
fd = open (filename, O_RDONLY | _O_BINARY);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
|
||||
_("Could not open '%s' for reading: %s"),
|
||||
gimp_filename_to_utf8 (filename), g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
brush = gimp_brush_load_brush (fd, filename, error);
|
||||
|
||||
close (fd);
|
||||
|
||||
if (! brush)
|
||||
return NULL;
|
||||
|
||||
/* Swap the brush to disk (if we're being stingy with memory) */
|
||||
if (stingy_memory_use)
|
||||
{
|
||||
temp_buf_swap (brush->mask);
|
||||
|
||||
if (brush->pixmap)
|
||||
temp_buf_swap (brush->pixmap);
|
||||
}
|
||||
|
||||
return g_list_prepend (NULL, brush);
|
||||
}
|
||||
|
||||
GimpBrush *
|
||||
gimp_brush_select_brush (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
|
||||
g_return_val_if_fail (last_coords != NULL, NULL);
|
||||
g_return_val_if_fail (cur_coords != NULL, NULL);
|
||||
|
||||
return GIMP_BRUSH_GET_CLASS (brush)->select_brush (brush,
|
||||
last_coords,
|
||||
cur_coords);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_brush_want_null_motion (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), FALSE);
|
||||
g_return_val_if_fail (last_coords != NULL, FALSE);
|
||||
g_return_val_if_fail (cur_coords != NULL, FALSE);
|
||||
|
||||
return GIMP_BRUSH_GET_CLASS (brush)->want_null_motion (brush,
|
||||
last_coords,
|
||||
cur_coords);
|
||||
}
|
||||
|
||||
static GimpBrush *
|
||||
gimp_brush_real_select_brush (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
return brush;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_brush_real_want_null_motion (GimpBrush *brush,
|
||||
GimpCoords *last_coords,
|
||||
GimpCoords *cur_coords)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TempBuf *
|
||||
gimp_brush_get_mask (const GimpBrush *brush)
|
||||
{
|
||||
g_return_val_if_fail (brush != NULL, NULL);
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
|
||||
|
||||
return brush->mask;
|
||||
}
|
||||
|
||||
TempBuf *
|
||||
gimp_brush_get_pixmap (const GimpBrush *brush)
|
||||
{
|
||||
g_return_val_if_fail (brush != NULL, NULL);
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
|
||||
|
||||
return brush->pixmap;
|
||||
}
|
||||
|
||||
gint
|
||||
gimp_brush_get_spacing (const GimpBrush *brush)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH (brush), 0);
|
||||
|
||||
return brush->spacing;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_set_spacing (GimpBrush *brush,
|
||||
gint spacing)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_BRUSH (brush));
|
||||
|
||||
if (brush->spacing != spacing)
|
||||
{
|
||||
brush->spacing = spacing;
|
||||
|
||||
gimp_brush_spacing_changed (brush);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_brush_spacing_changed (GimpBrush *brush)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_BRUSH (brush));
|
||||
|
||||
g_signal_emit (brush, brush_signals[SPACING_CHANGED], 0);
|
||||
}
|
||||
|
||||
GimpBrush *
|
||||
gimp_brush_load_brush (gint fd,
|
||||
const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
GimpBrush *brush;
|
||||
gint bn_size;
|
||||
BrushHeader header;
|
||||
gchar *name = NULL;
|
||||
guchar *pixmap;
|
||||
guchar *mask;
|
||||
gssize i, size;
|
||||
gboolean success = TRUE;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (fd != -1, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* Read in the header size */
|
||||
if (read (fd, &header, sizeof (header)) != sizeof (header))
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Could not read %d bytes from '%s': %s"),
|
||||
(gint) sizeof (header),
|
||||
gimp_filename_to_utf8 (filename), g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* rearrange the bytes in each unsigned int */
|
||||
header.header_size = g_ntohl (header.header_size);
|
||||
header.version = g_ntohl (header.version);
|
||||
header.width = g_ntohl (header.width);
|
||||
header.height = g_ntohl (header.height);
|
||||
header.bytes = g_ntohl (header.bytes);
|
||||
header.magic_number = g_ntohl (header.magic_number);
|
||||
header.spacing = g_ntohl (header.spacing);
|
||||
|
||||
/* Check for correct file format */
|
||||
|
||||
if (header.width == 0)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Width = 0."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.height == 0)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Height = 0."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.bytes == 0)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Bytes = 0."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (header.version)
|
||||
{
|
||||
case 1:
|
||||
/* If this is a version 1 brush, set the fp back 8 bytes */
|
||||
lseek (fd, -8, SEEK_CUR);
|
||||
header.header_size += 8;
|
||||
/* spacing is not defined in version 1 */
|
||||
header.spacing = 25;
|
||||
break;
|
||||
|
||||
case 3: /* cinepaint brush */
|
||||
if (header.bytes == 18 /* FLOAT16_GRAY_GIMAGE */)
|
||||
{
|
||||
header.bytes = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Unknown depth %d."),
|
||||
gimp_filename_to_utf8 (filename), header.bytes);
|
||||
return NULL;
|
||||
}
|
||||
/* fallthrough */
|
||||
|
||||
case 2:
|
||||
if (header.magic_number == GBRUSH_MAGIC)
|
||||
break;
|
||||
|
||||
default:
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Unknown version %d."),
|
||||
gimp_filename_to_utf8 (filename), header.version);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read in the brush name */
|
||||
if ((bn_size = (header.header_size - sizeof (header))))
|
||||
{
|
||||
gchar *utf8;
|
||||
|
||||
name = g_new (gchar, bn_size);
|
||||
|
||||
if ((read (fd, name, bn_size)) < bn_size)
|
||||
{
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"File appears truncated."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
g_free (name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utf8 = gimp_any_to_utf8 (name, -1,
|
||||
_("Invalid UTF-8 string in brush file '%s'."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
g_free (name);
|
||||
name = utf8;
|
||||
}
|
||||
|
||||
if (!name)
|
||||
name = g_strdup (_("Unnamed"));
|
||||
|
||||
brush = g_object_new (GIMP_TYPE_BRUSH,
|
||||
"name", name,
|
||||
NULL);
|
||||
|
||||
g_free (name);
|
||||
|
||||
brush->mask = temp_buf_new (header.width, header.height, 1, 0, 0, NULL);
|
||||
|
||||
mask = temp_buf_data (brush->mask);
|
||||
size = header.width * header.height * header.bytes;
|
||||
|
||||
switch (header.bytes)
|
||||
{
|
||||
case 1:
|
||||
success = (read (fd, mask, size) == size);
|
||||
break;
|
||||
|
||||
case 2: /* cinepaint brush, 16 bit floats */
|
||||
{
|
||||
guchar buf[8 * 1024];
|
||||
|
||||
for (i = 0; success && i < size;)
|
||||
{
|
||||
gssize bytes = MIN (size - i, sizeof (buf));
|
||||
|
||||
success = (read (fd, buf, bytes) == bytes);
|
||||
|
||||
if (success)
|
||||
{
|
||||
guint16 *b = (guint16 *) buf;
|
||||
|
||||
i += bytes;
|
||||
|
||||
for (; bytes > 0; bytes -= 2, mask++, b++)
|
||||
{
|
||||
union
|
||||
{
|
||||
guint16 u[2];
|
||||
gfloat f;
|
||||
} short_float;
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
short_float.u[0] = 0;
|
||||
short_float.u[1] = GUINT16_FROM_BE (*b);
|
||||
#else
|
||||
short_float.u[0] = GUINT16_FROM_BE (*b);
|
||||
short_float.u[1] = 0;
|
||||
#endif
|
||||
|
||||
*mask = (guchar) (short_float.f * 255.0 + 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
guchar buf[8 * 1024];
|
||||
|
||||
brush->pixmap = temp_buf_new (header.width, header.height,
|
||||
3, 0, 0, NULL);
|
||||
pixmap = temp_buf_data (brush->pixmap);
|
||||
|
||||
for (i = 0; success && i < size;)
|
||||
{
|
||||
gssize bytes = MIN (size - i, sizeof (buf));
|
||||
|
||||
success = (read (fd, buf, bytes) == bytes);
|
||||
|
||||
if (success)
|
||||
{
|
||||
guchar *b = buf;
|
||||
|
||||
i += bytes;
|
||||
|
||||
for (; bytes > 0; bytes -= 4, pixmap += 3, mask++, b += 4)
|
||||
{
|
||||
pixmap[0] = b[0];
|
||||
pixmap[1] = b[1];
|
||||
pixmap[2] = b[2];
|
||||
|
||||
mask[0] = b[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_object_unref (brush);
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"Unsupported brush depth %d\n"
|
||||
"GIMP brushes must be GRAY or RGBA."),
|
||||
gimp_filename_to_utf8 (filename), header.bytes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (! success)
|
||||
{
|
||||
g_object_unref (brush);
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Fatal parse error in brush file '%s': "
|
||||
"File appears truncated."),
|
||||
gimp_filename_to_utf8 (filename));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
brush->spacing = header.spacing;
|
||||
brush->x_axis.x = header.width / 2.0;
|
||||
brush->x_axis.y = 0.0;
|
||||
brush->y_axis.x = 0.0;
|
||||
brush->y_axis.y = header.height / 2.0;
|
||||
|
||||
return brush;
|
||||
}
|
@@ -27,6 +27,7 @@
|
||||
#include "base/pixel-processor.h"
|
||||
#include "base/pixel-region.h"
|
||||
|
||||
#include "gimp-utils.h"
|
||||
#include "gimpchannel.h"
|
||||
#include "gimpchannel-combine.h"
|
||||
|
||||
@@ -130,24 +131,16 @@ gimp_channel_combine_rect (GimpChannel *mask,
|
||||
gint w,
|
||||
gint h)
|
||||
{
|
||||
gint x2, y2;
|
||||
PixelRegion maskPR;
|
||||
guchar color;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (mask));
|
||||
|
||||
y2 = y + h;
|
||||
x2 = x + w;
|
||||
|
||||
x = CLAMP (x, 0, GIMP_ITEM (mask)->width);
|
||||
y = CLAMP (y, 0, GIMP_ITEM (mask)->height);
|
||||
x2 = CLAMP (x2, 0, GIMP_ITEM (mask)->width);
|
||||
y2 = CLAMP (y2, 0, GIMP_ITEM (mask)->height);
|
||||
|
||||
w = x2 - x;
|
||||
h = y2 - y;
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
if (! gimp_rectangle_intersect (x, y, w, h,
|
||||
0, 0,
|
||||
GIMP_ITEM (mask)->width,
|
||||
GIMP_ITEM (mask)->height,
|
||||
&x, &y, &w, &h))
|
||||
return;
|
||||
|
||||
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
|
||||
@@ -225,7 +218,11 @@ gimp_channel_combine_ellipse (GimpChannel *mask,
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (mask));
|
||||
|
||||
if (!w || !h)
|
||||
if (! gimp_rectangle_intersect (x, y, w, h,
|
||||
0, 0,
|
||||
GIMP_ITEM (mask)->width,
|
||||
GIMP_ITEM (mask)->height,
|
||||
NULL, NULL, NULL, NULL))
|
||||
return;
|
||||
|
||||
a = w / 2.0;
|
||||
@@ -489,26 +486,24 @@ gimp_channel_combine_mask (GimpChannel *mask,
|
||||
gint off_y)
|
||||
{
|
||||
PixelRegion srcPR, destPR;
|
||||
gint x1, y1, x2, y2;
|
||||
gint w, h;
|
||||
gint x, y, w, h;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (mask));
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (add_on));
|
||||
|
||||
x1 = CLAMP (off_x, 0, GIMP_ITEM (mask)->width);
|
||||
y1 = CLAMP (off_y, 0, GIMP_ITEM (mask)->height);
|
||||
x2 = CLAMP (off_x + GIMP_ITEM (add_on)->width, 0,
|
||||
GIMP_ITEM (mask)->width);
|
||||
y2 = CLAMP (off_y + GIMP_ITEM (add_on)->height, 0,
|
||||
GIMP_ITEM (mask)->height);
|
||||
|
||||
w = (x2 - x1);
|
||||
h = (y2 - y1);
|
||||
if (! gimp_rectangle_intersect (off_x, off_y,
|
||||
GIMP_ITEM (add_on)->width,
|
||||
GIMP_ITEM (add_on)->height,
|
||||
0, 0,
|
||||
GIMP_ITEM (mask)->width,
|
||||
GIMP_ITEM (mask)->height,
|
||||
&x, &y, &w, &h))
|
||||
return;
|
||||
|
||||
pixel_region_init (&srcPR, GIMP_DRAWABLE (add_on)->tiles,
|
||||
(x1 - off_x), (y1 - off_y), w, h, FALSE);
|
||||
x - off_x, y - off_y, w, h, FALSE);
|
||||
pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles,
|
||||
x1, y1, w, h, TRUE);
|
||||
x, y, w, h, TRUE);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
@@ -538,5 +533,5 @@ gimp_channel_combine_mask (GimpChannel *mask,
|
||||
|
||||
mask->bounds_known = FALSE;
|
||||
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask), x1, y2, w, h);
|
||||
gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h);
|
||||
}
|
||||
|
@@ -1494,6 +1494,9 @@ gimp_channel_new_from_component (GimpImage *gimage,
|
||||
|
||||
g_return_val_if_fail (pixel != -1, NULL);
|
||||
|
||||
gimp_projection_finish_draw (gimage->projection);
|
||||
gimp_projection_flush_now (gimage->projection);
|
||||
|
||||
projection = gimp_projection_get_tiles (gimage->projection);
|
||||
width = tile_manager_width (projection);
|
||||
height = tile_manager_height (projection);
|
||||
|
@@ -44,6 +44,12 @@
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
/* Need this test somewhere, might as well do it here */
|
||||
#ifdef G_OS_WIN32
|
||||
#if GLIB_CHECK_VERSION (2,6,0)
|
||||
#error GIMP 2.2 for Win32 must be compiled against GLib 2.4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -402,18 +408,70 @@ void
|
||||
gimp_data_create_filename (GimpData *data,
|
||||
const gchar *dest_dir)
|
||||
{
|
||||
gchar *safename;
|
||||
gchar *filename;
|
||||
gchar *fullpath;
|
||||
gint i;
|
||||
gint unum = 1;
|
||||
gchar *safename;
|
||||
gchar *filename;
|
||||
gchar *fullpath;
|
||||
gint i;
|
||||
gint unum = 1;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DATA (data));
|
||||
g_return_if_fail (dest_dir != NULL);
|
||||
g_return_if_fail (g_path_is_absolute (dest_dir));
|
||||
|
||||
if (data->internal)
|
||||
return;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
{
|
||||
const gchar *charset;
|
||||
|
||||
filename = g_strdup (gimp_object_get_name (GIMP_OBJECT (data)));
|
||||
|
||||
/* Map illegal characters to '-' while the name is still in UTF-8 */
|
||||
for (i = 0; filename[i]; i++)
|
||||
if (strchr ("<>:\"/\\|", filename[i]) ||
|
||||
g_ascii_iscntrl (filename[i]) ||
|
||||
g_ascii_isspace (filename[i]))
|
||||
filename[i] = '-';
|
||||
|
||||
/* Map also trailing periods to '-' */
|
||||
for (i = strlen (filename) - 1; i >= 0; i--)
|
||||
if (filename[i] == '.')
|
||||
filename[i] = '-';
|
||||
else
|
||||
break;
|
||||
|
||||
/* Next convert to the filename charset. Note that this branch of
|
||||
* GIMP must be compiled against GLib 2.4 and we thus use system
|
||||
* codepage for file names in the GLib API.
|
||||
*/
|
||||
g_get_charset (&charset);
|
||||
safename = g_convert_with_fallback (filename,
|
||||
-1, charset, "UTF-8",
|
||||
"-", NULL, NULL, &error);
|
||||
if (! safename)
|
||||
{
|
||||
g_warning ("gimp_data_create_filename:\n"
|
||||
"g_convert_with_fallback() failed for '%s': %s",
|
||||
filename, error->message);
|
||||
g_free (filename);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
g_free (filename);
|
||||
}
|
||||
#else
|
||||
safename = g_filename_from_utf8 (gimp_object_get_name (GIMP_OBJECT (data)),
|
||||
-1, NULL, NULL, NULL);
|
||||
-1, NULL, NULL, &error);
|
||||
if (! safename)
|
||||
{
|
||||
g_warning ("gimp_data_create_filename:\n"
|
||||
"g_filename_from_utf8() failed for '%s': %s",
|
||||
gimp_object_get_name (GIMP_OBJECT (data)), error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (safename[0] == '.')
|
||||
safename[0] = '-';
|
||||
@@ -421,6 +479,7 @@ gimp_data_create_filename (GimpData *data,
|
||||
for (i = 0; safename[i]; i++)
|
||||
if (safename[i] == G_DIR_SEPARATOR || g_ascii_isspace (safename[i]))
|
||||
safename[i] = '-';
|
||||
#endif
|
||||
|
||||
filename = g_strconcat (safename, gimp_data_get_extension (data), NULL);
|
||||
|
||||
|
@@ -169,8 +169,9 @@ gimp_gradient_load (const gchar *filename,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message (_("Corrupt segment %d in gradient file '%s'."),
|
||||
i, gimp_filename_to_utf8 (filename));
|
||||
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
|
||||
_("Corrupt segment %d in gradient file '%s'."),
|
||||
i, gimp_filename_to_utf8 (filename));
|
||||
g_object_unref (gradient);
|
||||
fclose (file);
|
||||
return NULL;
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-contiguous-region.h"
|
||||
#include "gimppickable.h"
|
||||
#include "gimpprojection.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
@@ -105,9 +106,16 @@ gimp_image_contiguous_region_by_seed (GimpImage *gimage,
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
|
||||
|
||||
if (sample_merged)
|
||||
pickable = GIMP_PICKABLE (gimage->projection);
|
||||
{
|
||||
pickable = GIMP_PICKABLE (gimage->projection);
|
||||
|
||||
gimp_projection_finish_draw (gimage->projection);
|
||||
gimp_projection_flush_now (gimage->projection);
|
||||
}
|
||||
else
|
||||
pickable = GIMP_PICKABLE (drawable);
|
||||
{
|
||||
pickable = GIMP_PICKABLE (drawable);
|
||||
}
|
||||
|
||||
src_type = gimp_pickable_get_image_type (pickable);
|
||||
has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (src_type);
|
||||
@@ -196,9 +204,9 @@ gimp_image_contiguous_region_by_color (GimpImage *gimage,
|
||||
guchar *mask_data;
|
||||
guchar *idata, *mdata;
|
||||
guchar rgb[MAX_CHANNELS];
|
||||
gint has_alpha, indexed;
|
||||
gint has_alpha;
|
||||
gint width, height;
|
||||
gint bytes, color_bytes, alpha;
|
||||
gint bytes;
|
||||
gint i, j;
|
||||
gpointer pr;
|
||||
GimpImageType d_type;
|
||||
@@ -211,14 +219,20 @@ gimp_image_contiguous_region_by_color (GimpImage *gimage,
|
||||
gimp_rgba_get_uchar (color, &col[0], &col[1], &col[2], &col[3]);
|
||||
|
||||
if (sample_merged)
|
||||
pickable = GIMP_PICKABLE (gimage->projection);
|
||||
{
|
||||
pickable = GIMP_PICKABLE (gimage->projection);
|
||||
|
||||
gimp_projection_finish_draw (gimage->projection);
|
||||
gimp_projection_flush_now (gimage->projection);
|
||||
}
|
||||
else
|
||||
pickable = GIMP_PICKABLE (drawable);
|
||||
{
|
||||
pickable = GIMP_PICKABLE (drawable);
|
||||
}
|
||||
|
||||
d_type = gimp_pickable_get_image_type (pickable);
|
||||
bytes = GIMP_IMAGE_TYPE_BYTES (d_type);
|
||||
has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (d_type);
|
||||
indexed = GIMP_IMAGE_TYPE_IS_INDEXED (d_type);
|
||||
|
||||
tiles = gimp_pickable_get_tiles (pickable);
|
||||
width = tile_manager_width (tiles);
|
||||
@@ -242,18 +256,6 @@ gimp_image_contiguous_region_by_color (GimpImage *gimage,
|
||||
select_transparent = FALSE;
|
||||
}
|
||||
|
||||
if (indexed)
|
||||
{
|
||||
/* indexed colors are always RGB or RGBA */
|
||||
color_bytes = has_alpha ? 4 : 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
|
||||
color_bytes = bytes;
|
||||
}
|
||||
|
||||
alpha = bytes - 1;
|
||||
mask = gimp_channel_new_mask (gimage, width, height);
|
||||
|
||||
pixel_region_init (&maskPR, gimp_drawable_data (GIMP_DRAWABLE (mask)),
|
||||
@@ -282,7 +284,7 @@ gimp_image_contiguous_region_by_color (GimpImage *gimage,
|
||||
/* Find how closely the colors match */
|
||||
*mdata++ = pixel_difference (col, rgb,
|
||||
antialias, threshold,
|
||||
color_bytes,
|
||||
has_alpha ? 4 : 3,
|
||||
has_alpha, select_transparent);
|
||||
|
||||
idata += bytes;
|
||||
|
@@ -147,6 +147,7 @@
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimplist.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimplayer-floating-sel.h"
|
||||
#include "gimppalette.h"
|
||||
#include "gimpprogress.h"
|
||||
|
||||
@@ -802,6 +803,9 @@ gimp_image_convert (GimpImage *gimage,
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_CONVERT,
|
||||
undo_desc);
|
||||
|
||||
if (gimp_image_floating_sel (gimage))
|
||||
floating_sel_relax (gimp_image_floating_sel (gimage), TRUE);
|
||||
|
||||
/* Push the image type to the stack */
|
||||
gimp_image_undo_push_image_type (gimage, NULL);
|
||||
|
||||
@@ -1058,6 +1062,9 @@ gimp_image_convert (GimpImage *gimage,
|
||||
if (quantobj)
|
||||
quantobj->delete_func (quantobj);
|
||||
|
||||
if (gimp_image_floating_sel (gimage))
|
||||
floating_sel_rigor (gimp_image_floating_sel (gimage), TRUE);
|
||||
|
||||
gimp_image_undo_group_end (gimage);
|
||||
|
||||
gimp_image_invalidate_layer_previews (gimage);
|
||||
@@ -2202,9 +2209,9 @@ compute_color_gray (QuantizeObj *quantobj,
|
||||
/* Compute representative color for a box, put it in colormap[icolor] */
|
||||
{
|
||||
int i, min, max;
|
||||
long count;
|
||||
long total;
|
||||
long gtotal;
|
||||
guint64 count;
|
||||
guint64 total;
|
||||
guint64 gtotal;
|
||||
|
||||
min = boxp->Rmin;
|
||||
max = boxp->Rmax;
|
||||
@@ -2224,9 +2231,9 @@ compute_color_gray (QuantizeObj *quantobj,
|
||||
|
||||
if (total != 0)
|
||||
{
|
||||
quantobj->cmap[icolor].red = (gtotal + (total >> 1)) / total;
|
||||
quantobj->cmap[icolor].green = quantobj->cmap[icolor].red;
|
||||
quantobj->cmap[icolor].blue = quantobj->cmap[icolor].red;
|
||||
quantobj->cmap[icolor].red =
|
||||
quantobj->cmap[icolor].green =
|
||||
quantobj->cmap[icolor].blue = (gtotal + (total >> 1)) / total;
|
||||
}
|
||||
else /* The only situation where total==0 is if the image was null or
|
||||
* all-transparent. In that case we just put a dummy value in
|
||||
@@ -2755,8 +2762,7 @@ fill_inverse_cmap_gray (QuantizeObj *quantobj,
|
||||
|
||||
for (i = 0; i < quantobj->actual_number_of_colors; i++)
|
||||
{
|
||||
dist = pixel - cmap[i].red;
|
||||
dist *= dist;
|
||||
dist = ABS(pixel - cmap[i].red);
|
||||
|
||||
if (dist < mindist)
|
||||
{
|
||||
@@ -4201,7 +4207,6 @@ initialize_median_cut (GimpImageBaseType type,
|
||||
}
|
||||
|
||||
if (palette_type == GIMP_WEB_PALETTE ||
|
||||
palette_type == GIMP_MONO_PALETTE ||
|
||||
palette_type == GIMP_CUSTOM_PALETTE)
|
||||
{
|
||||
switch (dither_type)
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "gimplayer.h"
|
||||
#include "gimplist.h"
|
||||
#include "gimppickable.h"
|
||||
#include "gimpprojection.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
@@ -291,7 +292,10 @@ gimp_image_crop_auto_shrink (GimpImage *gimage,
|
||||
else
|
||||
{
|
||||
pickable = GIMP_PICKABLE (gimage->projection);
|
||||
}
|
||||
|
||||
gimp_projection_finish_draw (gimage->projection);
|
||||
gimp_projection_flush_now (gimage->projection);
|
||||
}
|
||||
|
||||
type = gimp_pickable_get_image_type (pickable);
|
||||
bytes = GIMP_IMAGE_TYPE_BYTES (type);
|
||||
|
@@ -261,6 +261,9 @@ gimp_image_get_new_preview (GimpViewable *viewable,
|
||||
x2 = CLAMP (x + w, 0, width);
|
||||
y2 = CLAMP (y + h, 0, height);
|
||||
|
||||
if (x2 == x1 || y2 == y1)
|
||||
continue;
|
||||
|
||||
src1PR.bytes = comp->bytes;
|
||||
src1PR.x = x1;
|
||||
src1PR.y = y1;
|
||||
|
@@ -1,191 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpchannel.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-qmask.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimplayer-floating-sel.h"
|
||||
#include "gimpselection.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
void
|
||||
gimp_image_set_qmask_state (GimpImage *gimage,
|
||||
gboolean qmask_state)
|
||||
{
|
||||
GimpChannel *selection;
|
||||
GimpChannel *mask;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
if (qmask_state == gimage->qmask_state)
|
||||
return;
|
||||
|
||||
/* set image->qmask_state early so we can return early when
|
||||
* being called recursively
|
||||
*/
|
||||
gimage->qmask_state = qmask_state ? TRUE : FALSE;
|
||||
|
||||
selection = gimp_image_get_mask (gimage);
|
||||
mask = gimp_image_get_qmask (gimage);
|
||||
|
||||
if (qmask_state)
|
||||
{
|
||||
if (! mask)
|
||||
{
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
|
||||
_("Enable Quick Mask"));
|
||||
|
||||
if (gimp_channel_is_empty (selection))
|
||||
{
|
||||
/* if no selection */
|
||||
|
||||
GimpLayer *floating_sel = gimp_image_floating_sel (gimage);
|
||||
|
||||
if (floating_sel)
|
||||
floating_sel_to_layer (floating_sel);
|
||||
|
||||
mask = gimp_channel_new (gimage,
|
||||
gimage->width,
|
||||
gimage->height,
|
||||
GIMP_IMAGE_QMASK_NAME,
|
||||
&gimage->qmask_color);
|
||||
|
||||
/* Clear the mask */
|
||||
gimp_channel_clear (mask, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if selection */
|
||||
|
||||
mask = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (selection),
|
||||
GIMP_TYPE_CHANNEL,
|
||||
FALSE));
|
||||
|
||||
/* Clear the selection */
|
||||
gimp_channel_clear (selection, NULL, TRUE);
|
||||
|
||||
gimp_channel_set_color (mask, &gimage->qmask_color, FALSE);
|
||||
gimp_item_rename (GIMP_ITEM (mask), GIMP_IMAGE_QMASK_NAME);
|
||||
}
|
||||
|
||||
if (gimage->qmask_inverted)
|
||||
gimp_channel_invert (mask, FALSE);
|
||||
|
||||
gimp_image_add_channel (gimage, mask, 0);
|
||||
|
||||
gimp_image_undo_group_end (gimage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mask)
|
||||
{
|
||||
GimpLayer *floating_sel = gimp_image_floating_sel (gimage);
|
||||
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_QMASK,
|
||||
_("Disable Quick Mask"));
|
||||
|
||||
if (gimage->qmask_inverted)
|
||||
gimp_channel_invert (mask, TRUE);
|
||||
|
||||
if (floating_sel && floating_sel->fs.drawable == GIMP_DRAWABLE (mask))
|
||||
floating_sel_anchor (floating_sel);
|
||||
|
||||
gimp_selection_load (gimp_image_get_mask (gimage), mask);
|
||||
gimp_image_remove_channel (gimage, mask);
|
||||
|
||||
gimp_image_undo_group_end (gimage);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_image_qmask_changed (gimage);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_image_get_qmask_state (const GimpImage *gimage)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
return gimage->qmask_state;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_set_qmask_color (GimpImage *gimage,
|
||||
const GimpRGB *color)
|
||||
{
|
||||
GimpChannel *qmask;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (color != NULL);
|
||||
|
||||
gimage->qmask_color = *color;
|
||||
|
||||
qmask = gimp_image_get_qmask (gimage);
|
||||
if (qmask)
|
||||
gimp_channel_set_color (qmask, color, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_get_qmask_color (const GimpImage *gimage,
|
||||
GimpRGB *color)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (color != NULL);
|
||||
|
||||
*color = gimage->qmask_color;
|
||||
}
|
||||
|
||||
GimpChannel *
|
||||
gimp_image_get_qmask (const GimpImage *gimage)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
|
||||
|
||||
return gimp_image_get_channel_by_name (gimage, GIMP_IMAGE_QMASK_NAME);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_qmask_invert (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
if (gimage->qmask_state)
|
||||
{
|
||||
GimpChannel *qmask = gimp_image_get_qmask (gimage);
|
||||
|
||||
if (qmask)
|
||||
gimp_channel_invert (qmask, TRUE);
|
||||
}
|
||||
|
||||
gimage->qmask_inverted = ! gimage->qmask_inverted;
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_IMAGE_QMASK_H__
|
||||
#define __GIMP_IMAGE_QMASK_H__
|
||||
|
||||
|
||||
/* don't change this string, it's used to identify the Quick Mask
|
||||
* when opening files.
|
||||
*/
|
||||
#define GIMP_IMAGE_QMASK_NAME "Qmask"
|
||||
|
||||
|
||||
void gimp_image_set_qmask_state (GimpImage *gimage,
|
||||
gboolean qmask_state);
|
||||
gboolean gimp_image_get_qmask_state (const GimpImage *gimage);
|
||||
|
||||
void gimp_image_set_qmask_color (GimpImage *gimage,
|
||||
const GimpRGB *color);
|
||||
void gimp_image_get_qmask_color (const GimpImage *gimage,
|
||||
GimpRGB *color);
|
||||
|
||||
GimpChannel * gimp_image_get_qmask (const GimpImage *gimage);
|
||||
|
||||
void gimp_image_qmask_invert (GimpImage *gimage);
|
||||
|
||||
|
||||
#endif /* __GIMP_IMAGE_QMASK_H__ */
|
@@ -1023,11 +1023,13 @@ gimp_image_real_colormap_changed (GimpImage *gimage,
|
||||
{
|
||||
if (gimp_image_base_type (gimage) == GIMP_INDEXED)
|
||||
{
|
||||
gimp_image_color_hash_invalidate (gimage, color_index);
|
||||
|
||||
/* A colormap alteration affects the whole image */
|
||||
gimp_image_update (gimage, 0, 0, gimage->width, gimage->height);
|
||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
|
||||
|
||||
gimp_image_color_hash_invalidate (gimage, color_index);
|
||||
gimp_image_invalidate_layer_previews (gimage);
|
||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gimage));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2729,12 +2731,22 @@ gimp_image_remove_layer (GimpImage *gimage,
|
||||
GimpLayer *active_layer;
|
||||
gint index;
|
||||
gboolean old_has_alpha;
|
||||
gboolean undo_group = FALSE;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (GIMP_IS_LAYER (layer));
|
||||
g_return_if_fail (gimp_container_have (gimage->layers,
|
||||
GIMP_OBJECT (layer)));
|
||||
|
||||
if (gimp_drawable_has_floating_sel (GIMP_DRAWABLE (layer)))
|
||||
{
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
|
||||
_("Remove Layer"));
|
||||
undo_group = TRUE;
|
||||
|
||||
floating_sel_remove (gimp_image_floating_sel (gimage));
|
||||
}
|
||||
|
||||
active_layer = gimp_image_get_active_layer (gimage);
|
||||
|
||||
index = gimp_container_get_child_index (gimage->layers,
|
||||
@@ -2797,6 +2809,9 @@ gimp_image_remove_layer (GimpImage *gimage,
|
||||
|
||||
if (old_has_alpha != gimp_image_has_alpha (gimage))
|
||||
gimp_image_alpha_changed (gimage);
|
||||
|
||||
if (undo_group)
|
||||
gimp_image_undo_group_end (gimage);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -3024,12 +3039,22 @@ gimp_image_remove_channel (GimpImage *gimage,
|
||||
{
|
||||
GimpChannel *active_channel;
|
||||
gint index;
|
||||
gboolean undo_group = FALSE;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
||||
g_return_if_fail (gimp_container_have (gimage->channels,
|
||||
GIMP_OBJECT (channel)));
|
||||
|
||||
if (gimp_drawable_has_floating_sel (GIMP_DRAWABLE (channel)))
|
||||
{
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
|
||||
_("Remove Channel"));
|
||||
undo_group = TRUE;
|
||||
|
||||
floating_sel_remove (gimp_image_floating_sel (gimage));
|
||||
}
|
||||
|
||||
active_channel = gimp_image_get_active_channel (gimage);
|
||||
|
||||
index = gimp_container_get_child_index (gimage->channels,
|
||||
@@ -3063,6 +3088,9 @@ gimp_image_remove_channel (GimpImage *gimage,
|
||||
}
|
||||
|
||||
g_object_unref (channel);
|
||||
|
||||
if (undo_group)
|
||||
gimp_image_undo_group_end (gimage);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@@ -673,6 +673,9 @@ gimp_imagefile_load_thumb (GimpImagefile *imagefile,
|
||||
if (gimp_thumbnail_peek_thumb (thumbnail, size) < GIMP_THUMB_STATE_EXISTS)
|
||||
return NULL;
|
||||
|
||||
if (thumbnail->image_state == GIMP_THUMB_STATE_NOT_FOUND)
|
||||
return NULL;
|
||||
|
||||
pixbuf = gimp_thumbnail_load_thumb (thumbnail, size, &error);
|
||||
|
||||
if (! pixbuf)
|
||||
|
@@ -66,10 +66,8 @@ static gint64 gimp_item_get_memsize (GimpObject *object,
|
||||
static GimpItem * gimp_item_real_duplicate (GimpItem *item,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
static GimpItem * gimp_item_real_convert_from (GimpItem *item,
|
||||
GimpImage *dest_image,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
static void gimp_item_real_convert (GimpItem *item,
|
||||
GimpImage *dest_image);
|
||||
static gboolean gimp_item_real_rename (GimpItem *item,
|
||||
const gchar *new_name,
|
||||
const gchar *undo_desc);
|
||||
@@ -176,8 +174,7 @@ gimp_item_class_init (GimpItemClass *klass)
|
||||
|
||||
klass->is_attached = NULL;
|
||||
klass->duplicate = gimp_item_real_duplicate;
|
||||
klass->convert_from = gimp_item_real_convert_from;
|
||||
klass->convert_to = NULL;
|
||||
klass->convert = gimp_item_real_convert;
|
||||
klass->rename = gimp_item_real_rename;
|
||||
klass->translate = gimp_item_real_translate;
|
||||
klass->scale = gimp_item_real_scale;
|
||||
@@ -306,13 +303,11 @@ gimp_item_real_duplicate (GimpItem *item,
|
||||
return new_item;
|
||||
}
|
||||
|
||||
static GimpItem *
|
||||
gimp_item_real_convert_from (GimpItem *item,
|
||||
GimpImage *dest_image,
|
||||
GType new_type,
|
||||
gboolean add_alpha)
|
||||
static void
|
||||
gimp_item_real_convert (GimpItem *item,
|
||||
GimpImage *dest_image)
|
||||
{
|
||||
return gimp_item_duplicate (item, new_type, add_alpha);
|
||||
gimp_item_set_image (item, dest_image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -536,17 +531,10 @@ gimp_item_convert (GimpItem *item,
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
|
||||
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_ITEM), NULL);
|
||||
|
||||
new_item = GIMP_ITEM_GET_CLASS (item)->convert_from (item, dest_image,
|
||||
new_type, add_alpha);
|
||||
new_item = gimp_item_duplicate (item, new_type, add_alpha);
|
||||
|
||||
if (new_item)
|
||||
{
|
||||
if (dest_image != item->gimage)
|
||||
gimp_item_set_image (new_item, dest_image);
|
||||
|
||||
if (GIMP_ITEM_GET_CLASS (new_item)->convert_to)
|
||||
GIMP_ITEM_GET_CLASS (new_item)->convert_to (new_item, item);
|
||||
}
|
||||
GIMP_ITEM_GET_CLASS (new_item)->convert (new_item, dest_image);
|
||||
|
||||
return new_item;
|
||||
}
|
||||
|
@@ -68,12 +68,8 @@ struct _GimpItemClass
|
||||
GimpItem * (* duplicate) (GimpItem *item,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
GimpItem * (* convert_from) (GimpItem *item,
|
||||
GimpImage *dest_image,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
void (* convert_to) (GimpItem *item,
|
||||
GimpItem *src_item);
|
||||
void (* convert) (GimpItem *item,
|
||||
GimpImage *dest_image);
|
||||
gboolean (* rename) (GimpItem *item,
|
||||
const gchar *new_name,
|
||||
const gchar *undo_desc);
|
||||
|
@@ -79,8 +79,8 @@ static gboolean gimp_layer_is_attached (GimpItem *item);
|
||||
static GimpItem * gimp_layer_duplicate (GimpItem *item,
|
||||
GType new_type,
|
||||
gboolean add_alpha);
|
||||
static void gimp_layer_convert_to (GimpItem *item,
|
||||
GimpItem *src_item);
|
||||
static void gimp_layer_convert (GimpItem *item,
|
||||
GimpImage *dest_image);
|
||||
static gboolean gimp_layer_rename (GimpItem *item,
|
||||
const gchar *new_name,
|
||||
const gchar *undo_desc);
|
||||
@@ -239,7 +239,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
|
||||
item_class->removed = gimp_layer_removed;
|
||||
item_class->is_attached = gimp_layer_is_attached;
|
||||
item_class->duplicate = gimp_layer_duplicate;
|
||||
item_class->convert_to = gimp_layer_convert_to;
|
||||
item_class->convert = gimp_layer_convert;
|
||||
item_class->rename = gimp_layer_rename;
|
||||
item_class->translate = gimp_layer_translate;
|
||||
item_class->scale = gimp_layer_scale;
|
||||
@@ -487,19 +487,16 @@ gimp_layer_duplicate (GimpItem *item,
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_layer_convert_to (GimpItem *item,
|
||||
GimpItem *src_item)
|
||||
gimp_layer_convert (GimpItem *item,
|
||||
GimpImage *dest_image)
|
||||
{
|
||||
GimpLayer *layer = GIMP_LAYER (item);
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
||||
GimpImageBaseType old_base_type;
|
||||
GimpImageBaseType new_base_type;
|
||||
|
||||
if (GIMP_ITEM_CLASS (parent_class)->convert_to)
|
||||
GIMP_ITEM_CLASS (parent_class)->convert_to (item, src_item);
|
||||
|
||||
old_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));
|
||||
new_base_type = gimp_image_base_type (gimp_item_get_image (item));
|
||||
new_base_type = gimp_image_base_type (dest_image);
|
||||
|
||||
if (old_base_type != new_base_type)
|
||||
{
|
||||
@@ -545,7 +542,7 @@ gimp_layer_convert_to (GimpItem *item,
|
||||
gimp_item_height (item),
|
||||
TRUE);
|
||||
|
||||
gimp_layer_transform_color (gimp_item_get_image (item),
|
||||
gimp_layer_transform_color (dest_image,
|
||||
&newPR, &layerPR,
|
||||
NULL,
|
||||
old_base_type);
|
||||
@@ -560,8 +557,10 @@ gimp_layer_convert_to (GimpItem *item,
|
||||
tile_manager_unref (new_tiles);
|
||||
}
|
||||
|
||||
if (layer->mask && item->gimage != src_item->gimage)
|
||||
gimp_item_set_image (GIMP_ITEM (layer->mask), item->gimage);
|
||||
if (layer->mask)
|
||||
gimp_item_set_image (GIMP_ITEM (layer->mask), dest_image);
|
||||
|
||||
GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -290,6 +290,9 @@ gimp_palette_import_from_image (GimpImage *gimage,
|
||||
g_return_val_if_fail (n_colors > 1, NULL);
|
||||
g_return_val_if_fail (threshold > 0, NULL);
|
||||
|
||||
gimp_projection_finish_draw (gimage->projection);
|
||||
gimp_projection_flush_now (gimage->projection);
|
||||
|
||||
/* Get the image information */
|
||||
d_type = gimp_projection_get_image_type (gimage->projection);
|
||||
bytes = gimp_projection_get_bytes (gimage->projection);
|
||||
|
@@ -261,9 +261,10 @@ gimp_parasite_list_deserialize (GimpConfig *list,
|
||||
case G_TOKEN_SYMBOL:
|
||||
if (scanner->value.v_symbol == parasite_symbol)
|
||||
{
|
||||
gchar *parasite_name = NULL;
|
||||
gint parasite_flags = 0;
|
||||
gchar *parasite_data = NULL;
|
||||
gchar *parasite_name = NULL;
|
||||
gint parasite_flags = 0;
|
||||
guint8 *parasite_data = NULL;
|
||||
gint parasite_data_size = 0;
|
||||
GimpParasite *parasite;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
@@ -282,17 +283,43 @@ gimp_parasite_list_deserialize (GimpConfig *list,
|
||||
if (! gimp_scanner_parse_int (scanner, ¶site_flags))
|
||||
goto cleanup;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
token = G_TOKEN_INT;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
goto cleanup;
|
||||
{
|
||||
/* old format -- plain string */
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, ¶site_data))
|
||||
goto cleanup;
|
||||
gchar *str;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
|
||||
goto cleanup;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &str))
|
||||
goto cleanup;
|
||||
|
||||
parasite_data_size = strlen (str);
|
||||
parasite_data = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new format -- properly encoded binary data */
|
||||
|
||||
if (! gimp_scanner_parse_int (scanner, ¶site_data_size))
|
||||
goto cleanup;
|
||||
|
||||
token = G_TOKEN_STRING;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
goto cleanup;
|
||||
|
||||
if (! gimp_scanner_parse_data (scanner, parasite_data_size,
|
||||
¶site_data))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
parasite = gimp_parasite_new (parasite_name,
|
||||
parasite_flags,
|
||||
strlen (parasite_data),
|
||||
parasite_data_size,
|
||||
parasite_data);
|
||||
gimp_parasite_list_add (GIMP_PARASITE_LIST (list),
|
||||
parasite); /* adds a copy */
|
||||
@@ -301,7 +328,7 @@ gimp_parasite_list_deserialize (GimpConfig *list,
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
|
||||
g_free (parasite_data);
|
||||
cleanup:
|
||||
cleanup:
|
||||
g_free (parasite_name);
|
||||
}
|
||||
break;
|
||||
@@ -442,51 +469,19 @@ parasite_serialize (const gchar *key,
|
||||
GimpParasite *parasite,
|
||||
GimpConfigWriter *writer)
|
||||
{
|
||||
GString *str;
|
||||
const gchar *data;
|
||||
guint32 len;
|
||||
|
||||
if (! gimp_parasite_is_persistent (parasite))
|
||||
return;
|
||||
|
||||
gimp_config_writer_open (writer, parasite_symbol);
|
||||
|
||||
str = g_string_sized_new (64);
|
||||
gimp_config_writer_printf (writer, "\"%s\" %lu %lu",
|
||||
gimp_parasite_name (parasite),
|
||||
gimp_parasite_flags (parasite),
|
||||
gimp_parasite_data_size (parasite));
|
||||
|
||||
g_string_printf (str, "\"%s\" %lu \"",
|
||||
gimp_parasite_name (parasite),
|
||||
gimp_parasite_flags (parasite));
|
||||
|
||||
/* the current methodology is: never move the parasiterc from one
|
||||
* system to another. If you want to do this you should probably
|
||||
* write out parasites which contain any non-alphanumeric(+some)
|
||||
* characters as \xHH sequences altogether.
|
||||
*/
|
||||
|
||||
data = (const gchar *) gimp_parasite_data (parasite);
|
||||
|
||||
for (len = gimp_parasite_data_size (parasite); len > 0; len--, data++)
|
||||
{
|
||||
switch (*data)
|
||||
{
|
||||
case '\\': g_string_append_len (str, "\\\\", 2); break;
|
||||
case '\0': g_string_append_len (str, "\\0" , 2); break;
|
||||
case '"' : g_string_append_len (str, "\\\"", 2); break;
|
||||
/* disabled, not portable! */
|
||||
/* case '\n': fputs ("\\n", fp); break;*/
|
||||
/* case '\r': fputs ("\\r", fp); break;*/
|
||||
case 26 : g_string_append_len (str, "\\z", 2); break;
|
||||
|
||||
default : g_string_append_c (str, *data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_append (str, "\"");
|
||||
|
||||
gimp_config_writer_print (writer, str->str, str->len);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
gimp_config_writer_data (writer,
|
||||
gimp_parasite_data_size (parasite),
|
||||
gimp_parasite_data (parasite));
|
||||
|
||||
gimp_config_writer_close (writer);
|
||||
gimp_config_writer_linefeed (writer);
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "config/gimpcoreconfig.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimptoolinfo.h"
|
||||
|
||||
@@ -285,6 +286,11 @@ gimp_stroke_desc_new (Gimp *gimp,
|
||||
|
||||
if (tool_info)
|
||||
paint_info = tool_info->paint_info;
|
||||
|
||||
if (! paint_info)
|
||||
paint_info = (GimpPaintInfo *)
|
||||
gimp_container_get_child_by_name (gimp->paint_info_list,
|
||||
"GimpPaintbrush");
|
||||
}
|
||||
|
||||
desc = g_object_new (GIMP_TYPE_STROKE_DESC,
|
||||
|
@@ -366,7 +366,9 @@ static gboolean
|
||||
convert_dialog_palette_filter (const GimpObject *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
return GIMP_PALETTE (object)->n_colors <= 256;
|
||||
GimpPalette *palette = GIMP_PALETTE (object);
|
||||
|
||||
return palette->n_colors > 0 && palette->n_colors <= 256;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -117,7 +117,7 @@ file_open_dialog_response (GtkWidget *open_dialog,
|
||||
|
||||
for (list = uris; list; list = g_slist_next (list))
|
||||
{
|
||||
gchar *filename = g_filename_from_uri (list->data, NULL, NULL);
|
||||
gchar *filename = file_utils_filename_from_uri (list->data);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
|
@@ -158,14 +158,16 @@ file_open_location_response (GtkDialog *dialog,
|
||||
GimpImage *image;
|
||||
gchar *uri;
|
||||
gchar *filename;
|
||||
gchar *hostname;
|
||||
GError *error = NULL;
|
||||
GimpPDBStatusType status;
|
||||
|
||||
filename = g_filename_from_uri (text, NULL, NULL);
|
||||
filename = g_filename_from_uri (text, &hostname, NULL);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
uri = g_filename_to_uri (filename, NULL, NULL);
|
||||
uri = g_filename_to_uri (filename, hostname, NULL);
|
||||
g_free (hostname);
|
||||
g_free (filename);
|
||||
}
|
||||
else
|
||||
|
@@ -68,7 +68,8 @@ static gboolean file_save_dialog_save_image (GtkWidget *save_dialog,
|
||||
GtkWidget *
|
||||
file_save_dialog_new (Gimp *gimp)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *dialog;
|
||||
const gchar *uri;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
|
||||
@@ -78,6 +79,26 @@ file_save_dialog_new (Gimp *gimp)
|
||||
GTK_STOCK_SAVE,
|
||||
GIMP_HELP_FILE_SAVE);
|
||||
|
||||
uri = g_object_get_data (G_OBJECT (gimp), "gimp-file-save-last-uri");
|
||||
|
||||
if (uri)
|
||||
{
|
||||
gchar *folder_uri = g_path_get_dirname (uri);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#warning: FIXME: should use set_uri() but idle stuff in the file chooser seems to override set_current_name() when called immediately after set_uri()
|
||||
#endif
|
||||
|
||||
if (folder_uri)
|
||||
{
|
||||
gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
|
||||
folder_uri);
|
||||
g_free (folder_uri);
|
||||
}
|
||||
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "");
|
||||
}
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (file_save_dialog_response),
|
||||
gimp);
|
||||
@@ -95,7 +116,6 @@ file_save_dialog_response (GtkWidget *save_dialog,
|
||||
{
|
||||
GimpFileDialog *dialog = GIMP_FILE_DIALOG (save_dialog);
|
||||
gchar *uri;
|
||||
gchar *filename;
|
||||
|
||||
if (response_id != GTK_RESPONSE_OK)
|
||||
{
|
||||
@@ -107,31 +127,46 @@ file_save_dialog_response (GtkWidget *save_dialog,
|
||||
|
||||
uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
if (uri && strlen (uri))
|
||||
{
|
||||
file_save_overwrite (save_dialog, uri, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_file_dialog_set_sensitive (dialog, FALSE);
|
||||
gchar *filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (file_save_dialog_save_image (save_dialog,
|
||||
dialog->gimage,
|
||||
uri,
|
||||
uri,
|
||||
dialog->file_proc,
|
||||
dialog->save_a_copy))
|
||||
g_return_if_fail (filename != NULL);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
gtk_widget_hide (save_dialog);
|
||||
file_save_overwrite (save_dialog, uri, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
gulong handler_id;
|
||||
|
||||
gimp_file_dialog_set_sensitive (dialog, FALSE);
|
||||
handler_id = g_signal_connect (dialog, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed),
|
||||
&dialog);
|
||||
|
||||
if (file_save_dialog_save_image (save_dialog,
|
||||
dialog->gimage,
|
||||
uri,
|
||||
uri,
|
||||
dialog->file_proc,
|
||||
dialog->save_a_copy))
|
||||
{
|
||||
if (dialog)
|
||||
gtk_widget_hide (save_dialog);
|
||||
}
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
gimp_file_dialog_set_sensitive (dialog, TRUE);
|
||||
g_signal_handler_disconnect (dialog, handler_id);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_file_dialog_set_sensitive (dialog, TRUE);
|
||||
g_free (filename);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
typedef struct _OverwriteData OverwriteData;
|
||||
@@ -156,15 +191,14 @@ file_save_overwrite (GtkWidget *save_dialog,
|
||||
overwrite_data->uri = g_strdup (uri);
|
||||
overwrite_data->raw_filename = g_strdup (raw_filename);
|
||||
|
||||
dialog =
|
||||
gimp_message_dialog_new (_("File exists"), GIMP_STOCK_WARNING,
|
||||
save_dialog, 0,
|
||||
gimp_standard_help_func, NULL,
|
||||
dialog = gimp_message_dialog_new (_("File exists"), GIMP_STOCK_WARNING,
|
||||
save_dialog, GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
gimp_standard_help_func, NULL,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
_("_Replace"), GTK_RESPONSE_OK,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
_("_Replace"), GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
NULL);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (file_save_overwrite_response),
|
||||
@@ -231,6 +265,8 @@ file_save_dialog_save_image (GtkWidget *save_dialog,
|
||||
GimpPDBStatusType status;
|
||||
GError *error = NULL;
|
||||
|
||||
g_object_ref (gimage);
|
||||
|
||||
status = file_save_as (gimage,
|
||||
gimp_get_user_context (gimage->gimp),
|
||||
GIMP_PROGRESS (save_dialog),
|
||||
@@ -241,6 +277,12 @@ file_save_dialog_save_image (GtkWidget *save_dialog,
|
||||
save_a_copy,
|
||||
&error);
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
g_object_set_data_full (G_OBJECT (gimage->gimp), "gimp-file-save-last-uri",
|
||||
g_strdup (uri), (GDestroyNotify) g_free);
|
||||
|
||||
g_object_unref (gimage);
|
||||
|
||||
if (status != GIMP_PDB_SUCCESS &&
|
||||
status != GIMP_PDB_CANCEL)
|
||||
{
|
||||
|
@@ -89,7 +89,7 @@ image_scale_dialog_new (GimpImage *image,
|
||||
dialog->context = context;
|
||||
dialog->dialog = scale_dialog_new (GIMP_VIEWABLE (display->gimage),
|
||||
_("Scale Image"), "gimp-image-scale",
|
||||
display->shell,
|
||||
parent,
|
||||
gimp_standard_help_func,
|
||||
GIMP_HELP_IMAGE_SCALE,
|
||||
GIMP_DISPLAY_SHELL (display->shell)->unit,
|
||||
|
@@ -56,6 +56,8 @@ static void info_dialog_field_new (InfoDialog *idialog,
|
||||
GCallback callback,
|
||||
gpointer callback_data);
|
||||
static void info_dialog_update_field (InfoField *info_field);
|
||||
static void info_dialog_field_free (gpointer data,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
/* public functions */
|
||||
@@ -92,12 +94,24 @@ info_dialog_notebook_new (GimpViewable *viewable,
|
||||
help_func, help_data, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
info_dialog_field_free (gpointer data,
|
||||
gpointer user_data)
|
||||
{
|
||||
InfoField *field = data;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (field->obj,
|
||||
field->callback,
|
||||
field->callback_data);
|
||||
g_free (field);
|
||||
}
|
||||
|
||||
void
|
||||
info_dialog_free (InfoDialog *idialog)
|
||||
{
|
||||
g_return_if_fail (idialog != NULL);
|
||||
|
||||
g_slist_foreach (idialog->field_list, (GFunc) g_free, NULL);
|
||||
g_slist_foreach (idialog->field_list, (GFunc) info_dialog_field_free, NULL);
|
||||
g_slist_free (idialog->field_list);
|
||||
|
||||
gtk_widget_destroy (idialog->shell);
|
||||
|
@@ -103,8 +103,8 @@ print_size_dialog_new (GimpImage *image,
|
||||
parent,
|
||||
help_func, help_id,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
@@ -298,8 +298,8 @@ print_size_dialog_response (GtkWidget *dialog,
|
||||
case GTK_RESPONSE_OK:
|
||||
private->callback (dialog,
|
||||
private->image,
|
||||
gimp_size_entry_get_value (entry, 0),
|
||||
gimp_size_entry_get_value (entry, 1),
|
||||
gimp_size_entry_get_refval (entry, 0),
|
||||
gimp_size_entry_get_refval (entry, 1),
|
||||
gimp_size_entry_get_unit (entry),
|
||||
private->user_data);
|
||||
break;
|
||||
|
@@ -135,8 +135,8 @@ resize_dialog_new (GimpViewable *viewable,
|
||||
parent,
|
||||
help_func, help_id,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESIZE, GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
@@ -253,7 +253,8 @@ resize_dialog_new (GimpViewable *viewable,
|
||||
gimp_viewable_get_preview_size (viewable, 200, FALSE, TRUE, &width, &height);
|
||||
pixbuf = gimp_viewable_get_pixbuf (viewable, width, height);
|
||||
|
||||
gimp_offset_area_set_pixbuf (GIMP_OFFSET_AREA (private->area), pixbuf);
|
||||
if (pixbuf)
|
||||
gimp_offset_area_set_pixbuf (GIMP_OFFSET_AREA (private->area), pixbuf);
|
||||
|
||||
g_signal_connect (private->area, "offsets_changed",
|
||||
G_CALLBACK (offsets_changed),
|
||||
@@ -307,9 +308,15 @@ resize_dialog_reset (ResizeDialog *private)
|
||||
{
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", FALSE,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"width", private->old_width,
|
||||
"height", private->old_height,
|
||||
"unit", private->old_unit,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
@@ -116,8 +116,8 @@ scale_dialog_new (GimpViewable *viewable,
|
||||
parent,
|
||||
help_func, help_id,
|
||||
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GIMP_STOCK_SCALE, GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
@@ -279,9 +279,15 @@ scale_dialog_reset (ScaleDialog *private)
|
||||
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", FALSE,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"width", width,
|
||||
"height", height,
|
||||
"unit", private->unit,
|
||||
NULL);
|
||||
|
||||
g_object_set (private->box,
|
||||
"keep-aspect", TRUE,
|
||||
"xresolution", xres,
|
||||
"yresolution", yres,
|
||||
|
@@ -135,10 +135,10 @@ stroke_dialog_new (GimpItem *item,
|
||||
libart_radio = g_object_ref (group->next->data);
|
||||
gtk_container_remove (GTK_CONTAINER (radio_box), libart_radio);
|
||||
|
||||
paint_radio = g_object_ref (group->data);
|
||||
paint_radio = g_object_ref (group->data);
|
||||
gtk_container_remove (GTK_CONTAINER (radio_box), paint_radio);
|
||||
|
||||
gtk_widget_destroy (radio_box);
|
||||
gtk_object_sink (GTK_OBJECT (radio_box));
|
||||
|
||||
{
|
||||
PangoFontDescription *font_desc;
|
||||
|
@@ -637,8 +637,6 @@ user_install_dialog_run (const gchar *alternate_system_gimprc,
|
||||
gdk_color_parse ("white", &white_color);
|
||||
gdk_color_parse ("dark orange", &title_color);
|
||||
|
||||
gtk_widget_realize (dialog);
|
||||
|
||||
/* B/W Style for the page contents */
|
||||
page_style = gtk_widget_get_modifier_style (dialog);
|
||||
g_object_ref (page_style);
|
||||
@@ -1294,7 +1292,7 @@ user_install_migrate_files (const gchar *oldgimp,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gimp_templates_migrate ();
|
||||
gimp_templates_migrate (oldgimp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -98,7 +98,7 @@ gimp_display_disconnect (GimpDisplay *gdisp)
|
||||
#endif
|
||||
|
||||
/* set gdisp->gimage to NULL before unrefing because there may be code
|
||||
* that listenes for image removals and then iterates the display list
|
||||
* that listens for image removals and then iterates the display list
|
||||
* to find a valid display.
|
||||
*/
|
||||
gimage = gdisp->gimage;
|
||||
|
@@ -436,6 +436,8 @@ void
|
||||
gimp_display_reconnect (GimpDisplay *gdisp,
|
||||
GimpImage *gimage)
|
||||
{
|
||||
GimpImage *old_image;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY (gdisp));
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
@@ -444,10 +446,13 @@ gimp_display_reconnect (GimpDisplay *gdisp,
|
||||
|
||||
gimp_display_shell_disconnect (GIMP_DISPLAY_SHELL (gdisp->shell));
|
||||
|
||||
gimp_display_disconnect (gdisp);
|
||||
old_image = g_object_ref (gdisp->gimage);
|
||||
|
||||
gimp_display_disconnect (gdisp);
|
||||
gimp_display_connect (gdisp, gimage);
|
||||
|
||||
g_object_unref (old_image);
|
||||
|
||||
gimp_display_shell_reconnect (GIMP_DISPLAY_SHELL (gdisp->shell));
|
||||
}
|
||||
|
||||
|
@@ -106,7 +106,7 @@ static void gimp_display_shell_get_device_state (GimpDisplayShell *shell,
|
||||
static GdkModifierType
|
||||
gimp_display_shell_key_to_state (gint key);
|
||||
|
||||
GdkEvent * gimp_display_shell_compress_motion (GimpDisplayShell *shell);
|
||||
static GdkEvent * gimp_display_shell_compress_motion (GimpDisplayShell *shell);
|
||||
|
||||
|
||||
/* public functions */
|
||||
@@ -785,6 +785,13 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
case 1:
|
||||
state &= ~GDK_BUTTON1_MASK;
|
||||
|
||||
if (! shell->space_pressed && ! shell->space_release_pending)
|
||||
gdk_display_keyboard_ungrab (gdk_display, time);
|
||||
|
||||
gdk_display_pointer_ungrab (gdk_display, time);
|
||||
|
||||
gtk_grab_add (canvas);
|
||||
|
||||
if (active_tool &&
|
||||
(! gimp_image_is_empty (gimage) ||
|
||||
gimp_tool_control_handles_empty_image (active_tool->control)))
|
||||
@@ -808,10 +815,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
&image_coords, state,
|
||||
gdisp);
|
||||
|
||||
if (! shell->space_pressed && ! shell->space_release_pending)
|
||||
gdk_display_keyboard_ungrab (gdk_display, time);
|
||||
|
||||
gdk_display_pointer_ungrab (gdk_display, time);
|
||||
gtk_grab_remove (canvas);
|
||||
|
||||
if (shell->space_release_pending)
|
||||
{
|
||||
@@ -1064,8 +1068,19 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
&device_coords);
|
||||
|
||||
if (device_coords.x == mevent->x &&
|
||||
device_coords.y == mevent->y)
|
||||
{
|
||||
device_coords.y == mevent->y
|
||||
#ifdef G_OS_WIN32
|
||||
/* The Win32 backend for GDK just returns the
|
||||
* coordinates from the last motion/button event
|
||||
* for extended input devices, so if the event is
|
||||
* put back in the queue, this will keep scrolling
|
||||
* until the edge of the image is reached (bug
|
||||
* #167960) */
|
||||
&& mevent->device == gdk_display_get_core_pointer (
|
||||
gdk_display_get_default ())
|
||||
#endif /* G_OS_WIN32 */
|
||||
)
|
||||
{
|
||||
/* Put this event back on the queue
|
||||
* so it keeps scrolling
|
||||
*/
|
||||
@@ -1225,18 +1240,9 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
|
||||
case GDK_Tab:
|
||||
case GDK_ISO_Left_Tab:
|
||||
if (! state)
|
||||
if (state & GDK_CONTROL_MASK)
|
||||
{
|
||||
GimpDialogFactory *dialog_factory;
|
||||
|
||||
dialog_factory = gimp_dialog_factory_from_name ("toolbox");
|
||||
|
||||
/* Hide or show all dialogs */
|
||||
gimp_dialog_factories_toggle (dialog_factory, FALSE);
|
||||
}
|
||||
else if (! gimp_image_is_empty (gimage))
|
||||
{
|
||||
if (state & GDK_CONTROL_MASK)
|
||||
if (! gimp_image_is_empty (gimage))
|
||||
{
|
||||
if (kevent->keyval == GDK_Tab)
|
||||
gimp_display_shell_layer_select_init (shell,
|
||||
@@ -1246,6 +1252,15 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
|
||||
-1, kevent->time);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpDialogFactory *dialog_factory;
|
||||
|
||||
dialog_factory = gimp_dialog_factory_from_name ("toolbox");
|
||||
|
||||
/* Hide or show all dialogs */
|
||||
gimp_dialog_factories_toggle (dialog_factory, FALSE);
|
||||
}
|
||||
|
||||
return_val = TRUE;
|
||||
break;
|
||||
@@ -1738,7 +1753,7 @@ gimp_display_shell_key_to_state (gint key)
|
||||
* The gimp_display_shell_compress_motion function source may be re-used under
|
||||
* the XFree86-style license. <adam@gimp.org>
|
||||
*/
|
||||
GdkEvent *
|
||||
static GdkEvent *
|
||||
gimp_display_shell_compress_motion (GimpDisplayShell *shell)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
@@ -135,7 +135,7 @@ gimp_display_shell_close_dialog (GimpDisplayShell *shell,
|
||||
NULL);
|
||||
g_free (title);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_SAVE);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
|
||||
|
||||
g_signal_connect (dialog, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed),
|
||||
|
@@ -331,9 +331,13 @@ gimp_display_shell_draw_tri (GimpDrawable *texture,
|
||||
|
||||
gdk_drawable_get_size (dest, &dwidth, &dheight);
|
||||
|
||||
row = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
mask ? TRUE : gimp_drawable_has_alpha (texture),
|
||||
8, dwidth, 1);
|
||||
if (dwidth > 0 && dheight > 0)
|
||||
row = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
mask ? TRUE : gimp_drawable_has_alpha (texture),
|
||||
8, dwidth, 1);
|
||||
else
|
||||
return;
|
||||
|
||||
g_return_if_fail (row != NULL);
|
||||
|
||||
/* sort vertices in order of y-coordinate */
|
||||
|
@@ -456,11 +456,15 @@ gimp_display_shell_scale_by_values (GimpDisplayShell *shell,
|
||||
gint offset_y,
|
||||
gboolean resize_window)
|
||||
{
|
||||
Gimp *gimp;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
|
||||
gimp = shell->gdisp->gimage->gimp;
|
||||
/* Abort early if the values are all setup already. We don't
|
||||
* want to inadvertently resize the window (bug #164281).
|
||||
*/
|
||||
if (shell->scale == scale &&
|
||||
shell->offset_x == offset_x &&
|
||||
shell->offset_y == offset_y)
|
||||
return;
|
||||
|
||||
/* freeze the active tool */
|
||||
gimp_display_shell_pause (shell);
|
||||
|
@@ -875,6 +875,11 @@ gimp_display_shell_new (GimpDisplay *gdisp,
|
||||
|
||||
gimp_help_set_help_data (shell->vrule, NULL, GIMP_HELP_IMAGE_WINDOW_RULER);
|
||||
|
||||
/* Workaround for GTK+ Wintab bug on Windows when creating guides by
|
||||
* dragging from the rulers. See bug #168516. */
|
||||
gtk_widget_set_extension_events (shell->hrule, GDK_EXTENSION_EVENTS_ALL);
|
||||
gtk_widget_set_extension_events (shell->vrule, GDK_EXTENSION_EVENTS_ALL);
|
||||
|
||||
/* the canvas */
|
||||
gtk_widget_set_size_request (shell->canvas, n_width, n_height);
|
||||
gtk_widget_set_events (shell->canvas, GIMP_DISPLAY_SHELL_CANVAS_EVENT_MASK);
|
||||
@@ -1227,7 +1232,7 @@ gimp_display_shell_mask_bounds (GimpDisplayShell *shell,
|
||||
*x2 = CLAMP (*x2, 0, shell->disp_width);
|
||||
*y2 = CLAMP (*y2, 0, shell->disp_height);
|
||||
|
||||
return TRUE;
|
||||
return ((*x2 - *x1) > 0) && ((*y2 - *y1) > 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1533,6 +1538,9 @@ gimp_display_shell_set_highlight (GimpDisplayShell *shell,
|
||||
|
||||
gdk_region_get_rectangles (old, &rects, &num_rects);
|
||||
|
||||
gdk_region_destroy (old);
|
||||
gdk_region_destroy (new);
|
||||
|
||||
for (i = 0; i < num_rects; i++)
|
||||
gimp_display_update_area (shell->gdisp, TRUE,
|
||||
rects[i].x,
|
||||
|
@@ -252,7 +252,7 @@ gimp_scale_combo_box_set_scale (GimpScaleComboBox *combo_box,
|
||||
SCALE, &this,
|
||||
-1);
|
||||
|
||||
if (this == scale)
|
||||
if (fabs (this - scale) < 0.01)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -154,6 +154,7 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
GtkWidget *frame;
|
||||
GimpUnitStore *store;
|
||||
GtkShadowType shadow_type;
|
||||
gboolean has_focus_on_click;
|
||||
|
||||
box->spacing = 2;
|
||||
box->homogeneous = FALSE;
|
||||
@@ -188,6 +189,13 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
statusbar->unit_combo = gimp_unit_combo_box_new_with_model (store);
|
||||
g_object_unref (store);
|
||||
|
||||
has_focus_on_click =
|
||||
g_object_class_find_property (G_OBJECT_GET_CLASS (statusbar->unit_combo),
|
||||
"focus-on-click") != NULL;
|
||||
|
||||
GTK_WIDGET_UNSET_FLAGS (statusbar->unit_combo, GTK_CAN_FOCUS);
|
||||
if (has_focus_on_click)
|
||||
g_object_set (statusbar->unit_combo, "focus-on-click", FALSE, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), statusbar->unit_combo);
|
||||
gtk_widget_show (statusbar->unit_combo);
|
||||
|
||||
@@ -201,6 +209,9 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
gtk_widget_show (frame);
|
||||
|
||||
statusbar->scale_combo = gimp_scale_combo_box_new ();
|
||||
GTK_WIDGET_UNSET_FLAGS (statusbar->scale_combo, GTK_CAN_FOCUS);
|
||||
if (has_focus_on_click)
|
||||
g_object_set (statusbar->scale_combo, "focus-on-click", FALSE, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), statusbar->scale_combo);
|
||||
gtk_widget_show (statusbar->scale_combo);
|
||||
|
||||
@@ -218,6 +229,7 @@ gimp_statusbar_init (GimpStatusbar *statusbar)
|
||||
statusbar->cancel_button = gtk_button_new_with_label (_("Cancel"));
|
||||
gtk_widget_set_sensitive (statusbar->cancel_button, FALSE);
|
||||
gtk_box_pack_start (box, statusbar->cancel_button, FALSE, FALSE, 0);
|
||||
GTK_WIDGET_UNSET_FLAGS (statusbar->cancel_button, GTK_CAN_FOCUS);
|
||||
gtk_widget_show (statusbar->cancel_button);
|
||||
|
||||
g_signal_connect (statusbar->cancel_button, "clicked",
|
||||
@@ -479,9 +491,9 @@ gimp_statusbar_push_coords (GimpStatusbar *statusbar,
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf), statusbar->cursor_format_str,
|
||||
title,
|
||||
ROUND (x),
|
||||
(gint) RINT (x),
|
||||
separator,
|
||||
ROUND (y));
|
||||
(gint) RINT (y));
|
||||
}
|
||||
else /* show real world units */
|
||||
{
|
||||
@@ -518,7 +530,7 @@ gimp_statusbar_push_length (GimpStatusbar *statusbar,
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf), statusbar->length_format_str,
|
||||
title,
|
||||
ROUND (value));
|
||||
(gint) RINT (value));
|
||||
}
|
||||
else /* show real world units */
|
||||
{
|
||||
@@ -654,7 +666,7 @@ gimp_statusbar_set_cursor (GimpStatusbar *statusbar,
|
||||
{
|
||||
g_snprintf (buffer, sizeof (buffer),
|
||||
statusbar->cursor_format_str,
|
||||
"", ROUND (x), ", ", ROUND (y));
|
||||
"", (gint) RINT (x), ", ", (gint) RINT (y));
|
||||
}
|
||||
else /* show real world units */
|
||||
{
|
||||
|
@@ -106,7 +106,7 @@ file_open_image (Gimp *gimp,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ file_open_thumbnail (Gimp *gimp,
|
||||
gint image_id;
|
||||
gint i;
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
args = g_new0 (Argument, proc->num_args);
|
||||
|
||||
@@ -362,7 +362,7 @@ file_open_layer (Gimp *gimp,
|
||||
|
||||
new_image = file_open_image (gimp, context, progress,
|
||||
uri, uri,
|
||||
NULL, GIMP_RUN_NONINTERACTIVE,
|
||||
NULL, GIMP_RUN_INTERACTIVE,
|
||||
status, &mime_type, error);
|
||||
|
||||
if (new_image)
|
||||
|
@@ -133,7 +133,7 @@ file_save_as (GimpImage *gimage,
|
||||
return GIMP_PDB_CALLING_ERROR;
|
||||
}
|
||||
|
||||
filename = g_filename_from_uri (uri, NULL, NULL);
|
||||
filename = file_utils_filename_from_uri (uri);
|
||||
|
||||
if (filename)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user