diff options
Diffstat (limited to 'src/ksquirrelpart')
62 files changed, 23005 insertions, 0 deletions
diff --git a/src/ksquirrelpart/Makefile.am b/src/ksquirrelpart/Makefile.am new file mode 100644 index 0000000..2e50ce8 --- /dev/null +++ b/src/ksquirrelpart/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = $(all_includes) -I$(srcdir) + +# These are not really libraries, but modules dynamically opened. +# So they should be installed in kde_module_dir, which is usually $kde_prefix/lib/trinity +kde_module_LTLIBRARIES = libksquirrelpart.la + +AM_CXXFLAGS = -DKSQUIRREL_PART + +if SQ_HAVE_KEXIF +AM_CXXFLAGS += $(libkexif_CFLAGS) +endif + +AM_CCASFLAGS = -I$(srcdir) $(KSQUIRREL_ASM_DEFS) + +libksquirrelpart_la_SOURCES = ksquirrelpart.cpp sq_glparts.cpp sq_glu.cpp sq_glwidget.cpp sq_glwidget_stuff.cpp sq_libraryhandler.cpp sq_downloader.cpp sq_iconloader.cpp fmt_filters.cpp sq_externaltool.cpp sq_config.cpp sq_filedialog.cpp sq_imagefilter.ui sq_imagebcg.ui sq_glselectionpainter.cpp sq_glwidget_helpers.cpp sq_label.cpp sq_bcglabel.cpp sq_popupmenu.cpp sq_codecsettingsskeleton.ui sq_codecsettings.cpp sq_imageproperties.ui sq_utils.cpp sq_helpwidget.ui sq_utils_asm_scale.S sq_utils_scale.cpp sq_diroperator.cpp sq_glview.cpp sq_errorstring.cpp +libksquirrelpart_la_LIBADD = $(LIB_TDEPARTS) +libksquirrelpart_la_LDFLAGS = $(all_libraries) $(LIB_TQT) $(LIB_TDECORE) $(LIB_TDEUI) $(LIB_TDEIO) $(LIB_TDEFX) $(KDE_PLUGIN) $(ksquirrellibs_LIBS) $(LIB_TDEPRINT) -lkonq -ltdefx $(LIB_QUI) + +if SQ_HAVE_KEXIF +libksquirrelpart_la_LDFLAGS += $(libkexif_LIBS) +endif + +METASOURCES = AUTO + +ksquirreldir = $(kde_datadir)/ksquirrelpart +ksquirrel_DATA = ksquirrelpart.rc + +kde_services_DATA = ksquirrelpart.desktop diff --git a/src/ksquirrelpart/file_broken.xpm b/src/ksquirrelpart/file_broken.xpm new file mode 100644 index 0000000..1040d96 --- /dev/null +++ b/src/ksquirrelpart/file_broken.xpm @@ -0,0 +1,831 @@ +/* XPM */ +static const char * file_broken_xpm[] = { +"64 64 764 2", +" c None", +". c #A5A9AA", +"+ c #A4A8A9", +"@ c #A3A7A8", +"# c #A2A6A7", +"$ c #A1A5A6", +"% c #A0A4A5", +"& c #9FA3A4", +"* c #9EA2A3", +"= c #9DA1A2", +"- c #9CA0A1", +"; c #9B9FA0", +"> c #9A9E9F", +", c #999D9E", +"' c #989C9D", +") c #979B9C", +"! c #969A9B", +"~ c #95999A", +"{ c #949899", +"] c #939798", +"^ c #929697", +"/ c #919596", +"( c #909495", +"_ c #8F9394", +": c #8E9293", +"< c #8D9192", +"[ c #8C9091", +"} c #8B8F90", +"| c #8A8E8F", +"1 c #898D8E", +"2 c #888C8D", +"3 c #878B8C", +"4 c #A6AAAB", +"5 c #ACB7BF", +"6 c #B3C4D4", +"7 c #B2C3D3", +"8 c #B1C2D2", +"9 c #B0C1D1", +"0 c #AFC0D0", +"a c #AEBFCF", +"b c #ADBECE", +"c c #ACBDCD", +"d c #ABBCCC", +"e c #AABBCB", +"f c #A9BACA", +"g c #A8B9C9", +"h c #A7B8C8", +"i c #A6B7C7", +"j c #A5B6C6", +"k c #A4B5C5", +"l c #95A0A8", +"m c #868A8B", +"n c #B0BECA", +"o c #C2E0FF", +"p c #D1E7FF", +"q c #D0E7FF", +"r c #CFE7FF", +"s c #CFE6FF", +"t c #9CAAB6", +"u c #828687", +"v c #C0DCF9", +"w c #E4F1FF", +"x c #FFFFFF", +"y c #FEFFFF", +"z c #FEFEFF", +"A c #FDFEFF", +"B c #FCFEFF", +"C c #FBFDFF", +"D c #FAFDFF", +"E c #FAFCFF", +"F c #F9FCFF", +"G c #F8FCFF", +"H c #F8FBFF", +"I c #F7FBFF", +"J c #F6FAFF", +"K c #F5FAFF", +"L c #DEEEFF", +"M c #BEDAF7", +"N c #85898A", +"O c #E8F3FF", +"P c #EFF7FF", +"Q c #F4FAFF", +"R c #E7F3FF", +"S c #F3F9FF", +"T c #E6F2FF", +"U c #F2F8FF", +"V c #E5F2FF", +"W c #F1F8FF", +"X c #FAEFEF", +"Y c #EAAFAF", +"Z c #EFCECF", +"` c #EECDCF", +" . c #CA3434", +".. c #C21616", +"+. c #E59F9F", +"@. c #BD1C1C", +"#. c #BC1C1C", +"$. c #EDCDCF", +"%. c #F0F8FF", +"&. c #FBEFEF", +"*. c #CB3434", +"=. c #DE3939", +"-. c #F64747", +";. c #C61A1A", +">. c #BE1C1C", +",. c #E83D3D", +"'. c #E73C3C", +"). c #BC1B1B", +"!. c #ECCDCF", +"~. c #F0F7FF", +"{. c #E3F1FF", +"]. c #CC3434", +"^. c #DF3939", +"/. c #FF6969", +"(. c #FF7A7A", +"_. c #F0CECF", +":. c #BF1C1C", +"<. c #FB6363", +"[. c #FB6161", +"}. c #E73737", +"|. c #BC1A1A", +"1. c #EBCCCF", +"2. c #CD3434", +"3. c #FFA3A3", +"4. c #FF8080", +"5. c #C01C1C", +"6. c #FB9E9E", +"7. c #FB9D9D", +"8. c #FB5E5E", +"9. c #E73333", +"0. c #BC1919", +"a. c #EBCBCF", +"b. c #E0EFFF", +"c. c #B5D9FF", +"d. c #CE3434", +"e. c #E03939", +"f. c #FF6868", +"g. c #FFA1A1", +"h. c #FE7F7F", +"i. c #F54747", +"j. c #E59E9F", +"k. c #C11C1C", +"l. c #E93D3D", +"m. c #FB6362", +"n. c #FB9C9C", +"o. c #FB9B9B", +"p. c #FB9A9A", +"q. c #FA9999", +"r. c #FA5A59", +"s. c #E62F2F", +"t. c #BC1819", +"u. c #EACBCF", +"v. c #EBF5FF", +"w. c #E5F1FF", +"x. c #99CCFF", +"y. c #CF3434", +"z. c #E13939", +"A. c #FE6665", +"B. c #FE9C9B", +"C. c #FE7C7A", +"D. c #DC7F7F", +"E. c #C21C1C", +"F. c #FC6160", +"G. c #FB9796", +"H. c #FB9695", +"I. c #FB9594", +"J. c #FB9493", +"K. c #FA9392", +"L. c #FA9291", +"M. c #F94242", +"N. c #E62B2B", +"O. c #BC1818", +"P. c #E9CBCF", +"Q. c #EDF6FF", +"R. c #E9F4FF", +"S. c #E2F0FF", +"T. c #D03434", +"U. c #E23939", +"V. c #FE6463", +"W. c #FE9794", +"X. c #FD7876", +"Y. c #F44646", +"Z. c #C82222", +"`. c #EA3D3D", +" + c #FC5F5D", +".+ c #FD928F", +"++ c #FD918E", +"@+ c #FD908D", +"#+ c #FC8F8C", +"$+ c #FC8E8B", +"%+ c #FC8D8A", +"&+ c #FB8683", +"*+ c #F93434", +"=+ c #F82C2C", +"-+ c #E52727", +";+ c #BC1717", +">+ c #E8CBCF", +",+ c #E1F0FF", +"'+ c #D13434", +")+ c #FE6260", +"!+ c #FE918D", +"~+ c #FD7370", +"{+ c #FC5D5B", +"]+ c #FD8D88", +"^+ c #FD8C87", +"/+ c #FD8A86", +"(+ c #FC8985", +"_+ c #FC8884", +":+ c #FC8783", +"<+ c #FC8682", +"[+ c #FA6462", +"}+ c #F82A2A", +"|+ c #F82727", +"1+ c #E52323", +"2+ c #BC1616", +"3+ c #E7CACF", +"4+ c #EFF6FF", +"5+ c #E6F3FF", +"6+ c #CEE6FF", +"7+ c #D23434", +"8+ c #E33939", +"9+ c #FE5C5A", +"0+ c #FE8C87", +"a+ c #FE8C86", +"b+ c #FD8B85", +"c+ c #FD8984", +"d+ c #FC7672", +"e+ c #FD8782", +"f+ c #FD8681", +"g+ c #FD8580", +"h+ c #FC847F", +"i+ c #FC837E", +"j+ c #FC827D", +"k+ c #FC817B", +"l+ c #FC807A", +"m+ c #F83636", +"n+ c #F72525", +"o+ c #F72323", +"p+ c #E41F1F", +"q+ c #BA1313", +"r+ c #EAD9DF", +"s+ c #EBF4FF", +"t+ c #CDE6FF", +"u+ c #DC5F5F", +"v+ c #D92C2C", +"w+ c #FC4B4A", +"x+ c #FE7B76", +"y+ c #FE8780", +"z+ c #FD8780", +"A+ c #FD8680", +"B+ c #FD857F", +"C+ c #FD847D", +"D+ c #FC837C", +"E+ c #FC827B", +"F+ c #FC817A", +"G+ c #FC8079", +"H+ c #FC7F78", +"I+ c #FC7E77", +"J+ c #FB7D76", +"K+ c #FB7C75", +"L+ c #FB7A74", +"M+ c #F95C58", +"N+ c #F62121", +"O+ c #D71919", +"P+ c #C13031", +"Q+ c #EBE7EF", +"R+ c #DFEFFF", +"S+ c #FC4A4A", +"T+ c #FE7770", +"U+ c #FD8179", +"V+ c #FD8078", +"W+ c #FD7F77", +"X+ c #FC7E76", +"Y+ c #FC7D75", +"Z+ c #FC7C74", +"`+ c #FC7A72", +" @ c #FC7971", +".@ c #FC7870", +"+@ c #FB776F", +"@@ c #FB766E", +"#@ c #FB756D", +"$@ c #FA6F68", +"%@ c #F82E2E", +"&@ c #C23031", +"*@ c #EAE7EF", +"=@ c #CCE5FF", +"-@ c #FC4A49", +";@ c #FD726B", +">@ c #FD7C73", +",@ c #FD7A71", +"'@ c #FD7970", +")@ c #FC786F", +"!@ c #FC776E", +"~@ c #FC766D", +"{@ c #FC756C", +"]@ c #FC746B", +"^@ c #FC736A", +"/@ c #FB7269", +"(@ c #FB7168", +"_@ c #FB7066", +":@ c #FB6E65", +"<@ c #F83F3C", +"[@ c #D81919", +"}@ c #C33031", +"|@ c #E8E6EF", +"1@ c #DDEEFF", +"2@ c #CBE5FF", +"3@ c #FB4A49", +"4@ c #FC6E65", +"5@ c #FC776C", +"6@ c #FC766C", +"7@ c #FC756B", +"8@ c #FC746A", +"9@ c #FC7369", +"0@ c #FC7267", +"a@ c #FC7166", +"b@ c #FC7065", +"c@ c #FB6F64", +"d@ c #FB6E63", +"e@ c #FB6D62", +"f@ c #FB6B61", +"g@ c #FB6A60", +"h@ c #FA695F", +"i@ c #F94944", +"j@ c #D91919", +"k@ c #C43031", +"l@ c #DCEDFF", +"m@ c #CBE4FF", +"n@ c #FA4949", +"o@ c #FC6960", +"p@ c #FC7064", +"q@ c #FC6F63", +"r@ c #FC6E62", +"s@ c #FC6D61", +"t@ c #FC6C60", +"u@ c #FC6A5F", +"v@ c #FB695D", +"w@ c #FB685C", +"x@ c #FB675B", +"y@ c #FB665A", +"z@ c #FB6559", +"A@ c #FA6458", +"B@ c #F94641", +"C@ c #C53031", +"D@ c #E7E5EF", +"E@ c #DBEDFF", +"F@ c #CAE4FF", +"G@ c #DB5F5F", +"H@ c #D82C2C", +"I@ c #FA4646", +"J@ c #FC6258", +"K@ c #FC685B", +"L@ c #FC675A", +"M@ c #FC6659", +"N@ c #FC6558", +"O@ c #FB6457", +"P@ c #FB6356", +"Q@ c #FB6255", +"R@ c #FB6154", +"S@ c #FB6053", +"T@ c #FA5B4F", +"U@ c #F83A36", +"V@ c #DA1919", +"W@ c #C52F31", +"X@ c #C9E4FF", +"Y@ c #F3CECF", +"Z@ c #CB0C0C", +"`@ c #F04242", +" # c #FB4F48", +".# c #FB6253", +"+# c #FB6152", +"@# c #FB6051", +"## c #FB5E50", +"$# c #FB5D4F", +"%# c #FA5C4E", +"&# c #FA5B4D", +"*# c #FA5A4C", +"=# c #F94B41", +"-# c #F11F1F", +";# c #C70C0C", +"># c #D5898F", +",# c #DAECFF", +"'# c #CF1C1C", +")# c #ED3D3D", +"!# c #FB4B45", +"~# c #FB5C4D", +"{# c #FB5B4C", +"]# c #FB5A4B", +"^# c #FB594A", +"/# c #FB5849", +"(# c #FA5748", +"_# c #FA5646", +":# c #F95244", +"<# c #F83834", +"[# c #F72A2A", +"}# c #F61F1F", +"|# c #F31D1D", +"1# c #E91A1A", +"2# c #C50909", +"3# c #D7989F", +"4# c #D9ECFF", +"5# c #C8E3FF", +"6# c #D01C1C", +"7# c #EE3D3D", +"8# c #FB4943", +"9# c #FB5948", +"0# c #FB5847", +"a# c #FB5746", +"b# c #FB5545", +"c# c #FA5444", +"d# c #FA5343", +"e# c #F95242", +"f# c #F8463B", +"g# c #F62E2D", +"h# c #F52A2A", +"i# c #F52727", +"j# c #F52525", +"k# c #F52323", +"l# c #F51F1F", +"m# c #F11D1D", +"n# c #EF1A1A", +"o# c #EF1818", +"p# c #E91616", +"q# c #C50707", +"r# c #D6979F", +"s# c #D8EBFF", +"t# c #F4CECF", +"u# c #D11C1C", +"v# c #FA5545", +"w# c #F95343", +"x# c #F85041", +"y# c #F53934", +"z# c #F32C2C", +"A# c #F12A2A", +"B# c #F12727", +"C# c #F12525", +"D# c #F12323", +"E# c #F22121", +"F# c #EE1D1D", +"G# c #EE1A1A", +"H# c #EE1616", +"I# c #ED1414", +"J# c #E71212", +"K# c #C50606", +"L# c #D5979F", +"M# c #D7EBFF", +"N# c #C7E3FF", +"O# c #D31C1C", +"P# c #EF3D3D", +"Q# c #F95444", +"R# c #F85343", +"S# c #F6493D", +"T# c #F2302F", +"U# c #F02C2C", +"V# c #EF2A2A", +"W# c #EE2727", +"X# c #EE2525", +"Y# c #ED2323", +"Z# c #EE2121", +"`# c #EB1F1F", +" $ c #E91D1D", +".$ c #EA1A1A", +"+$ c #EB1818", +"@$ c #EC1616", +"#$ c #ED1212", +"$$ c #ED0F0F", +"%$ c #E70D0D", +"&$ c #C50404", +"*$ c #D4969F", +"=$ c #D6EAFF", +"-$ c #C6E2FF", +";$ c #D41C1C", +">$ c #F4433A", +",$ c #F02E2E", +"'$ c #EE2C2C", +")$ c #EC2A2A", +"!$ c #EB2727", +"~$ c #EB2525", +"{$ c #EA2323", +"]$ c #E92121", +"^$ c #E51F1F", +"/$ c #E51D1D", +"($ c #E51A1A", +"_$ c #E71818", +":$ c #E71616", +"<$ c #E91414", +"[$ c #EA1212", +"}$ c #EC0F0F", +"|$ c #EC0D0D", +"1$ c #EB0B0B", +"2$ c #E50909", +"3$ c #C50202", +"4$ c #D3969F", +"5$ c #D5EAFF", +"6$ c #EEF6FF", +"7$ c #FAEEEF", +"8$ c #D31414", +"9$ c #EB3D3D", +"0$ c #FB4843", +"a$ c #F75343", +"b$ c #F23D37", +"c$ c #EF2E2E", +"d$ c #EC2C2C", +"e$ c #EA2A2A", +"f$ c #E92727", +"g$ c #E82525", +"h$ c #E62323", +"i$ c #E32121", +"j$ c #E11F1F", +"k$ c #E11D1D", +"l$ c #E11A1A", +"m$ c #E21818", +"n$ c #E31616", +"o$ c #E41414", +"p$ c #E61212", +"q$ c #E70F0F", +"r$ c #E90D0D", +"s$ c #EA0909", +"t$ c #EA0707", +"u$ c #E30404", +"v$ c #C00000", +"w$ c #D8C2CF", +"x$ c #C5E2FF", +"y$ c #EB9E9F", +"z$ c #D71818", +"A$ c #F53F3E", +"B$ c #FB5245", +"C$ c #EE2E2E", +"D$ c #EB2C2C", +"E$ c #E92A2A", +"F$ c #E72727", +"G$ c #E52525", +"H$ c #E22323", +"I$ c #DE2121", +"J$ c #DD1F1F", +"K$ c #DD1D1D", +"L$ c #DD1A1A", +"M$ c #DD1818", +"N$ c #DE1616", +"O$ c #DF1414", +"P$ c #E11212", +"Q$ c #E20F0F", +"R$ c #E40D0D", +"S$ c #E60B0B", +"T$ c #E80909", +"U$ c #E80404", +"V$ c #CE0202", +"W$ c #C9595F", +"X$ c #D4E9FF", +"Y$ c #C4E1FF", +"Z$ c #EA9E9F", +"`$ c #D71616", +" % c #F53B3A", +".% c #FA4F42", +"+% c #F3433A", +"@% c #E82A2A", +"#% c #E62727", +"$% c #E22525", +"%% c #DD2323", +"&% c #DB2121", +"*% c #CE1D1D", +"=% c #D71D1D", +"-% c #D81A1A", +";% c #D91818", +">% c #D91616", +",% c #DB1414", +"'% c #DC1212", +")% c #DE0F0F", +"!% c #DF0D0D", +"~% c #E20B0B", +"{% c #E40909", +"]% c #E60707", +"^% c #E70404", +"/% c #CF0202", +"(% c #CA595F", +"_% c #D3E9FF", +":% c #EDF5FF", +"<% c #EA9D9F", +"[% c #D71414", +"}% c #F33735", +"|% c #F84D40", +"1% c #F64E3F", +"2% c #E42727", +"3% c #DE2525", +"4% c #DB2323", +"5% c #D92121", +"6% c #CA1919", +"7% c #C91111", +"8% c #C61010", +"9% c #D31818", +"0% c #D51616", +"a% c #D61414", +"b% c #D71212", +"c% c #D90F0F", +"d% c #DB0D0D", +"e% c #DD0B0B", +"f% c #DF0909", +"g% c #E10707", +"h% c #E20404", +"i% c #CB595F", +"j% c #D2E8FF", +"k% c #C3E1FF", +"l% c #ECF5FF", +"m% c #E99D9F", +"n% c #D61313", +"o% c #EE3231", +"p% c #F13230", +"q% c #E62A2A", +"r% c #E22727", +"s% c #D82121", +"t% c #C91919", +"u% c #CF2F31", +"v% c #E7E4EF", +"w% c #D45B5F", +"x% c #C40E0E", +"y% c #D01414", +"z% c #D21212", +"A% c #D40F0F", +"B% c #D60D0D", +"C% c #D80B0B", +"D% c #DA0909", +"E% c #DC0707", +"F% c #DE0404", +"G% c #CC0202", +"H% c #CC595F", +"I% c #D1E8FF", +"J% c #C2E1FF", +"K% c #F7FAFF", +"L% c #E79C9F", +"M% c #D41111", +"N% c #E72C2C", +"O% c #E32727", +"P% c #DF2525", +"Q% c #D35B5F", +"R% c #C30B0B", +"S% c #CE0F0F", +"T% c #D10D0D", +"U% c #D30B0B", +"V% c #D50909", +"W% c #D80707", +"X% c #D90404", +"Y% c #CA0202", +"Z% c #CD595F", +"`% c #ADD6FF", +" & c #F4F9FF", +".& c #E49A9F", +"+& c #D20F0F", +"@& c #E12727", +"#& c #E12525", +"$& c #CB1919", +"%& c #D12F31", +"&& c #D25A5F", +"*& c #C20808", +"=& c #CD0B0B", +"-& c #D10909", +";& c #D30707", +">& c #D50404", +",& c #C80202", +"'& c #CE595F", +")& c #C1E0FF", +"!& c #DEEFFF", +"~& c #F2F9FF", +"{& c #E39A9F", +"]& c #D00E0E", +"^& c #CD1919", +"/& c #D22F31", +"(& c #C30505", +"_& c #CE0707", +":& c #D00404", +"<& c #C60202", +"[& c #C0DFFF", +"}& c #EEF7FF", +"|& c #E2999F", +"1& c #CF0C0C", +"2& c #CF1919", +"3& c #D32F31", +"4& c #D15A5F", +"5& c #C40303", +"6& c #CF595F", +"7& c #ECF6FF", +"8& c #E1999F", +"9& c #D52D2F", +"0& c #D1595F", +"a& c #D0595F", +"b& c #BFDFFF", +"c& c #EAF4FF", +"d& c #BFDEFF", +"e& c #BEDEFF", +"f& c #CAE5FF", +"g& c #BDDEFF", +"h& c #BCDDFF", +"i& c #BBDDFF", +"j& c #BADCFF", +"k& c #B9DCFF", +"l& c #C4E2FF", +"m& c #B8DBFF", +"n& c #889299", +"o& c #99C9F9", +"p& c #B0D7FF", +"q& c #97C7F7", +"r& c #A1B6CA", +"s& c #ACD5FF", +"t& c #ABD5FF", +"u& c #AAD5FF", +"v& c #AAD4FF", +"w& c #A9D4FF", +"x& c #A8D4FF", +"y& c #A8D3FF", +"z& c #A7D3FF", +"A& c #A6D2FF", +"B& c #A5D2FF", +"C& c #A4D2FF", +"D& c #A4D1FF", +"E& c #A3D1FF", +"F& c #8DA2B6", +"G& c #A2B2BF", +"H& c #9DBEDF", +"I& c #9BC3E9", +"J& c #9BC2E9", +"K& c #9BC2E8", +"L& c #9AC2E8", +"M& c #9AC1E8", +"N& c #9AC1E7", +"O& c #99C1E7", +"P& c #99C0E7", +"Q& c #99C0E6", +"R& c #98C0E6", +"S& c #98BFE6", +"T& c #98BFE5", +"U& c #97BFE5", +"V& c #97BEE5", +"W& c #97BEE4", +"X& c #96BEE4", +"Y& c #96BDE4", +"Z& c #96BDE3", +"`& c #95BDE3", +" * c #95BCE3", +".* c #95BCE2", +"+* c #94BCE2", +"@* c #90ABC5", +"#* c #8B9BA8", +"$* c #848889", +"%* c #999C9D", +"&* c #96999A", +"** c #959899", +"=* c #949798", +"-* c #939697", +";* c #929596", +">* c #909394", +",* c #8E9292", +"'* c #8D9091", +")* c #8B8E8F", +"!* c #888B8C", +"~* c #878A8B", +"{* c #868A8A", +"]* c #858889", +"^* c #848788", +"/* c #838787", +"(* c #818586", +"_* c #818485", +":* c #808485", +"<* c #7F8384", +"[* c #7F8383", +"}* c #787C7D", +" ", +" ", +" ", +" . + + @ # # $ % % & & * = = - ; ; > , , ' ) ) ! ! ~ { { ] ^ ^ / ( ( _ : : < < [ } } | 1 1 2 3 3 ", +" 4 5 6 6 7 7 7 8 8 8 9 9 9 0 0 0 a a a b b b c c c c d d d e e e f f f g g g h h h i i i j j j k l m ", +" 4 n o p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p q q q q q q q q r r s s s s s o t u ", +" 4 v w x x x x x x x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K L M N ", +" 4 o I x x x x x x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K O o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q R o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q Q R o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q Q S T o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q Q S S T o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q Q S S U T o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q Q S S U U V o N ", +" 4 o P x x x x x x x x x x x x x x x x x x x y z z A A B C C D D E F G H I I I J K K Q Q S S U U W V o N ", +" 4 o P x x x x x x x x x x X Y x x x x x x y z z A A Z ` C D D E F G H I I I J K K Q Q S S U U W W V o N ", +" 4 o P x x x x x x x x x X ...+.x x x x y z z A A Z @.#.$.D E F G H I I I J K K Q Q S S U U W W %.w o N ", +" 4 o P x x x x x x x x &.*.=.-.;.+.x x y z z A A Z >.,.'.).!.F G H I I I J K K Q Q S S U U W W %.~.{.o N ", +" 4 o P x x x x x x x &.].^./.(.-.;.+.y z z A A _.:.,.<.[.}.|.1.H I I I J K K Q Q S S U U W W %.~.P {.o N ", +" 4 o P x x x x x x &.2.^./.3.3.4.-.;.+.z A A _.5.,.<.6.7.8.9.0.a.I I J K K Q Q S S U U W W %.~.P P b.c.N ", +" 4 o P x x x x x &.d.e.f.g.g.g.g.h.i.;.j.A _.k.l.m.n.o.p.q.r.s.t.u.J K K Q Q S S U U W W %.P v.O w.q x.N ", +" 4 o P x x x x &.y.z.A.B.B.B.B.B.B.C.i.;.D.E.l.F.G.H.I.J.K.L.M.N.O.P.K Q Q S S U U W W Q.R.V w {.S.r x.N ", +" 4 o P x x x &.T.U.V.W.W.W.W.W.W.W.W.X.Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+Q S S U U W Q.O T V w {.S.,+r x.N ", +" 4 o P x x &.'+U.)+!+!+!+!+!+!+!+!+!+!+~+M.{+]+^+/+(+_+:+<+[+=+}+|+1+2+3+S U U 4+O 5+T V w {.S.,+,+6+x.N ", +" 4 o P x &.7+8+9+0+0+0+0+0+0+0+0+0+a+b+c+d+e+f+g+h+i+j+k+l+m+}+|+n+o+p+q+r+~.s+R 5+T V w {.S.,+,+b.t+x.N ", +" 4 o P x x u+v+w+x+y+y+z+z+z+z+z+A+B+C+D+E+F+G+H+I+J+K+L+M+}+|+n+o+N+O+P+Q+R.R 5+T V w {.S.,+,+b.R+t+x.N ", +" 4 o P x x x u+v+S+T+U+U+U+U+U+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@|+n+o+N+O+&@*@O R 5+T V w {.S.,+,+b.R+L =@x.N ", +" 4 o P x x x x u+v+-@;@>@>@>@>@,@'@)@!@~@{@]@^@/@(@_@:@<@|+n+o+N+[@}@|@O R 5+T V w {.S.,+,+b.R+L 1@2@x.N ", +" 4 o P x x x x x u+v+3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@|+n+o+N+j@k@|@O R 5+T V w {.S.,+,+b.R+L 1@l@m@x.N ", +" 4 o P x x x x y z u+v+n@o@p@q@r@s@t@u@v@w@x@y@z@A@B@|+n+o+N+j@C@D@O R 5+T V w {.S.,+,+b.R+L 1@l@E@F@x.N ", +" 4 o P x x x y z z A G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@|+n+o+N+V@W@D@O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@X@x.N ", +" 4 o P x x y z z A A Y@Z@`@ #.#+#@###$#%#&#*#=#=+|+n+o+N+-#;#>#O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#X@x.N ", +" 4 o P x y z z A A Y@'#)#!#~#{#]#^#/#(#_#:#<#[#|+n+o+N+}#|#1#2#3#5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#5#x.N ", +" 4 o P y z z A A Y@6#7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#N+l#m#n#o#p#q#r#V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#5#x.N ", +" 4 o P z z A A t#u#7#8#9#0#a#v#c#w#x#y#z#A#B#C#D#E#-#F#G#o#H#I#J#K#L#{.S.,+,+b.R+L 1@l@E@E@,#4#s#M#N#x.N ", +" 4 o 4+z A A t#O#P#8#9#0#a#v#Q#R#S#T#U#V#W#X#Y#Z#`# $.$+$@$I##$$$%$&$*$,+,+b.R+L 1@l@E@E@,#4#s#M#=$-$x.N ", +" 4 o 4+A A t#;$P#8#9#0#a#v#Q#R#>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$1$2$3$4$b.R+L 1@l@E@E@,#4#s#M#=$5$-$x.N ", +" 4 o 6$A 7$8$9$0$9#0#a#v#Q#a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$1$s$t$u$v$w$L 1@l@E@E@,#4#s#M#=$5$5$x$x.N ", +" 4 o 6$B C y$z$A$B$a#v#Q#a$b$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$t$U$V$W$L 1@l@E@E@,#4#s#M#=$5$5$X$Y$x.N ", +" 4 o 6$C C D Z$`$ %.%Q#R#+%C$D$@%#%$%%%&%*%=%-%;%>%,%'%)%!%~%{%]%^%/%(%L 1@l@E@E@,#4#s#M#=$5$5$X$_%Y$x.N ", +" 4 o :%C D D E <%[%}%|%1%c$D$@%2%3%4%5%6%7%8%9%0%a%b%c%d%e%f%g%h%V$i%L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%k%x.N ", +" 4 o l%D D E F G m%n%o%p%d$q%r%3%4%s%t%u%v%w%x%y%z%A%B%C%D%E%F%G%H%L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%J%x.N ", +" 4 o l%D E F G H K%L%M%N%q%O%P%4%s%6%u%v%O R Q%R%S%T%U%V%W%X%Y%Z%L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q o x.N ", +" 4 `%V H I J &S U W .&+&@&#&%%5%$&%&v%O R 5+T &&*&=&-&;&>&,&'&L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r )&x.N ", +" 4 x.!&K Q S ~&U W ~.P {&]&4%&%^&/&v%O R 5+T V w &&(&_&:&<&'&L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r [&x.N ", +" 4 x.L Q S ~&U W ~.P }&Q.|&1&2&3&v%O R 5+T V w {.S.4&5&3$6&L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+[&x.N ", +" 4 x.1@S ~&U W ~.P }&Q.7&l%8&9&v%O R 5+T V w {.S.,+,+0&a&L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+b&x.N ", +" 4 x.l@~&U W ~.P }&Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@d&x.N ", +" 4 x.l@U W ~.P }&Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@e&x.N ", +" 4 x.E@W ~.P }&Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&g&x.N ", +" 4 x.E@~.P }&Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@g&x.N ", +" 4 x.,#P }&Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@h&x.N ", +" 4 x.4#}&Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#i&x.N ", +" 4 x.4#Q.7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#N#i&x.N ", +" 4 x.s#7&l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#N#-$j&x.N ", +" 4 x.M#l%v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#N#-$x$k&x.N ", +" 4 x.M#v.c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#N#-$x$l&k&x.N ", +" 4 x.=$c&R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#N#-$x$l&k%m&x.n& ", +" 4 o&-$R.O R 5+T V w {.S.,+,+b.R+L 1@l@E@E@,#4#s#M#=$5$5$X$_%j%I%q r r 6+t+=@2@f&X@X@5#N#-$x$l&k%J%p&q&N ", +" 4 r&x.`%s&s&s&s&t&t&t&t&t&u&v&v&v&v&w&w&w&w&x&y&y&y&y&z&z&z&z&z&A&A&A&A&B&B&B&B&B&C&D&D&D&D&E&E&E&x.F&u ", +" 4 G&H&I&J&J&J&K&L&L&M&M&M&N&N&O&P&P&P&Q&Q&R&S&S&S&S&T&U&U&V&V&V&W&X&X&Y&Y&Y&Z&Z&`& * * *.*.*+*@*#*$* ", +" . > , %*' ) ) ! &*~ **=*] -*^ ;*/ ( >*_ : ,*< '*[ } )*| 1 1 2 !*3 ~*{*N ]*$*^*/*u u (*_*:*<*[*}* ", +" ", +" "}; diff --git a/src/ksquirrelpart/fmt_filters.cpp b/src/ksquirrelpart/fmt_filters.cpp new file mode 100644 index 0000000..860cdeb --- /dev/null +++ b/src/ksquirrelpart/fmt_filters.cpp @@ -0,0 +1,2287 @@ +/* + * Copyright (c) 2005 Dmitry Baryshev <ksquirrel.iv@gmail.com> + */ + +/* This file is part of the KDE libraries + Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org> + (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> + (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> + (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl> + (C) 2000 Josef Weidendorfer <weidendo@in.tum.de> + (C) 2004 Zack Rusin <zack@kde.org> + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +// +// =================================================================== +// Effects originally ported from ImageMagick for PixiePlus, plus a few +// new ones. (mosfet 05/26/2003) +// =================================================================== +// +/* + Portions of this software are based on ImageMagick. Such portions are clearly +marked as being ported from ImageMagick. ImageMagick is copyrighted under the +following conditions: + +Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated to +making software imaging solutions freely available. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files ("ImageMagick"), to deal +in ImageMagick without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of ImageMagick, and to permit persons to whom the ImageMagick is +furnished 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 ImageMagick. + +The software is provided "as is", without warranty of any kind, express or +implied, including but not limited to the warranties of merchantability, +fitness for a particular purpose and noninfringement. In no event shall +ImageMagick Studio be liable for any claim, damages or other liability, +whether in an action of contract, tort or otherwise, arising from, out of or +in connection with ImageMagick or the use or other dealings in ImageMagick. + +Except as contained in this notice, the name of the ImageMagick Studio shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in ImageMagick without prior written authorization from the +ImageMagick Studio. +*/ + +#include "fmt_filters.h" + +#include <cmath> +#include <algorithm> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +namespace fmt_filters +{ + +#define MaxRGB 255L +#define DegreesToRadians(x) ((x)*M_PI/180.0) +#define MagickSQ2PI 2.50662827463100024161235523934010416269302368164062 +#define MagickEpsilon 1.0e-12 +#define MagickPI 3.14159265358979323846264338327950288419716939937510 + +#define F_MAX(a, b) ((b) < (a) ? (a) : (b)) +#define F_MIN(a, b) ((a) < (b) ? (a) : (b)) + +static void rgb2hsv(const fmt_filters::rgb &rgb, s32 *h, s32 *s, s32 *v); +static void hsv2rgb(s32 h, s32 s, s32 v, fmt_filters::rgb *rgb); +static fmt_filters::rgba interpolateColor(const fmt_filters::image &image, double x_offset, double y_offset, const fmt_filters::rgba &background); +static u32 generateNoise(u32 pixel, fmt_filters::NoiseType noise_type); +static u32 intensityValue(s32 r, s32 g, s32 b); +static u32 intensityValue(const fmt_filters::rgba &rr); +static s32 getBlurKernel(s32 width, double sigma, double **kernel); +static void blurScanLine(double *kernel, s32 width, fmt_filters::rgba *src, fmt_filters::rgba *dest, s32 columns); +static void hull(const s32 x_offset, const s32 y_offset, const s32 polarity, const s32 columns, + const s32 rows, u8 *f, u8 *g); +static bool convolveImage(fmt_filters::image *image, fmt_filters::rgba **dest, const unsigned int order, const double *kernel); +static int getOptimalKernelWidth(double radius, double sigma); + +template<class T> +static void scaleDown(T &val, T min, T max); + +struct double_packet +{ + double red; + double green; + double blue; + double alpha; +}; + +struct short_packet +{ + unsigned short int red; + unsigned short int green; + unsigned short int blue; + unsigned short int alpha; +}; + +bool checkImage(const image &im) +{ + return (im.rw && im.rh && im.w && im.h && im.data); +} + +// colorize tool +void colorize(const image &im, s32 red, s32 green, s32 blue) +{ + // check if all parameters are good + if(!checkImage(im)) + return; + + if(!red && !green && !blue) + return; + + u8 *bits; + s32 val; + s32 V[3] = { red, green, blue }; + + // add to RED component 'red' value, and check if the result is out of bounds. + // do the same with GREEN and BLUE channels. + for(s32 y = 0;y < im.h;++y) + { + bits = im.data + im.rw * y * sizeof(rgba); + + for(s32 x = 0;x < im.w;x++) + { + for(s32 v = 0;v < 3;++v) + { + val = (s32)*(bits + v) + V[v]; + + if(val > 255) + *(bits + v) = 255; + else if(val < 0) + *(bits + v) = 0; + else + *(bits + v) = val; + } + + bits += 4; + } + } +} + +// brightness tool +void brightness(const image &im, s32 bn) +{ + // check if all parameters are good + if(!checkImage(im)) + return; + + u8 *bits; + s32 val; + + // add to all color components 'bn' value, and check if the result is out of bounds. + for(s32 y = 0;y < im.h;++y) + { + bits = im.data + im.rw * y * sizeof(rgba); + + for(s32 x = 0;x < im.w;x++) + { + for(s32 v = 0;v < 3;v++) + { + val = bn + *bits; + *bits = val < 0 ? 0 : (val > 255 ? 255 : val); + + bits++; + } + + bits++; + } + } +} + +// gamma tool +void gamma(const image &im, double L) +{ + // check if all parameters are good + if(!checkImage(im)) + return; + + if(L == 0 || L < 0) L = 0.01; + + rgba *_rgba; + u8 R, G, B; + u8 GT[256]; + + GT[0] = 0; + + // fill the array with gamma koefficients + for (s32 x = 1; x < 256; ++x) + GT[x] = (u8)round(255 * pow((double)x / 255.0, 1.0 / L)); + + // now change gamma + for(s32 y = 0;y < im.h;++y) + { + _rgba = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + R = _rgba[x].r; + G = _rgba[x].g; + B = _rgba[x].b; + + _rgba[x].r = GT[R]; + _rgba[x].g = GT[G]; + _rgba[x].b = GT[B]; + } + } +} + +// contrast tool +void contrast(const image &im, s32 contrast) +{ + if(!checkImage(im) || !contrast) + return; + + if(contrast < -255) contrast = -255; + if(contrast > 255) contrast = 255; + + rgba *bits; + u8 Ravg, Gavg, Bavg; + s32 Ra = 0, Ga = 0, Ba = 0, Rn, Gn, Bn; + + // calculate the average values for RED, GREEN and BLUE + // color components + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + Ra += bits->r; + Ga += bits->g; + Ba += bits->b; + + bits++; + } + } + + s32 S = im.w * im.h; + + Ravg = Ra / S; + Gavg = Ga / S; + Bavg = Ba / S; + + // ok, now change contrast + // with the terms of alghoritm: + // + // if contrast > 0: I = (I - Avg) * 256 / (256 - contrast) + Avg + // if contrast < 0: I = (I - Avg) * (256 + contrast) / 256 + Avg + // + // where + // I - current color component value + // Avg - average value of this component (Ravg, Gavg or Bavg) + // + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + Rn = (contrast > 0) ? ((bits->r - Ravg) * 256 / (256 - contrast) + Ravg) : ((bits->r - Ravg) * (256 + contrast) / 256 + Ravg); + Gn = (contrast > 0) ? ((bits->g - Gavg) * 256 / (256 - contrast) + Gavg) : ((bits->g - Gavg) * (256 + contrast) / 256 + Gavg); + Bn = (contrast > 0) ? ((bits->b - Bavg) * 256 / (256 - contrast) + Bavg) : ((bits->b - Bavg) * (256 + contrast) / 256 + Bavg); + + bits->r = Rn < 0 ? 0 : (Rn > 255 ? 255 : Rn); + bits->g = Gn < 0 ? 0 : (Gn > 255 ? 255 : Gn); + bits->b = Bn < 0 ? 0 : (Bn > 255 ? 255 : Bn); + + bits++; + } + } +} + +// negative +void negative(const image &im) +{ + // check if all parameters are good + if(!checkImage(im)) + return; + + rgba *bits; + u8 R, G, B; + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + R = bits->r; + G = bits->g; + B = bits->b; + + bits->r = 255 - R; + bits->g = 255 - G; + bits->b = 255 - B; + + bits++; + } + } +} + +// swap RGB values +void swapRGB(const image &im, s32 type) +{ + // check if all parameters are good + if(!checkImage(im) || (type != GBR && type != BRG)) + return; + + rgba *bits; + u8 R, G, B; + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + R = bits->r; + G = bits->g; + B = bits->b; + + bits->r = (type == GBR) ? G : B; + bits->g = (type == GBR) ? B : R; + bits->b = (type == GBR) ? R : G; + + bits++; + } + } +} + +// blend +void blend(const image &im, const rgb &rgb, float opacity) +{ + // check parameters + if(!checkImage(im)) + return; + + scaleDown(opacity, 0.0f, 1.0f); + + rgba *bits; + s32 r = rgb.r, g = rgb.g, b = rgb.b; + + // blend! + for(s32 y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + bits->r = bits->r + (u8)((b - bits->r) * opacity); + bits->g = bits->g + (u8)((g - bits->g) * opacity); + bits->b = bits->b + (u8)((r - bits->b) * opacity); + + bits++; + } + } +} + +void flatten(const image &im, const rgb &ca, const rgb &cb) +{ + if(!checkImage(im)) + return; + + s32 r1 = ca.r; s32 r2 = cb.r; + s32 g1 = ca.g; s32 g2 = cb.g; + s32 b1 = ca.b; s32 b2 = cb.b; + s32 min = 0, max = 255; + s32 mean; + + rgba *bits; + rgb _rgb; + + for(s32 y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;++x) + { + mean = (bits->r + bits->g + bits->b) / 3; + min = F_MIN(min, mean); + max = F_MAX(max, mean); + bits++; + } + } + + // Conversion factors + float sr = ((float) r2 - r1) / (max - min); + float sg = ((float) g2 - g1) / (max - min); + float sb = ((float) b2 - b1) / (max - min); + + // Repaint the image + for(s32 y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.w*y; + + for(s32 x = 0;x < im.w;++x) + { + mean = (bits->r + bits->g + bits->b) / 3; + + bits->r = (s32)(sr * (mean - min) + r1 + 0.5); + bits->g = (s32)(sg * (mean - min) + g1 + 0.5); + bits->b = (s32)(sb * (mean - min) + b1 + 0.5); + + bits++; + } + } +} + +void fade(const image &im, const rgb &rgb, float val) +{ + if(!checkImage(im)) + return; + + u8 tbl[256]; + + for (s32 i = 0;i < 256;i++) + tbl[i] = (s32)(val * i + 0.5); + + s32 r, g, b, cr, cg, cb; + + rgba *bits; + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + cr = bits->r; + cg = bits->g; + cb = bits->b; + + r = (cr > rgb.r) ? (cr - tbl[cr - rgb.r]) : (cr + tbl[rgb.r - cr]); + g = (cg > rgb.g) ? (cg - tbl[cg - rgb.g]) : (cg + tbl[rgb.g - cg]); + b = (cb > rgb.b) ? (cb - tbl[cb - rgb.b]) : (cb + tbl[rgb.b - cb]); + + bits->r = r; + bits->g = g; + bits->b = b; + + bits++; + } + } +} + +void gray(const image &im) +{ + if(!checkImage(im)) + return; + + rgba *bits; + s32 g; + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + g = (bits->r * 11 + bits->g * 16 + bits->b * 5)/32; + + bits->r = g; + bits->g = g; + bits->b = g; + + bits++; + } + } +} + +void desaturate(const image &im, float desat) +{ + if(!checkImage(im)) + return; + + scaleDown(desat, 0.0f, 1.0f); + + rgba *bits; + s32 h = 0, s = 0, v = 0; + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + rgb _rgb(bits->r, bits->g, bits->b); + rgb2hsv(_rgb, &h, &s, &v); + hsv2rgb(h, (s32)(s * (1.0 - desat)), v, &_rgb); + + bits->r = _rgb.r; + bits->g = _rgb.g; + bits->b = _rgb.b; + + bits++; + } + } +} + +void threshold(const image &im, u32 trh) +{ + if(!checkImage(im)) + return; + + scaleDown(trh, (u32)0, (u32)255); + + rgba *bits; + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + if(intensityValue(bits->r, bits->g, bits->b) < trh) + bits->r = bits->g = bits->b = 0; + else + bits->r = bits->g = bits->b = 255; + + bits++; + } + } +} + +void solarize(const image &im, double factor) +{ + if(!checkImage(im)) + return; + + s32 threshold; + rgba *bits; + + threshold = (s32)(factor * (MaxRGB+1)/100.0); + + for(s32 y = 0;y < im.h;y++) + { + bits = (rgba *)im.data + im.rw * y; + + for(s32 x = 0;x < im.w;x++) + { + bits->r = bits->r > threshold ? MaxRGB-bits->r : bits->r; + bits->g = bits->g > threshold ? MaxRGB-bits->g : bits->g; + bits->b = bits->b > threshold ? MaxRGB-bits->b : bits->b; + + bits++; + } + } +} + +void spread(const image &im, u32 amount) +{ + if(!checkImage(im) || im.w < 3 || im.h < 3) + return; + + rgba *n = new rgba [im.rw * im.rh]; + + if(!n) + return; + + s32 quantum; + s32 x_distance, y_distance; + rgba *bits = (rgba *)im.data, *q; + + memcpy(n, im.data, im.rw * im.rh * sizeof(rgba)); + + quantum = (amount+1) >> 1; + + for(s32 y = 0;y < im.h;y++) + { + q = n + im.rw*y; + + for(s32 x = 0;x < im.w;x++) + { + x_distance = x + ((rand() & (amount+1))-quantum); + y_distance = y + ((rand() & (amount+1))-quantum); + x_distance = F_MIN(x_distance, im.w-1); + y_distance = F_MIN(y_distance, im.h-1); + + if(x_distance < 0) x_distance = 0; + if(y_distance < 0) y_distance = 0; + + *q++ = *(bits + y_distance*im.rw + x_distance); + } + } + + memcpy(im.data, n, im.rw * im.rh * sizeof(rgba)); + + delete [] n; +} + +void swirl(const image &im, double degrees, const rgba &background) +{ + if(!checkImage(im)) + return; + + double cosine, distance, factor, radius, sine, x_center, x_distance, + x_scale, y_center, y_distance, y_scale; + s32 x, y; + + rgba *q, *p; + rgba *bits = (rgba *)im.data; + rgba *dest = new rgba [im.rw * im.rh]; + + if(!dest) + return; + + memcpy(dest, im.data, im.rw * im.rh * sizeof(rgba)); + + // compute scaling factor + x_center = im.w / 2.0; + y_center = im.h / 2.0; + + radius = F_MAX(x_center, y_center); + x_scale=1.0; + y_scale=1.0; + + if(im.w > im.h) + y_scale=(double)im.w / im.h; + else if(im.w < im.h) + x_scale=(double)im.h / im.w; + + degrees = DegreesToRadians(degrees); + + // swirl each row + + for(y = 0;y < im.h;y++) + { + p = bits + im.rw * y; + q = dest + im.rw * y; + y_distance = y_scale * (y-y_center); + + for(x = 0;x < im.w;x++) + { + // determine if the pixel is within an ellipse + *q = *p; + x_distance = x_scale*(x-x_center); + distance = x_distance*x_distance+y_distance*y_distance; + + if(distance < (radius*radius)) + { + // swirl + factor = 1.0 - sqrt(distance)/radius; + sine = sin(degrees*factor*factor); + cosine = cos(degrees*factor*factor); + + *q = interpolateColor(im, + (cosine*x_distance-sine*y_distance)/x_scale+x_center, + (sine*x_distance+cosine*y_distance)/y_scale+y_center, + background); + } + + p++; + q++; + } + } + + memcpy(im.data, dest, im.rw * im.rh * sizeof(rgba)); + + delete [] dest; +} + +void noise(const image &im, NoiseType noise_type) +{ + if(!checkImage(im)) + return; + + s32 x, y; + rgba *dest = new rgba [im.rw * im.rh]; + + if(!dest) + return; + + rgba *bits; + rgba *destData; + + for(y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.rw * y; + destData = dest + im.rw * y; + + for(x = 0;x < im.w;++x) + { + destData[x].r = generateNoise(bits->r, noise_type); + destData[x].g = generateNoise(bits->g, noise_type); + destData[x].b = generateNoise(bits->b, noise_type); + destData[x].a = bits->a; + + bits++; + } + } + + memcpy(im.data, dest, im.rw * im.rh * sizeof(rgba)); + + delete [] dest; +} + +void implode(const image &im, double _factor, const rgba &background) +{ + if(!checkImage(im)) + return; + + double amount, distance, radius; + double x_center, x_distance, x_scale; + double y_center, y_distance, y_scale; + rgba *dest; + s32 x, y; + + rgba *n = new rgba [im.rw * im.rh]; + + if(!n) + return; + + rgba *bits; + + // compute scaling factor + x_scale = 1.0; + y_scale = 1.0; + x_center = (double)0.5*im.w; + y_center = (double)0.5*im.h; + radius=x_center; + + if(im.w > im.h) + y_scale = (double)im.w/im.h; + else if(im.w < im.h) + { + x_scale = (double)im.h/im.w; + radius = y_center; + } + + amount=_factor/10.0; + + if(amount >= 0) + amount/=10.0; + + double factor; + + for(y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.rw * y; + dest = n + im.rw * y; + + y_distance = y_scale * (y-y_center); + + for(x = 0;x < im.w;++x) + { + x_distance = x_scale*(x-x_center); + distance= x_distance*x_distance+y_distance*y_distance; + + if(distance < (radius*radius)) + { + // Implode the pixel. + factor = 1.0; + + if(distance > 0.0) + factor = pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount); + + *dest = interpolateColor(im, factor*x_distance/x_scale+x_center, + factor*y_distance/y_scale+y_center, + background); + } + else + *dest = *bits; + + bits++; + dest++; + } + } + + memcpy(im.data, n, im.rw * im.rh * sizeof(rgba)); + + delete [] n; +} + +void despeckle(const image &im) +{ + if(!checkImage(im)) + return; + + s32 i, j, x, y; + u8 *blue_channel, *red_channel, *green_channel, *buffer, *alpha_channel; + s32 packets; + + static const s32 + X[4] = {0, 1, 1,-1}, + Y[4] = {1, 0, 1, 1}; + + rgba *n = new rgba [im.rw * im.rh]; + + if(!n) + return; + + packets = (im.w+2) * (im.h+2); + + red_channel = new u8 [packets]; + green_channel = new u8 [packets]; + blue_channel = new u8 [packets]; + alpha_channel = new u8 [packets]; + buffer = new u8 [packets]; + + if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel || !buffer) + { + if(red_channel) delete [] red_channel; + if(green_channel) delete [] green_channel; + if(blue_channel) delete [] blue_channel; + if(alpha_channel) delete [] alpha_channel; + if(buffer) delete [] buffer; + + delete [] n; + + return; + } + + // copy image pixels to color component buffers + j = im.w+2; + + rgba *bits; + + for(y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.rw*y; + ++j; + + for(x = 0;x < im.w;++x) + { + red_channel[j] = bits->r; + green_channel[j] = bits->g; + blue_channel[j] = bits->b; + alpha_channel[j] = bits->a; + + bits++; + ++j; + } + + ++j; + } + + // reduce speckle in red channel + for(i = 0;i < 4;i++) + { + hull(X[i],Y[i],1,im.w,im.h,red_channel,buffer); + hull(-X[i],-Y[i],1,im.w,im.h,red_channel,buffer); + hull(-X[i],-Y[i],-1,im.w,im.h,red_channel,buffer); + hull(X[i],Y[i],-1,im.w,im.h,red_channel,buffer); + } + + // reduce speckle in green channel + for(i = 0;i < packets;i++) + buffer[i] = 0; + + for(i = 0;i < 4;i++) + { + hull(X[i],Y[i],1,im.w,im.h,green_channel,buffer); + hull(-X[i],-Y[i],1,im.w,im.h,green_channel,buffer); + hull(-X[i],-Y[i],-1,im.w,im.h,green_channel,buffer); + hull(X[i],Y[i],-1,im.w,im.h,green_channel,buffer); + } + + // reduce speckle in blue channel + for(i = 0;i < packets;i++) + buffer[i] = 0; + + for(i = 0;i < 4;i++) + { + hull(X[i],Y[i],1,im.w,im.h,blue_channel,buffer); + hull(-X[i],-Y[i],1,im.w,im.h,blue_channel,buffer); + hull(-X[i],-Y[i],-1,im.w,im.h,blue_channel,buffer); + hull(X[i],Y[i],-1,im.w,im.h,blue_channel,buffer); + } + + // copy color component buffers to despeckled image + j = im.w+2; + + for(y = 0;y < im.h;++y) + { + bits = n + im.rw*y; + ++j; + + for(x = 0;x < im.w;++x) + { + *bits = rgba(red_channel[j], green_channel[j], blue_channel[j], alpha_channel[j]); + + bits++; + ++j; + } + + ++j; + } + + delete [] buffer; + delete [] red_channel; + delete [] green_channel; + delete [] blue_channel; + delete [] alpha_channel; + + memcpy(im.data, n, im.rw * im.rh * sizeof(rgba)); + + delete [] n; +} + +void blur(const image &im, double radius, double sigma) +{ + if(!checkImage(im)) + return; + + double *kernel; + rgba *dest; + s32 width; + s32 x, y; + rgba *scanline, *temp; + rgba *p, *q; + + if(sigma == 0.0) + return; + + kernel = 0; + + if(radius > 0) + width = getBlurKernel((s32)(2*ceil(radius)+1), sigma, &kernel); + else + { + double *last_kernel = 0; + + width = getBlurKernel(3, sigma, &kernel); + + while((long)(MaxRGB * kernel[0]) > 0) + { + if(last_kernel) + delete [] last_kernel; + + last_kernel = kernel; + kernel = 0; + + width = getBlurKernel(width+2, sigma, &kernel); + } + + if(last_kernel) + { + delete [] kernel; + width -= 2; + kernel = last_kernel; + } + } + + if(width < 3) + { + delete [] kernel; + return; + } + + dest = new rgba [im.rw * im.rh]; + + if(!dest) + { + delete [] kernel; + return; + } + + scanline = new rgba [im.h]; + temp = new rgba [im.h]; + + if(!scanline || !temp) + { + if(scanline) delete [] scanline; + if(temp) delete [] temp; + + delete [] kernel; + return; + } + + rgba *bits = (rgba *)im.data; + + for(y = 0;y < im.h;++y) + { + p = bits + im.rw*y; + q = dest + im.rw*y; + + blurScanLine(kernel, width, p, q, im.w); + } + + for(x = 0;x < im.w;++x) + { + for(y = 0;y < im.h;++y) + scanline[y] = *(bits + im.rw*y + x); + + blurScanLine(kernel, width, scanline, temp, im.h); + + for(y = 0;y < im.h;++y) + *(dest + im.rw*y + x) = temp[y]; + + } + + delete [] scanline; + delete [] temp; + delete [] kernel; + + memcpy(im.data, dest, im.rw * im.rh * sizeof(rgba)); + + delete [] dest; +} + +void equalize(const image &im) +{ + if(!checkImage(im)) + return; + + double_packet high, low, intensity, *map, *histogram; + short_packet *equalize_map; + s32 x, y; + rgba *p, *q; + long i; + u8 r, g, b, a; + + histogram = new double_packet [256]; + map = new double_packet [256]; + equalize_map = new short_packet [256]; + + if(!histogram || !map || !equalize_map) + { + if(histogram) delete [] histogram; + if(map) delete [] map; + if(equalize_map) delete [] equalize_map; + + return; + } + + rgba *bits = (rgba *)im.data; + + /* + * Form histogram. + */ + memset(histogram, 0, 256 * sizeof(double_packet)); + + for(y = 0;y < im.h;++y) + { + p = bits + im.rw * y; + + for(x = 0;x < im.w;++x) + { + histogram[p->r].red++; + histogram[p->g].green++; + histogram[p->b].blue++; + histogram[p->a].alpha++; + + p++; + } + } + /* + Integrate the histogram to get the equalization map. + */ + memset(&intensity, 0 ,sizeof(double_packet)); + + for(i = 0;i < 256;++i) + { + intensity.red += histogram[i].red; + intensity.green += histogram[i].green; + intensity.blue += histogram[i].blue; + intensity.alpha += histogram[i].alpha; + + map[i] = intensity; + } + + low=map[0]; + high=map[255]; + memset(equalize_map, 0, 256 * sizeof(short_packet)); + + for(i = 0;i < 256;++i) + { + if(high.red != low.red) + equalize_map[i].red=(unsigned short) + ((65535*(map[i].red-low.red))/(high.red-low.red)); + if(high.green != low.green) + equalize_map[i].green=(unsigned short) + ((65535*(map[i].green-low.green))/(high.green-low.green)); + if(high.blue != low.blue) + equalize_map[i].blue=(unsigned short) + ((65535*(map[i].blue-low.blue))/(high.blue-low.blue)); + if(high.alpha != low.alpha) + equalize_map[i].alpha=(unsigned short) + ((65535*(map[i].alpha-low.alpha))/(high.alpha-low.alpha)); + } + + delete [] histogram; + delete [] map; + + /* + Stretch the histogram. + */ + for(y = 0;y < im.h;++y) + { + q = bits + im.rw*y; + + for(x = 0;x < im.w;++x) + { + if(low.red != high.red) + r = (equalize_map[(unsigned short)(q->r)].red/257); + else + r = q->r; + if(low.green != high.green) + g = (equalize_map[(unsigned short)(q->g)].green/257); + else + g = q->g; + if(low.blue != high.blue) + b = (equalize_map[(unsigned short)(q->b)].blue/257); + else + b = q->b; + if(low.alpha != high.alpha) + a = (equalize_map[(unsigned short)(q->a)].alpha/257); + else + a = q->a; + + *q = rgba(r, g, b, a); + + q++; + } + } + + delete [] equalize_map; +} + +struct PointInfo +{ + double x, y, z; +}; + +void shade(const image &im, bool color_shading, double azimuth, + double elevation) +{ + if(!checkImage(im)) + return; + + rgba *n = new rgba [im.rw * im.rh]; + + if(!n) + return; + + double distance, normal_distance, shade; + s32 x, y; + + struct PointInfo light, normal; + + rgba *bits; + rgba *q; + + azimuth = DegreesToRadians(azimuth); + elevation = DegreesToRadians(elevation); + light.x = MaxRGB*cos(azimuth)*cos(elevation); + light.y = MaxRGB*sin(azimuth)*cos(elevation); + light.z = MaxRGB*sin(elevation); + normal.z= 2*MaxRGB; // constant Z of surface normal + + rgba *s0, *s1, *s2; + + for(y = 0;y < im.h;++y) + { + bits = (rgba *)im.data + im.rw * (F_MIN(F_MAX(y-1,0),im.h-3)); + q = n + im.rw * y; + + // shade this row of pixels. + *q++ = (*(bits+im.rw)); + bits++; + + s0 = bits; + s1 = bits + im.rw; + s2 = bits + 2*im.rw; + + for(x = 1;x < im.w-1;++x) + { + // determine the surface normal and compute shading. + normal.x = intensityValue(*(s0-1))+intensityValue(*(s1-1))+intensityValue(*(s2-1))- + (double) intensityValue(*(s0+1))-(double) intensityValue(*(s1+1))- + (double) intensityValue(*(s2+1)); + + normal.y = intensityValue(*(s2-1))+intensityValue(*s2)+intensityValue(*(s2+1))- + (double) intensityValue(*(s0-1))-(double) intensityValue(*s0)- + (double) intensityValue(*(s0+1)); + + if(normal.x == 0 && normal.y == 0) + shade = light.z; + else + { + shade = 0.0; + distance = normal.x*light.x+normal.y*light.y+normal.z*light.z; + + if(distance > 0.0) + { + normal_distance = normal.x*normal.x+normal.y*normal.y+normal.z*normal.z; + + if(fabs(normal_distance) > 0.0000001) + shade=distance/sqrt(normal_distance); + } + } + + if(!color_shading) + { + *q = rgba((u8)(shade), + (u8)(shade), + (u8)(shade), + s1->a); + } + else + { + *q = rgba((u8)((shade * s1->r)/(MaxRGB+1)), + (u8)((shade * s1->g)/(MaxRGB+1)), + (u8)((shade * s1->b)/(MaxRGB+1)), + s1->a); + } + + ++s0; + ++s1; + ++s2; + q++; + } + + *q++ = (*s1); + } + + memcpy(im.data, n, im.rw * im.rh * sizeof(rgba)); + + delete [] n; +} + +void edge(image &im, double radius) +{ + if(!checkImage(im)) + return; + + double *kernel; + int width; + long i; + rgba *dest = 0; + + width = getOptimalKernelWidth(radius, 0.5); + + const int W = width*width; + + if(im.w < width || im.h < width) + return; + + kernel = new double [W]; + + if(!kernel) + return; + + for(i = 0;i < W;i++) + kernel[i] = -1.0; + + kernel[i/2] = W-1.0; + + if(!convolveImage(&im, &dest, width, kernel)) + { + delete [] kernel; + + if(dest) + delete [] dest; + + return; + } + + delete [] kernel; + + memcpy(im.data, dest, im.rw * im.rh * sizeof(rgba)); + + delete [] dest; +} + +void emboss(image &im, double radius, double sigma) +{ + if(!checkImage(im)) + return; + + double alpha, *kernel; + int j, width; + long i, u, v; + rgba *dest = 0; + + if(sigma == 0.0) + return; + + width = getOptimalKernelWidth(radius, sigma); + + if(im.w < width || im.h < width) + return; + + kernel = new double [width*width]; + + if(!kernel) + return; + + i = 0; + j = width/2; + + const double S = sigma * sigma; + + for(v = (-width/2);v <= (width/2);v++) + { + for(u=(-width/2); u <= (width/2); u++) + { + alpha = exp(-((double) u*u+v*v)/(2.0*S)); + + kernel[i] = ((u < 0) || (v < 0) ? -8.0 : 8.0)*alpha/(2.0*MagickPI*S); + + if (u == j) + kernel[i]=0.0; + + i++; + } + + j--; + } + + if(!convolveImage(&im, &dest, width, kernel)) + { + delete [] kernel; + return; + } + + delete [] kernel; + + fmt_filters::image mm((u8 *)dest, im.w, im.h, im.rw, im.rh); + + equalize(mm); + + memcpy(im.data, dest, im.rw * im.rh * sizeof(rgba)); + + delete [] dest; +} + +void sharpen(image &im, double radius, double sigma) +{ + if(!checkImage(im)) + return; + + double alpha, normalize, *kernel; + int width; + long i, u, v; + rgba *dest = 0; + + if(sigma == 0.0) + sigma = 0.01; + + width = getOptimalKernelWidth(radius, sigma); + + if(im.w < width) + return; + + kernel = new double [width*width]; + + if(!kernel) + return; + + i = 0; + normalize = 0.0; + const double S = sigma * sigma; + const int w2 = width / 2; + + for(v = -w2; v <= w2; v++) + { + for(u = -w2; u <= w2; u++) + { + alpha = exp(-((double) u*u+v*v)/(2.0*S)); + kernel[i] = alpha/(2.0*MagickPI*S); + normalize += kernel[i]; + + i++; + } + } + + kernel[i/2] = (-2.0)*normalize; + + if(!convolveImage(&im, &dest, width, kernel)) + { + delete [] kernel; + + if(dest) + delete [] dest; + + return; + } + + delete [] kernel; + + memcpy(im.data, dest, im.rw * im.rh * sizeof(rgba)); + + delete [] dest; +} + +void oil(const image &im, double radius) +{ + if(!checkImage(im)) + return; + + unsigned long count; + unsigned long histogram[256]; + unsigned int k; + int width; + int x, y, mx, my, sx, sy; + int mcx, mcy; + rgba *s = 0, *q; + + scaleDown(radius, 1.0, 5.0); + + rgba *n = new rgba [im.rw * im.rh]; + + if(!n) + return; + + memcpy(n, im.data, im.rw * im.rh * sizeof(rgba)); + + width = getOptimalKernelWidth(radius, 0.5); + + if(im.w < width) + { + delete [] n; + return; + } + + rgba *bits = (rgba *)im.data; + + for(y = 0;y < im.h;++y) + { + sy = y-(width/2); + q = n + im.rw*y; + + for(x = 0;x < im.w;++x) + { + count = 0; + memset(histogram, 0, 256 * sizeof(unsigned long)); + sy = y-(width/2); + + for(mcy = 0;mcy < width;++mcy,++sy) + { + my = sy < 0 ? 0 : sy > im.h-1 ? im.h-1 : sy; + sx = x+(-width/2); + + for(mcx = 0; mcx < width;++mcx,++sx) + { + mx = sx < 0 ? 0 : sx > im.w-1 ? im.w-1 : sx; + + k = intensityValue(*(bits + my*im.rw + mx)); + + if(k > 255) k = 255; + + histogram[k]++; + + if(histogram[k] > count) + { + count = histogram[k]; + s = bits + my*im.rw + mx; + } + } + } + + *q++ = (*s); + } + } + + memcpy(im.data, n, im.rw * im.rh * sizeof(rgba)); + + delete [] n; +} +/* + * Red-eye removal was taken from "redeye" plugin for GIMP + */ + +/* redeye.c: redeye remover plugin code + * + * Copyright (C) 2004 Robert Merkel <robert.merkel@benambra.org> (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 furnished 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, + * FITNESS 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 + * CONNECTION 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. +1;3B */ + +void redeye(const image &im, const int w, const int h, const int x, const int y, int th) +{ + const double RED_FACTOR = 0.5133333; + const double GREEN_FACTOR = 1; + const double BLUE_FACTOR = 0.1933333; + + if(!checkImage(im)) + return; + + scaleDown(th, 0, 255); + + int y1, x1; + int adjusted_red, adjusted_green, adjusted_blue; + + rgba *src = (rgba *)im.data, *s; + + for(y1 = y;y1 < y+h;++y1) + { + s = src + im.w*y1 + x; + + for(x1 = x;x1 < x+w;x1++) + { + adjusted_red = int(s->r * RED_FACTOR); + adjusted_green = int(s->g * GREEN_FACTOR); + adjusted_blue = int(s->b * BLUE_FACTOR); + + if(adjusted_red >= adjusted_green - th && adjusted_red >= adjusted_blue - th) + s->r = (int)(((double)(adjusted_green + adjusted_blue)) / (2.0 * RED_FACTOR)); + + s++; + } + } +} + + +/*************************************************************************/ + +/* + * + * Helper functions + * + */ + +/*************************************************************************/ + +static bool convolveImage(image *image, rgba **dest, const unsigned int order, + const double *kernel) +{ + long width; + double red, green, blue; + u8 alpha; + double normalize, *normal_kernel; + const double *k; + rgba *q; + int x, y, mx, my, sx, sy; + long i; + int mcx, mcy; + + width = order; + + if((width % 2) == 0) + return false; + + const int W = width*width; + + normal_kernel = new double [W]; + + if(!normal_kernel) + return false; + + *dest = new rgba [image->rw * image->rh]; + + if(!*dest) + { + delete [] normal_kernel; + return false; + } + + normalize = 0.0; + + for(i = 0;i < W;i++) + normalize += kernel[i]; + + if(fabs(normalize) <= MagickEpsilon) + normalize = 1.0; + + normalize=1.0/normalize; + + for(i = 0;i < W;i++) + normal_kernel[i] = normalize*kernel[i]; + + rgba *bits = (rgba *)image->data; + + for(y = 0;y < image->h;++y) + { + sy = y-(width/2); + q = *dest + image->rw * y; + + for(x = 0;x < image->w;++x) + { + k = normal_kernel; + red = green = blue = alpha = 0; + sy = y-(width/2); + alpha = (bits + image->rw*y+x)->a; + + for(mcy=0; mcy < width; ++mcy, ++sy) + { + my = sy < 0 ? 0 : sy > image->h-1 ? image->h-1 : sy; + sx = x+(-width/2); + + for(mcx=0; mcx < width; ++mcx, ++sx) + { + mx = sx < 0 ? 0 : sx > image->w-1 ? image->w-1 : sx; + red += (*k) * ((bits + image->rw*my+mx)->r*257); + green += (*k) * ((bits + image->rw*my+mx)->g*257); + blue += (*k) * ((bits + image->rw*my+mx)->b*257); +// alpha += (*k) * ((bits + image->rw*my+mx)->a*257); + + ++k; + } + } + + red = red < 0 ? 0 : red > 65535 ? 65535 : red+0.5; + green = green < 0 ? 0 : green > 65535 ? 65535 : green+0.5; + blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue+0.5; +// alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha+0.5; + + *q++ = rgba((unsigned char)(red/257UL), + (unsigned char)(green/257UL), + (unsigned char)(blue/257UL), + alpha); + } + } + + delete [] normal_kernel; + + return true; +} + +static void rgb2hsv(const rgb &rgb, s32 *h, s32 *s, s32 *v) +{ + if(!h || !s || !v) + return; + + s32 r = rgb.r; + s32 g = rgb.g; + s32 b = rgb.b; + + u32 max = r; + s32 whatmax = 0; // r=>0, g=>1, b=>2 + + if((u32)g > max) + { + max = g; + whatmax = 1; + } + + if((u32)b > max) + { + max = b; + whatmax = 2; + } + + u32 min = r; // find minimum value + if((u32)g < min) min = g; + if((u32)b < min) min = b; + + s32 delta = max-min; + *v = max; // calc value + *s = max ? (510*delta+max)/(2*max) : 0; + + if(*s == 0) + { + *h = -1; // undefined hue + } + else + { + switch(whatmax) + { + case 0: // red is max component + if(g >= b) + *h = (120*(g-b)+delta)/(2*delta); + else + *h = (120*(g-b+delta)+delta)/(2*delta) + 300; + break; + + case 1: // green is max component + if(b > r) + *h = 120 + (120*(b-r)+delta)/(2*delta); + else + *h = 60 + (120*(b-r+delta)+delta)/(2*delta); + break; + + case 2: // blue is max component + if(r > g) + *h = 240 + (120*(r-g)+delta)/(2*delta); + else + *h = 180 + (120*(r-g+delta)+delta)/(2*delta); + break; + } + } +} + +static void hsv2rgb(s32 h, s32 s, s32 v, rgb *rgb) +{ + if(h < -1 || (u32)s > 255 || (u32)v > 255 || !rgb) + return; + + s32 r = v, g = v, b = v; + + if(s == 0 || h == -1) + { + // Ignore + } + else + { // chromatic case + if((u32)h >= 360) + h %= 360; + + u32 f = h%60; + h /= 60; + u32 p = (u32)(2*v*(255-s)+255)/510; + u32 q, t; + + if(h&1) + { + q = (u32)(2*v*(15300-s*f)+15300)/30600; + + switch(h) + { + case 1: r=(s32)q; g=(s32)v, b=(s32)p; break; + case 3: r=(s32)p; g=(s32)q, b=(s32)v; break; + case 5: r=(s32)v; g=(s32)p, b=(s32)q; break; + } + } + else + { + t = (u32)(2*v*(15300-(s*(60-f)))+15300)/30600; + + switch(h) + { + case 0: r=(s32)v; g=(s32)t, b=(s32)p; break; + case 2: r=(s32)p; g=(s32)v, b=(s32)t; break; + case 4: r=(s32)t; g=(s32)p, b=(s32)v; break; + } + } + } + + rgb->r = r; + rgb->g = g; + rgb->b = b; +} + +static rgba interpolateColor(const image &im, double x_offset, double y_offset, const rgba &background) +{ + double alpha, beta; + rgba p, q, r, s; + s32 x, y; + rgba *bits = (rgba *)im.data; + + if(!checkImage(im)) + return background; + + x = (s32)x_offset; + y = (s32)y_offset; + + if((x < -1) || (x >= im.w) || (y < -1) || (y >= im.h)) + return background; + + if((x >= 0) && (y >= 0) && (x < (im.w-1)) && (y < (im.h-1))) + { + rgba *t = bits + y * im.rw; + + p = t[x]; + q = t[x+1]; + r = t[x+im.rw]; + s = t[x+im.rw+1]; + } + else + { + rgba *t = bits + y * im.rw; + + p = background; + + if((x >= 0) && (y >= 0)) + p = t[x]; + + q = background; + + if(((x+1) < im.w) && (y >= 0)) + q = t[x+1]; + + r = background; + + if((x >= 0) && ((y+1) < im.h)) + { + t = bits + (y+1) * im.rw; + r = t[x+im.rw]; + } + + s = background; + + if(((x+1) < im.w) && ((y+1) < im.h)) + { + t = bits + (y+1) * im.rw; + s = t[x+im.rw+1]; + } + } + + x_offset -= floor(x_offset); + y_offset -= floor(y_offset); + alpha = 1.0-x_offset; + beta = 1.0-y_offset; + + rgba _r; + + _r.r = (u8)(beta * (alpha*p.r + x_offset*q.r) + y_offset * (alpha*r.r + x_offset*s.r)); + _r.g = (u8)(beta * (alpha*p.g + x_offset*q.g) + y_offset * (alpha*r.g + x_offset*s.g)); + _r.b = (u8)(beta * (alpha*p.b + x_offset*q.b) + y_offset * (alpha*r.b + x_offset*s.b)); + _r.a = (u8)(beta * (alpha*p.a + x_offset*q.a) + y_offset * (alpha*r.a + x_offset*s.a)); + + return _r; +} + +static u32 generateNoise(u32 pixel, NoiseType noise_type) +{ +#define NoiseEpsilon 1.0e-5 +#define NoiseMask 0x7fff +#define SigmaUniform 4.0 +#define SigmaGaussian 4.0 +#define SigmaImpulse 0.10 +#define SigmaLaplacian 10.0 +#define SigmaMultiplicativeGaussian 0.5 +#define SigmaPoisson 0.05 +#define TauGaussian 20.0 + + double alpha, beta, sigma, value; + alpha=(double) (rand() & NoiseMask)/NoiseMask; + if (alpha == 0.0) + alpha=1.0; + switch(noise_type){ + case UniformNoise: + default: + { + value=(double) pixel+SigmaUniform*(alpha-0.5); + break; + } + case GaussianNoise: + { + double tau; + + beta=(double) (rand() & NoiseMask)/NoiseMask; + sigma=sqrt(-2.0*log(alpha))*cos(2.0*M_PI*beta); + tau=sqrt(-2.0*log(alpha))*sin(2.0*M_PI*beta); + value=(double) pixel+ + (sqrt((double) pixel)*SigmaGaussian*sigma)+(TauGaussian*tau); + break; + } + case MultiplicativeGaussianNoise: + { + if (alpha <= NoiseEpsilon) + sigma=MaxRGB; + else + sigma=sqrt(-2.0*log(alpha)); + beta=(rand() & NoiseMask)/NoiseMask; + value=(double) pixel+ + pixel*SigmaMultiplicativeGaussian*sigma*cos(2.0*M_PI*beta); + break; + } + case ImpulseNoise: + { + if (alpha < (SigmaImpulse/2.0)) + value=0; + else + if (alpha >= (1.0-(SigmaImpulse/2.0))) + value=MaxRGB; + else + value=pixel; + break; + } + case LaplacianNoise: + { + if (alpha <= 0.5) + { + if (alpha <= NoiseEpsilon) + value=(double) pixel-MaxRGB; + else + value=(double) pixel+SigmaLaplacian*log(2.0*alpha); + break; + } + beta=1.0-alpha; + if (beta <= (0.5*NoiseEpsilon)) + value=(double) pixel+MaxRGB; + else + value=(double) pixel-SigmaLaplacian*log(2.0*beta); + break; + } + case PoissonNoise: + { + s32 + i; + + for (i=0; alpha > exp(-SigmaPoisson*pixel); i++) + { + beta=(double) (rand() & NoiseMask)/NoiseMask; + alpha=alpha*beta; + } + value=i/SigmaPoisson; + break; + } + } + + if(value < 0.0) + return 0; + else if(value > MaxRGB) + return MaxRGB; + else + return ((u32) (value+0.5)); +} + +static inline u32 intensityValue(s32 r, s32 g, s32 b) +{ + return ((u32)((0.299*r + 0.587*g + 0.1140000000000001*b))); +} + +static inline u32 intensityValue(const rgba &rr) +{ + return ((u32)((0.299*rr.r + 0.587*rr.g + 0.1140000000000001*rr.b))); +} + +template<class T> +static inline void scaleDown(T &val, T min, T max) +{ + if(val < min) + val = min; + else if(val > max) + val = max; +} + +static void blurScanLine(double *kernel, s32 width, rgba *src, rgba *dest, s32 columns) +{ + double *p; + rgba *q; + s32 x; + long i; + double red, green, blue, alpha; + double scale = 0.0; + + if(width > columns) + { + for(x = 0;x < columns;++x) + { + scale = 0.0; + red = blue = green = alpha = 0.0; + p = kernel; + q = src; + + for(i = 0;i < columns;++i) + { + if((i >= (x-width/2)) && (i <= (x+width/2))) + { + red += (*p)*(q->r * 257); + green += (*p)*(q->g*257); + blue += (*p)*(q->b*257); + alpha += (*p)*(q->a*257); + } + + if(((i+width/2-x) >= 0) && ((i+width/2-x) < width)) + scale += kernel[i+width/2-x]; + + p++; + q++; + } + + scale = 1.0/scale; + red = scale*(red+0.5); + green = scale*(green+0.5); + blue = scale*(blue+0.5); + alpha = scale*(alpha+0.5); + + red = red < 0 ? 0 : red > 65535 ? 65535 : red; + green = green < 0 ? 0 : green > 65535 ? 65535 : green; + blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; + alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; + + dest[x] = rgba((u8)(red/257UL), + (u8)(green/257UL), + (u8)(blue/257UL), + (u8)(alpha/257UL)); + } + + return; + } + + for(x = 0;x < width/2;++x) + { + scale = 0.0; + red = blue = green = alpha = 0.0; + p = kernel+width/2-x; + q = src; + + for(i = width/2-x;i < width;++i) + { + red += (*p)*(q->r*257); + green += (*p)*(q->g*257); + blue += (*p)*(q->b*257); + alpha += (*p)*(q->a*257); + scale += (*p); + p++; + q++; + } + + scale=1.0/scale; + + red = scale*(red+0.5); + green = scale*(green+0.5); + blue = scale*(blue+0.5); + alpha = scale*(alpha+0.5); + + red = red < 0 ? 0 : red > 65535 ? 65535 : red; + green = green < 0 ? 0 : green > 65535 ? 65535 : green; + blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; + alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; + + dest[x] = rgba((u8)(red/257UL), + (u8)(green/257UL), + (u8)(blue/257UL), + (u8)(alpha/257UL)); + } + + for(;x < columns-width/2;++x) + { + red = blue = green = alpha = 0.0; + p = kernel; + q = src+(x-width/2); + + for(i = 0;i < (long)width;++i) + { + red += (*p)*(q->r*257); + green += (*p)*(q->g*257); + blue += (*p)*(q->b*257); + alpha += (*p)*(q->a*257); + p++; + q++; + } + + red = scale*(red+0.5); + green = scale*(green+0.5); + blue = scale*(blue+0.5); + alpha = scale*(alpha+0.5); + + red = red < 0 ? 0 : red > 65535 ? 65535 : red; + green = green < 0 ? 0 : green > 65535 ? 65535 : green; + blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; + alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; + + dest[x] = rgba((u8)(red/257UL), + (u8)(green/257UL), + (u8)(blue/257UL), + (u8)(alpha/257UL)); + } + + for(;x < columns;++x) + { + red = blue = green = alpha = 0.0; + scale=0; + p = kernel; + q = src+(x-width/2); + + for(i = 0;i < columns-x+width/2;++i) + { + red += (*p)*(q->r*257); + green += (*p)*(q->g*257); + blue += (*p)*(q->b*257); + alpha += (*p)*(q->a*257); + scale += (*p); + p++; + q++; + } + + scale=1.0/scale; + red = scale*(red+0.5); + green = scale*(green+0.5); + blue = scale*(blue+0.5); + alpha = scale*(alpha+0.5); + + red = red < 0 ? 0 : red > 65535 ? 65535 : red; + green = green < 0 ? 0 : green > 65535 ? 65535 : green; + blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; + alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; + + dest[x] = rgba((u8)(red/257UL), + (u8)(green/257UL), + (u8)(blue/257UL), + (u8)(alpha/257UL)); + } +} + +static s32 getBlurKernel(s32 width, double sigma, double **kernel) +{ + +#define KernelRank 3 +#define KernelRankQ 18.0 + + double alpha, normalize; + long i; + s32 bias; + + if(sigma == 0.0) + return 0; + + if(width == 0) + width = 3; + + *kernel = new double [width]; + + if(!*kernel) + return 0; + + memset(*kernel, 0, width * sizeof(double)); + bias = KernelRank * width/2; + + for(i = (-bias);i <= bias; i++) + { + alpha = exp(-((double) i*i)/(KernelRankQ*sigma*sigma)); + (*kernel)[(i+bias)/KernelRank] += alpha/(MagickSQ2PI*sigma); + } + + normalize = 0; + + for(i = 0;i < width;i++) + normalize += (*kernel)[i]; + + for(i = 0;i < width;i++) + (*kernel)[i] /= normalize; + + return width; + +#undef KernelRankQ +#undef KernelRank + +} + +static void hull(const s32 x_offset, const s32 y_offset, const s32 polarity, const s32 columns, + const s32 rows, u8 *f, u8 *g) +{ + s32 x, y; + + u8 *p, *q, *r, *s; + u32 v; + + if(f == 0 || g == 0) + return; + + p = f+(columns+2); + q = g+(columns+2); + r = p+(y_offset*(columns+2)+x_offset); + + for(y = 0;y < rows;y++) + { + p++; + q++; + r++; + if(polarity > 0) + for(x = 0;x < columns;x++) + { + v=(*p); + if (*r > v) + v++; + *q=v > 255 ? 255 : v; + p++; + q++; + r++; + } + else + for(x = 0;x < columns;x++) + { + v=(*p); + if (v > (u32) (*r+1)) + v--; + *q=v; + p++; + q++; + r++; + } + p++; + q++; + r++; + } + + p = f+(columns+2); + q = g+(columns+2); + r = q+(y_offset*(columns+2)+x_offset); + s = q-(y_offset*(columns+2)+x_offset); + + for(y = 0;y < rows;y++) + { + p++; + q++; + r++; + s++; + + if(polarity > 0) + for(x=0; x < (s32) columns; x++) + { + v=(*q); + if (((u32) (*s+1) > v) && (*r > v)) + v++; + *p=v > 255 ? 255 : v; + p++; + q++; + r++; + s++; + } + else + for (x=0; x < columns; x++) + { + v=(*q); + if (((u32) (*s+1) < v) && (*r < v)) + v--; + *p=v; + p++; + q++; + r++; + s++; + } + + p++; + q++; + r++; + s++; + } +} + +static int getOptimalKernelWidth(double radius, double sigma) +{ + double normalize, value; + long width; + long u; + + if(sigma == 0.0) + sigma = 0.01; + + if(radius > 0.0) + return((int)(2.0*ceil(radius)+1.0)); + + const double S = sigma * sigma; + + for(width = 5;;) + { + normalize = 0.0; + + for(u = (-width/2);u <= (width/2);u++) + normalize+=exp(-((double) u*u)/(2.0*S))/(MagickSQ2PI*sigma); + + u = width/2; + value = exp(-((double) u*u)/(2.0*S))/(MagickSQ2PI*sigma)/normalize; + + if((long)(65535*value) <= 0) + break; + + width+=2; + } + + return ((int)width-2); +} + +} // namespace diff --git a/src/ksquirrelpart/fmt_filters.h b/src/ksquirrelpart/fmt_filters.h new file mode 100644 index 0000000..9f6cb5d --- /dev/null +++ b/src/ksquirrelpart/fmt_filters.h @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2005 Dmitry Baryshev <ksquirrel.iv@gmail.com> + */ + +/* + * All methods (except redeye) in this namespace are ported from KDE 3.2.3. + * All of them are copyrighted by their authors. See fmt_filters_README for more. + */ + +/* This file is part of the KDE libraries + Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org> + (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> + (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> + (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl> + (C) 2000 Josef Weidendorfer <weidendo@in.tum.de> + (C) 2004 Zack Rusin <zack@kde.org> + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +// +// =================================================================== +// Effects originally ported from ImageMagick for PixiePlus, plus a few +// new ones. (mosfet 05/26/2003) +// =================================================================== +// +/* + Portions of this software are based on ImageMagick. Such portions are clearly +marked as being ported from ImageMagick. ImageMagick is copyrighted under the +following conditions: + +Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated to +making software imaging solutions freely available. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files ("ImageMagick"), to deal +in ImageMagick without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of ImageMagick, and to permit persons to whom the ImageMagick is +furnished 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 ImageMagick. + +The software is provided "as is", without warranty of any kind, express or +implied, including but not limited to the warranties of merchantability, +fitness for a particular purpose and noninfringement. In no event shall +ImageMagick Studio be liable for any claim, damages or other liability, +whether in an action of contract, tort or otherwise, arising from, out of or +in connection with ImageMagick or the use or other dealings in ImageMagick. + +Except as contained in this notice, the name of the ImageMagick Studio shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in ImageMagick without prior written authorization from the +ImageMagick Studio. +*/ + +#ifndef FMT_FILTERS_H +#define FMT_FILTERS_H + +////////////////////////////////////////// +// // +// Pass the image through some filter // +// // +////////////////////////////////////////// + + +namespace fmt_filters +{ + typedef char s8; + typedef unsigned char u8; + + typedef short s16; + typedef unsigned short u16; + + typedef int s32; + typedef unsigned int u32; + + struct image + { + image() : data(0), w(0), h(0), rw(0), rh(0) + {} + + image(unsigned char *d, int _w, int _h) : data(d), w(_w), h(_h), rw(_w), rh(_h) + {} + + image(unsigned char *d, int _w, int _h, int _rw, int _rh) : data(d), w(_w), h(_h), rw(_rw), rh(_rh) + {} + + unsigned char *data; + int w; + int h; + int rw; + int rh; + }; + + struct rgb + { + rgb() : r(0), g(0), b(0) + {} + + rgb(int _r, int _g, int _b) : r(_r), g(_g), b(_b) + {} + + unsigned char r; + unsigned char g; + unsigned char b; + }; + + struct rgba + { + rgba(int r1, int g1, int b1, int a1) : r(r1), g(g1), b(b1), a(a1) + {} + + rgba() : r(0), g(0), b(0), a(0) + {} + + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + }; + + enum NoiseType + { + UniformNoise = 0, // Uniform distribution + GaussianNoise, // Gaussian distribution + MultiplicativeGaussianNoise, // Multiplicative Gaussian distribution + ImpulseNoise, // Impulse distribution + LaplacianNoise, // Laplacian distribution + PoissonNoise // Poisson distribution + }; + + + bool checkImage(const image &im); + + // colorize the image, which is w x h, left alpha channel unchanged. + // + // it just adds to each pixel in the image + // aproproriate value. + void colorize(const image &im, int red, int green, int blue); + + // change brightness of the image + void brightness(const image &im, int bn); + + // change gamma + // gamma should be 0.0 <= L <= 6.0 + // + // it is no problem to set L to 8.0 or 9.0, but the resulting + // image won't have much difference from 6.0 + void gamma(const image &im, double L); + + // change contrast with Photoshop-like method + // contrast should be -255 <= contrast <= 255 + void contrast(const image &im, int contrast); + + enum swapRGBtype { GBR = 0, BRG = 1 }; + + // negative + void negative(const image &im); + + // swap RGB values + void swapRGB(const image &im, int type); + + // + // All the following filters are ported from KDE's + // KImageEffect. See tdelibs/tdefx/kimageeffect.cpp + // for more. + // + + // blend + // opacity = [0.0; 1.0] + void blend(const image &im, const rgb &rgb, float opacity); + + // val = [0.0; 1.0] + void fade(const image &im, const rgb &rgb, float val); + + void gray(const image &im); + + // desat = [0.0; 1.0] + void desaturate(const image &im, float desat); + + // threshold = [0; 255] + void threshold(const image &im, unsigned int threshold); + + // factor = [0.0; 50.0] + void solarize(const image &im, double factor); + + // amount = [1; 10] + void spread(const image &im, unsigned int amount); + + // degrees = [-720.0; 720.0] + void swirl(const image &im, double degrees, const rgba &background); + + void noise(const image &im, NoiseType noise_type); + + void flatten(const image &im, const rgb &ca, const rgb &cb); + + // azimuth = [0.0; 90.0], elevation = [0.0; 90.0] + void shade(const image &im, bool color, double azimuth, double elevation); + + void equalize(const image &im); + + // radius = [0.01; 90.0], sigma = [0.01; 50.0] + void blur(const image &im, double radius, double sigma); + + void despeckle(const image &im); + + // factor = [0; 100] + void implode(const image &im, double factor, const rgba &background); + + // radius = [0.01; 30.0] + void edge(image &im, double radius); + + // radius = [0.01; 99.9], sigma = [0.01; 99.9] + void emboss(image &im, double radius, double sigma); + + // radius = [0.01; 99.9], sigma = [0.01; 30.0] + void sharpen(image &im, double radius, double sigma); + + // radius = [1.0; 5.0] + void oil(const image &im, double radius); + +/* + * Red-eye removal was taken from "redeye" plugin for GIMP + */ + +/* redeye.c: redeye remover plugin code + * + * Copyright (C) 2004 Robert Merkel <robert.merkel@benambra.org> (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 furnished 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, + * FITNESS 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 + * CONNECTION 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. +1;3B */ + + // red-eye removal. + // th = [0; 255] + void redeye(const image &im, const int w, const int h, + const int x, const int y, + int th); + + // Do we need some color definitions ? + static const rgba white = rgba(255, 255, 255, 255); + static const rgba black = rgba(0, 0, 0, 255); + static const rgba red = rgba(255, 0, 0, 255); + static const rgba green = rgba(0, 255, 0, 255); + static const rgba blue = rgba(0, 0, 255, 255); + static const rgba cyan = rgba(0, 255, 255, 255); + static const rgba magenta = rgba(255, 0, 255, 255); + static const rgba yellow = rgba(255, 255, 0, 255); + static const rgba mediumgray = rgba(128, 128, 128, 255); + static const rgba lightgray = rgba(160, 160, 164, 255); + static const rgba normalgray = rgba(192, 192, 192, 255); + static const rgba darkred = rgba(128, 0, 0, 255); + static const rgba darkgreen = rgba(0, 128, 0, 255); + static const rgba darkblue = rgba(0, 0, 128, 255); + static const rgba darkcyan = rgba(0, 128, 128, 255); + static const rgba darkmagenta = rgba(128, 0, 128, 255); + static const rgba darkyellow = rgba(128, 128, 0, 255); +} + +#endif diff --git a/src/ksquirrelpart/ksquirrelpart.cpp b/src/ksquirrelpart/ksquirrelpart.cpp new file mode 100644 index 0000000..7021e54 --- /dev/null +++ b/src/ksquirrelpart/ksquirrelpart.cpp @@ -0,0 +1,271 @@ +/*************************************************************************** + sq_ksquirrelpart.cpp - description + ------------------- + begin : Thu Nov 29 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <tdeaction.h> +#include <tdeparts/browserextension.h> +#include <tdeparts/genericfactory.h> +#include <tdefileitem.h> +#include <tdeglobal.h> +#include <tdelocale.h> +#include <kstandarddirs.h> +#include <kdebug.h> + +#include "ksquirrelpart.h" +#include "sq_glwidget.h" + +#include "sq_glview.h" +#include "sq_config.h" +#include "sq_diroperator.h" +#include "sq_libraryhandler.h" +#include "sq_iconloader.h" +#include "sq_externaltool.h" +#include "sq_errorstring.h" + +typedef KParts::GenericFactory<KSquirrelPart> KSquirrelFactory; +K_EXPORT_COMPONENT_FACTORY(libksquirrelpart, KSquirrelFactory) + +KSquirrelPart::KSquirrelPart(TQWidget *parentWidget, const char *, + TQObject* parent, const char *name, + const TQStringList &) : KParts::ReadOnlyPart(parent, name) +{ + kdDebug() << "+KSquirrelPart" << endl; + + setInstance(KSquirrelFactory::instance()); + + ext = new KSquirrelPartBrowserExtension(this); + + TDEGlobal::dirs()->addResourceType("data", TDEStandardDirs::kde_default("data") + TQString::fromLatin1("ksquirrel")); + TDEGlobal::locale()->setActiveCatalogue(KSquirrelFactory::instance()->instanceName()); + + if(!SQ_ErrorString::instance()) + new SQ_ErrorString(parentWidget); + + if(!SQ_Config::instance()) + new SQ_Config; + + if(!SQ_IconLoader::instance()) + new SQ_IconLoader; + + if(!SQ_ExternalTool::instance()) + new SQ_ExternalTool; + + SQ_ExternalTool::instance()->newPopupMenu(); + + // This will allow global object of SQ_LibraryHandler, which + // will exist until Konqueror will be closed + if(!SQ_LibraryHandler::instance()) + new SQ_LibraryHandler; + + new SQ_DirOperator; + + gl = new SQ_GLWidget(parentWidget, "ksquirrelpart-opengl-widget"); + gl->glInitA(); + + connect(gl, TQ_SIGNAL(message(const TQString &)), this, TQ_SIGNAL(setStatusBarText(const TQString&))); + setWidget(gl); + + TDEAction *a; + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_Plus)); + new TDEAction(i18n("Zoom +"), "zoom-in", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart zoom in"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_Minus)); + new TDEAction(i18n("Zoom -"), "zoom-out", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart zoom out"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_P)); + new TDEAction(i18n("Properties"), "image-x-generic", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart properties"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_R)); + new TDEAction(i18n("Normalize"), "rebuild", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart normalize"); + + // colorize & filters + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_D)); + new TDEAction(i18n("Color balance..."), "colorize", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart colorbalance"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_U)); + new TDEAction(i18n("Apply filter..."), "effect", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart filter"); + + // rotate + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_Left+CTRL)); + new TDEAction(i18n("Rotate left"), "object-rotate-left", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart rotateleft"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_Right+CTRL)); + new TDEAction(i18n("Rotate right"), "object-rotate-right", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart rotateright"); + + // copy/move + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_F5)); + new TDEAction(i18n("Copy to..."), "edit-copy", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart copyto"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_F7)); + new TDEAction(i18n("Move to..."), "edit-cut", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart moveto"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_F6)); + new TDEAction(i18n("Copy to last folder"), "", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart copy"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_F8)); + new TDEAction(i18n("Move to last folder"), "", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart move"); + + a = gl->actionCollection()->action(TQString("action_%1").arg(TQt::Key_S)); + new TDEAction(i18n("Save As..."), "document-save-as", 0, a, TQ_SLOT(activate()), actionCollection(), "ksquirrelpart saveas"); + + sa = new TDESelectAction(i18n("Zoom"), 0, actionCollection(), "ksquirrelpart zoom"); + sa->setEditable(true); + + TQStringList zooms; + zooms << TQString::number(10) + '%'; + zooms << TQString::number(25) + '%'; + zooms << TQString::number(33) + '%'; + zooms << TQString::number(50) + '%'; + zooms << TQString::number(75) + '%'; + zooms << TQString::number(100) + '%'; + zooms << TQString::number(150) + '%'; + zooms << TQString::number(200) + '%'; + zooms << TQString::number(250) + '%'; + zooms << TQString::number(300) + '%'; + zooms << TQString::number(350) + '%'; + zooms << TQString::number(400) + '%'; + zooms << TQString::number(450) + '%'; + zooms << TQString::number(500) + '%'; + zooms << TQString::number(600) + '%'; + zooms << TQString::number(700) + '%'; + zooms << TQString::number(800) + '%'; + zooms << TQString::number(900) + '%'; + zooms << TQString::number(1000) + '%'; + + sa->setItems(zooms); + sa->setCurrentItem(5); + connect(sa, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotZoom())); + + TQString group = "selection_group"; + + ar = new TDEToggleAction(i18n("Rectangle"), "rectangle", TDEShortcut(TQt::Key_R+CTRL), 0, 0, actionCollection(), "ksquirrelpart rectangle"); + ar->setExclusiveGroup(group); + connect(ar, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotSelectionRect(bool))); + + ae = new TDEToggleAction(i18n("Ellipse"), "circle", TDEShortcut(TQt::Key_E+CTRL), 0, 0, actionCollection(), "ksquirrelpart ellipse"); + ae->setExclusiveGroup(group); + connect(ae, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotSelectionEllipse(bool))); + + setXMLFile("ksquirrelpart/ksquirrelpart.rc"); +} + +KSquirrelPart::~KSquirrelPart() +{ + kdDebug() << "-KSquirrelPart" << endl; +} + +void KSquirrelPart::slotZoom() +{ + bool ok; + + int z = sa->currentText().replace(TQChar('%'), "").toInt(&ok); + + if(ok) + gl->zoom((float)z / 100.0f); +} + +void KSquirrelPart::slotSelectionRect(bool b) +{ + if(b) + gl->slotSelectionRect(); + else if(!ae->isChecked()) + gl->slotSelectionClear(); +} + +void KSquirrelPart::slotSelectionEllipse(bool b) +{ + if(b) + gl->slotSelectionEllipse(); + else if(!ar->isChecked()) + gl->slotSelectionClear(); +} + +void KSquirrelPart::print() +{ + gl->slotPrint(); +} + +TDEAboutData* KSquirrelPart::createAboutData() +{ + TDEAboutData *kAboutData = new TDEAboutData( + "ksquirrel", + I18N_NOOP("KSquirrelPart"), + "0.1.2", + I18N_NOOP("Image Viewer"), + TDEAboutData::License_GPL, + "(c) 2007, Dmitry Baryshev <ksquirrel.iv@gmail.com>"); + + return kAboutData; +} + +bool KSquirrelPart::openFile() +{ + emit started(0); + + KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, m_url); + SQ_DirOperator::instance()->execute(&fi); + + emit setWindowCaption(m_url.prettyURL()); + + emit completed(0); + + return true; +} + +void KSquirrelPart::setKonquerorWindowCaption(const KURL &, const TQString &filename) +{ + TQString caption = TQString("%1").arg(filename); + emit setWindowCaption(caption); +} + +void KSquirrelPart::partActivateEvent(KParts::PartActivateEvent *e) +{ + if(e->activated()) + { + if(!gl->manualBlocked()) + gl->startAnimation(); + } + else + { + // stop animation when KPart becomes inactive + gl->stopAnimation(); + + SQ_LibraryHandler::instance()->sync(); + SQ_Config::instance()->sync(); + } + + KParts::ReadOnlyPart::partActivateEvent(e); +} + +/***************************************************************/ + +KSquirrelPartBrowserExtension::KSquirrelPartBrowserExtension(KSquirrelPart *viewPart, const char *name) + :KParts::BrowserExtension(viewPart, name) +{ + mPart = viewPart; + emit enableAction("print", true); +} + +KSquirrelPartBrowserExtension::~KSquirrelPartBrowserExtension() +{} + +void KSquirrelPartBrowserExtension::print() +{ + mPart->print(); +} + +#include "ksquirrelpart.moc" diff --git a/src/ksquirrelpart/ksquirrelpart.desktop b/src/ksquirrelpart/ksquirrelpart.desktop new file mode 100644 index 0000000..b4f7e9e --- /dev/null +++ b/src/ksquirrelpart/ksquirrelpart.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Service +MimeType=image/x-vnd.adobe.photoshop;image/x-hdr;image/x-exr;image/x-eps;image/x-psp;image/x-dds;image/x-mdl;image/ljpeg;image/x-dicom;image/x-xfig;image/svg+xml;image/gif;image/x-xpm;image/x-xbm;image/jpeg;image/x-bmp;image/png;image/tiff;image/x-portable-bitmap;image/x-portable-pixmap;image/x-portable-anymap;image/x-portable-greymap;image/jp2;image/x-jng;image/x-wmf;video/x-mng;video/x-flic;image/x-targa;image/x-pcx;image/x-photo-cd;image/x-rgb;image/x-xcursor;image/x-ico;image/psd;image/x-djvu;image/x-xcf-gimp;image/x-avs;image/x-cut;image/x-dxf;image/x-iff;image/x-jbig;image/x-koala;image/x-leaf;image/x-lif;image/x-mac;image/x-msp;image/x-mtv;image/x-neo;image/x-pi1;image/x-pi3;image/x-pict;image/x-pix;image/x-pxr;image/x-ras;image/x-raw;image/x-rawrgb;image/x-sct;image/x-sun;image/x-utah;image/x-wal;image/x-wbmp;image/x-xim;image/x-xwd;application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1 +X-TDE-ServiceTypes=KParts/ReadOnlyPart +X-TDE-Library=libksquirrelpart +X-TDE-InitialPreference=5 +Icon=ksquirrel + +Name=KSquirrel Image Viewer +Name[ru]=KSquirrel Просмотр изображений +Name[de]=KSquirrel Bildbetrachter diff --git a/src/ksquirrelpart/ksquirrelpart.h b/src/ksquirrelpart/ksquirrelpart.h new file mode 100644 index 0000000..0c2a91f --- /dev/null +++ b/src/ksquirrelpart/ksquirrelpart.h @@ -0,0 +1,89 @@ +/*************************************************************************** + sq_ksquirrelpart.h - description + ------------------- + begin : Thu Nov 29 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KSQUIRRELPART_H +#define KSQUIRRELPART_H + +#include <tdeparts/part.h> + +class TDEAboutData; +class TDEToggleAction; +class TDESelectAction; + +class SQ_GLWidget; + +class KSquirrelPart; + +class KSquirrelPartBrowserExtension: public KParts::BrowserExtension +{ + TQ_OBJECT + + + public: + KSquirrelPartBrowserExtension(KSquirrelPart* viewPart, const char *name = 0); + ~KSquirrelPartBrowserExtension(); + + public slots: + void print(); + + private: + KSquirrelPart *mPart; +}; + +/***********************************************************/ + +class KSquirrelPart : public KParts::ReadOnlyPart +{ + TQ_OBJECT + + + public: + KSquirrelPart(TQWidget*, const char*, TQObject*, const char*, const TQStringList &); + virtual ~KSquirrelPart(); + + static TDEAboutData* createAboutData(); + + TQString filePath(); + + void print(); + + protected: + void partActivateEvent(KParts::PartActivateEvent *); + + protected slots: + virtual bool openFile(); + virtual void setKonquerorWindowCaption(const KURL &url, const TQString &filename); + + private slots: + void slotSelectionRect(bool); + void slotSelectionEllipse(bool); + void slotZoom(); + + private: + SQ_GLWidget *gl; + TDEToggleAction *ar, *ae; + TDESelectAction *sa; + KSquirrelPartBrowserExtension *ext; +}; + +inline +TQString KSquirrelPart::filePath() +{ + return m_file; +} + +#endif diff --git a/src/ksquirrelpart/ksquirrelpart.rc b/src/ksquirrelpart/ksquirrelpart.rc new file mode 100644 index 0000000..10aa894 --- /dev/null +++ b/src/ksquirrelpart/ksquirrelpart.rc @@ -0,0 +1,20 @@ +<!DOCTYPE kpartgui> +<kpartgui name="KSquirrelPart"> +<ToolBar name="mainToolBar"><text>Main Toolbar</text> + <Separator/> + + <Action name="ksquirrelpart zoom in"/> + <Action name="ksquirrelpart zoom out"/> + <Action name="ksquirrelpart rotateleft"/> + <Action name="ksquirrelpart rotateright"/> + + <Separator/> + + <Action name="ksquirrelpart normalize"/> + <Action name="ksquirrelpart properties"/> + + <Action name="ksquirrelpart saveas"/> + <Action name="ksquirrelpart zoom"/> + +</ToolBar> +</kpartgui> diff --git a/src/ksquirrelpart/sq_bcglabel.cpp b/src/ksquirrelpart/sq_bcglabel.cpp new file mode 100644 index 0000000..41395e3 --- /dev/null +++ b/src/ksquirrelpart/sq_bcglabel.cpp @@ -0,0 +1,28 @@ +/*************************************************************************** + sq_bcglabel.cpp - description + ------------------- + begin : ??? May 4 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "sq_bcglabel.h" + +SQ_BCGLabel::SQ_BCGLabel(TQWidget *parent, const char *name, WFlags f) : TQLabel(parent, name, f | TQt::WNoAutoErase) +{ + setScaledContents(false); + + setAlignment(TQt::AlignHCenter | TQt::AlignVCenter); +} + +SQ_BCGLabel::~SQ_BCGLabel() +{} diff --git a/src/ksquirrelpart/sq_bcglabel.h b/src/ksquirrelpart/sq_bcglabel.h new file mode 100644 index 0000000..d8546a9 --- /dev/null +++ b/src/ksquirrelpart/sq_bcglabel.h @@ -0,0 +1,34 @@ +/*************************************************************************** + sq_bcglabel.h - description + ------------------- + begin : ??? May 4 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_BCGLABEL_H +#define SQ_BCGLABEL_H + +#include <tqlabel.h> + +/** + *@author Baryshev Dmitry + */ + +class SQ_BCGLabel : public TQLabel +{ + public: + SQ_BCGLabel(TQWidget *parent, const char *name = 0, WFlags f = 0); + ~SQ_BCGLabel(); +}; + +#endif diff --git a/src/ksquirrelpart/sq_codecsettings.cpp b/src/ksquirrelpart/sq_codecsettings.cpp new file mode 100644 index 0000000..47b3609 --- /dev/null +++ b/src/ksquirrelpart/sq_codecsettings.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + sq_codecsettings.cpp - description + ------------------- + begin : Mon Mar 5 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <ksquirrel-libs/fmt_codec_base.h> + +#include "sq_codecsettings.h" +#include "sq_library.h" +#include "sq_config.h" + +void SQ_CodecSettings::applySettings(SQ_LIBRARY *lib, SQ_CodecSettings::settings fromwhere) +{ + SQ_Config::instance()->setGroup("Main"); + + int set = SQ_Config::instance()->readNumEntry("applyto", SQ_CodecSettings::Both); + + // thumbnail loader and image viewer will use default settings + if((fromwhere == SQ_CodecSettings::ThumbnailLoader && (set == SQ_CodecSettings::ThumbnailLoader || set == SQ_CodecSettings::Both)) + || (fromwhere == SQ_CodecSettings::ImageViewer && (set == SQ_CodecSettings::ImageViewer || set == SQ_CodecSettings::Both))) + { + lib->codec->set_settings(lib->settings); + lib->codec_il->set_settings(lib->settings); + } + else + { + lib->codec->fill_default_settings(); + lib->codec_il->fill_default_settings(); + } +} diff --git a/src/ksquirrelpart/sq_codecsettings.h b/src/ksquirrelpart/sq_codecsettings.h new file mode 100644 index 0000000..f789e9f --- /dev/null +++ b/src/ksquirrelpart/sq_codecsettings.h @@ -0,0 +1,34 @@ +/*************************************************************************** + sq_codecsettings.h - description + ------------------- + begin : Mon Mar 5 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_CODECSETTINGS_H +#define SQ_CODECSETTINGS_H + +/** + *@author Baryshev Dmitry + */ + +struct SQ_LIBRARY; + +struct SQ_CodecSettings +{ + enum settings { ThumbnailLoader = 0, ImageViewer, Both, RunTume, None }; + + static void applySettings(SQ_LIBRARY *l, SQ_CodecSettings::settings fromwhere); +}; + +#endif diff --git a/src/ksquirrelpart/sq_codecsettingsskeleton.ui b/src/ksquirrelpart/sq_codecsettingsskeleton.ui new file mode 100644 index 0000000..1314543 --- /dev/null +++ b/src/ksquirrelpart/sq_codecsettingsskeleton.ui @@ -0,0 +1,217 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>SQ_CodecSettingsSkeleton</class> +<widget class="TQDialog"> + <property name="name"> + <cstring>SQ_CodecSettingsSkeleton</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>283</width> + <height>335</height> + </rect> + </property> + <property name="caption"> + <string>Codec settings</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>codecIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="Line" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>codecName</cstring> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQGroupBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>groupBox</cstring> + </property> + <property name="title"> + <string></string> + </property> + </widget> + <widget class="Line" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLayoutWidget" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushApply</cstring> + </property> + <property name="text"> + <string>Apply</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushOK</cstring> + </property> + <property name="text"> + <string>OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushCancel</cstring> + </property> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>pushOK</sender> + <signal>clicked()</signal> + <receiver>SQ_CodecSettingsSkeleton</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>pushCancel</sender> + <signal>clicked()</signal> + <receiver>SQ_CodecSettingsSkeleton</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>pushApply</sender> + <signal>clicked()</signal> + <receiver>SQ_CodecSettingsSkeleton</receiver> + <slot>slotApply()</slot> + </connection> +</connections> +<tabstops> + <tabstop>pushOK</tabstop> + <tabstop>pushApply</tabstop> + <tabstop>pushCancel</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in declaration">ksquirrel-libs/settings.h</include> + <include location="global" impldecl="in implementation">tqcheckbox.h</include> + <include location="global" impldecl="in implementation">tqmessagebox.h</include> + <include location="global" impldecl="in implementation">tqobjectlist.h</include> + <include location="global" impldecl="in implementation">tqbuttongroup.h</include> + <include location="global" impldecl="in implementation">tqslider.h</include> + <include location="global" impldecl="in implementation">kurlrequester.h</include> + <include location="global" impldecl="in implementation">knuminput.h</include> + <include location="global" impldecl="in implementation">tqwidgetfactory.h</include> + <include location="global" impldecl="in implementation">tqspinbox.h</include> + <include location="global" impldecl="in implementation">tqtextedit.h</include> + <include location="global" impldecl="in implementation">kurl.h</include> + <include location="global" impldecl="in implementation">kcolorbutton.h</include> + <include location="local" impldecl="in implementation">sq_codecsettingsskeleton.ui.h</include> +</includes> +<variables> + <variable access="private">TQWidget *w;</variable> + <variable access="private">fmt_settings *sett;</variable> +</variables> +<signals> + <signal>apply();</signal> +</signals> +<slots> + <slot access="private" specifier="non virtual">slotApply()</slot> +</slots> +<functions> + <function access="private" specifier="non virtual">init()</function> + <function specifier="non virtual">addSettingsWidget( const TQString & path )</function> + <function access="private" specifier="non virtual">recursivelyReadWrite( fmt_settings & settings, bool r )</function> + <function returnType="int">exec( fmt_settings & settings )</function> + <function specifier="non virtual">setCodecInfo( const TQPixmap & pixmap, const TQString & text )</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/ksquirrelpart/sq_codecsettingsskeleton.ui.h b/src/ksquirrelpart/sq_codecsettingsskeleton.ui.h new file mode 100644 index 0000000..d976149 --- /dev/null +++ b/src/ksquirrelpart/sq_codecsettingsskeleton.ui.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** TQt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +void SQ_CodecSettingsSkeleton::init() +{ + w = 0; + sett = 0; +} + +void SQ_CodecSettingsSkeleton::addSettingsWidget(const TQString &path) +{ + w = TQWidgetFactory::create(path, 0, this, "skeleton_settings"); + TQWidget *fake; + + if(w) + fake = w; + else + { + pushApply->setEnabled(false); + pushOK->setEnabled(false); + + TQTextEdit *t = new TQTextEdit(i18n("Error loading widget from <b>%1</b>. Please check your installation or contact <a href=\"mailto:ksquirrel.iv@gmail.com\">ksquirrel.iv@gmail.com</a>").arg(path), TQString(), groupBox); + t->setReadOnly(true); + fake = t; + } + + fake->reparent(groupBox, TQPoint(0,0), true); + + TQGridLayout *grid = new TQGridLayout(groupBox, 1, 1, 11, 6); + grid->addMultiCellWidget(fake, 1, 1, 0, 3); + + TQSpacerItem *spacer = new TQSpacerItem(15, 1, TQSizePolicy::Minimum, TQSizePolicy::Expanding); + grid->addItem(spacer, 2, 1); +} + +void SQ_CodecSettingsSkeleton::recursivelyReadWrite(fmt_settings &settings, bool r) +{ + if(!w) + return; + + TQObjectList ch = w->childrenListObject(); + fmt_settings::iterator t; + + for(TQObjectList::iterator it = ch.begin();it != ch.end();++it) + { + t = settings.find((*it)->name()); + + if((*it)->inherits("TQCheckBox")) + { + TQCheckBox *c = dynamic_cast<TQCheckBox *>(*it); + + if(c && t != settings.end()) + { + if(r) + c->setChecked((*t).second.bVal); + else + (*t).second.bVal = c->isChecked(); + } + } + else if((*it)->inherits("TQButtonGroup")) + { + TQButtonGroup *c = dynamic_cast<TQButtonGroup *>(*it); + + if(c && t != settings.end()) + { + if(r) + c->setButton((*t).second.iVal); + else + (*t).second.iVal = c->selectedId(); + } + } + else if((*it)->inherits("TQSlider")) + { + TQSlider *c = dynamic_cast<TQSlider *>(*it); + + if(c && t != settings.end()) + { + if(r) + c->setValue((*t).second.iVal); + else + (*t).second.iVal = c->value(); + } + } + else if((*it)->inherits("KURLRequester")) + { + KURLRequester *u = dynamic_cast<KURLRequester *>(*it); + + if(u && t != settings.end()) + { + if(r) + u->setURL((*t).second.sVal); + else + { + KURL url = u->url(); // get rid of "file://" if present + (*t).second.sVal = url.isEmpty() ? "" : url.path().ascii(); + } + } + } + else if((*it)->inherits("KDoubleSpinBox")) + { + KDoubleSpinBox *d = dynamic_cast<KDoubleSpinBox *>(*it); + + if(d && t != settings.end()) + { + if(r) + d->setValue((*t).second.dVal); + else + (*t).second.dVal = d->value(); + } + } + // TQSpinBox should be checked after KDoubleSpinBox ! + else if((*it)->inherits("TQSpinBox")) + { + TQSpinBox *c = dynamic_cast<TQSpinBox *>(*it); + + if(c && t != settings.end()) + { + if(r) + c->setValue((*t).second.iVal); + else + (*t).second.iVal = c->value(); + } + } + else if((*it)->inherits("KColorButton")) + { + KColorButton *c = dynamic_cast<KColorButton *>(*it); + + if(c && t != settings.end()) + { + if(r) + c->setColor(TQColor(TQString((*t).second.sVal))); + else + (*t).second.sVal = TQString(c->color().name()).ascii(); + } + } + } +} + +int SQ_CodecSettingsSkeleton::exec(fmt_settings &settings) +{ + // read settings + recursivelyReadWrite(settings, true); + + sett = &settings; + + int result = TQDialog::exec(); + + // save settings + if(result == TQDialog::Accepted) + recursivelyReadWrite(settings, false); + + return result; +} + +void SQ_CodecSettingsSkeleton::setCodecInfo( const TQPixmap &pixmap, const TQString &text ) +{ + codecIcon->setPixmap(pixmap); + codecName->setText(text); +} + +void SQ_CodecSettingsSkeleton::slotApply() +{ + recursivelyReadWrite(*sett, false); + emit apply(); +} diff --git a/src/ksquirrelpart/sq_config.cpp b/src/ksquirrelpart/sq_config.cpp new file mode 100644 index 0000000..ea0fc4b --- /dev/null +++ b/src/ksquirrelpart/sq_config.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + sq_config.cpp - description + ------------------- + begin : ??? ??? 14 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sq_config.h" + +SQ_Config * SQ_Config::m_instance = 0; + +SQ_Config::SQ_Config(TQObject *parent) : TQObject(parent) +{ + m_instance = this; + + tdeconf = new TDEConfig("ksquirrelrc"); +} + +SQ_Config::~SQ_Config() +{ + delete tdeconf; +} diff --git a/src/ksquirrelpart/sq_config.h b/src/ksquirrelpart/sq_config.h new file mode 100644 index 0000000..73cf0c4 --- /dev/null +++ b/src/ksquirrelpart/sq_config.h @@ -0,0 +1,136 @@ +/*************************************************************************** + sq_config.h - description + ------------------- + begin : ??? ??? 14 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_CONFIG_H +#define SQ_CONFIG_H + +#include <tqobject.h> +#include <tdeconfig.h> + +class TDEConfig; + +/* + * Class for reading/writing config file + */ + +class SQ_Config : public TQObject +{ + public: + SQ_Config(TQObject *parent = 0); + ~SQ_Config(); + + static SQ_Config* instance() { return m_instance; } + + void sync(); + + void setGroup(const TQString &group); + bool hasGroup(const TQString &group) const; + bool deleteGroup( const TQString& group, bool bDeep = true, bool bGlobal = false ); + TQString readEntry(const TQString& pKey, const TQString& aDefault = TQString() ) const; + TQStringList readListEntry( const TQString& pKey, char sep = ',' ) const; + int readNumEntry( const TQString& pKey, int nDefault = 0 ) const; + bool readBoolEntry( const TQString& pKey, bool bDefault = false ) const; + TQRect readRectEntry( const TQString& pKey, const TQRect* pDefault = 0L ) const; + TQPoint readPointEntry( const TQString& pKey, const TQPoint* pDefault = 0L ) const; + TQSize readSizeEntry( const TQString& pKey, const TQSize* pDefault = 0L ) const; + double readDoubleNumEntry( const TQString& pKey, double nDefault = 0.0 ) const; + TQValueList<int> readIntListEntry( const TQString& pKey ) const; + + void writeEntry( const TQString& pKey, const TQString& pValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, const TQStringList &rValue, char sep = ',', bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, int nValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, bool bValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, const TQRect& rValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, const TQPoint& rValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, const TQSize& rValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + void writeEntry( const TQString& pKey, double nValue, bool bPersistent = true, bool bGlobal = false, char format = 'g', int precision = 6, bool bNLS = false ); + void writeEntry( const TQString& pKey, const TQValueList<int>& rValue, bool bPersistent = true, bool bGlobal = false, bool bNLS = false ); + + private: + TDEConfig *tdeconf; + static SQ_Config *m_instance; +}; + +inline +void SQ_Config::sync() { tdeconf->sync(); } + +inline +void SQ_Config::setGroup(const TQString &group) { tdeconf->setGroup(group) ; } + +inline +bool SQ_Config::hasGroup(const TQString &group) const { return tdeconf->hasGroup(group) ; } + +inline +bool SQ_Config::deleteGroup(const TQString& group, bool bDeep, bool bGlobal) { return tdeconf->deleteGroup(group, bDeep, bGlobal) ; } + +inline +TQString SQ_Config::readEntry(const TQString& pKey, const TQString& aDefault) const { return tdeconf->readEntry(pKey, aDefault) ; } + +inline +TQStringList SQ_Config::readListEntry(const TQString& pKey, char sep) const { return tdeconf->readListEntry(pKey, sep) ; } + +inline +int SQ_Config::readNumEntry(const TQString& pKey, int nDefault) const { return tdeconf->readNumEntry(pKey, nDefault) ; } + +inline +bool SQ_Config::readBoolEntry(const TQString& pKey, bool bDefault) const { return tdeconf->readBoolEntry(pKey, bDefault ) ; } + +inline +TQRect SQ_Config::readRectEntry(const TQString& pKey, const TQRect* pDefault) const { return tdeconf->readRectEntry(pKey, pDefault) ; } + +inline +TQPoint SQ_Config::readPointEntry(const TQString& pKey, const TQPoint* pDefault) const { return tdeconf->readPointEntry(pKey, pDefault) ; } + +inline +TQSize SQ_Config::readSizeEntry(const TQString& pKey, const TQSize* pDefault) const { return tdeconf->readSizeEntry(pKey, pDefault) ; } + +inline +double SQ_Config::readDoubleNumEntry(const TQString& pKey, double nDefault) const { return tdeconf->readDoubleNumEntry(pKey, nDefault); } + +inline +TQValueList<int> SQ_Config::readIntListEntry( const TQString& pKey ) const { return tdeconf->readIntListEntry(pKey); } + +/**********************************************/ + +inline +void SQ_Config::writeEntry(const TQString& pKey, const TQString& pValue, bool bPersistent, bool bGlobal, bool bNLS) { tdeconf->writeEntry( pKey, pValue, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry(const TQString& pKey, const TQStringList &rValue, char sep, bool bPersistent, bool bGlobal, bool bNLS ) { tdeconf->writeEntry(pKey, rValue, sep, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry(const TQString& pKey, int nValue, bool bPersistent, bool bGlobal, bool bNLS ) { tdeconf->writeEntry(pKey, nValue, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry(const TQString& pKey, bool bValue, bool bPersistent, bool bGlobal, bool bNLS ) { tdeconf->writeEntry(pKey, bValue, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry(const TQString& pKey, const TQRect& rValue, bool bPersistent, bool bGlobal, bool bNLS ) { tdeconf->writeEntry(pKey, rValue, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry(const TQString& pKey, const TQPoint& rValue, bool bPersistent, bool bGlobal, bool bNLS ) { tdeconf->writeEntry(pKey, rValue, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry(const TQString& pKey, const TQSize& rValue, bool bPersistent, bool bGlobal, bool bNLS ) { tdeconf->writeEntry(pKey,rValue, bPersistent, bGlobal, bNLS ) ; } + +inline +void SQ_Config::writeEntry( const TQString& pKey, double nValue, bool bPersistent, bool bGlobal, char format, int precision, bool bNLS) { tdeconf->writeEntry(pKey, nValue, bPersistent, bGlobal, format, precision, bNLS); } + +inline +void SQ_Config::writeEntry( const TQString& pKey, const TQValueList<int>& rValue, bool bPersistent, bool bGlobal, bool bNLS) { tdeconf->writeEntry(pKey, rValue, bPersistent, bGlobal, bNLS); } + +#endif diff --git a/src/ksquirrelpart/sq_diroperator.cpp b/src/ksquirrelpart/sq_diroperator.cpp new file mode 100644 index 0000000..bf2232f --- /dev/null +++ b/src/ksquirrelpart/sq_diroperator.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + sq_diroperator.cpp - description + ------------------- + begin : Thu Nov 29 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <kurl.h> +#include <konq_operations.h> + +#include "sq_diroperator.h" +#include "sq_libraryhandler.h" +#include "sq_downloader.h" +#include "sq_glwidget.h" + +SQ_DirOperator * SQ_DirOperator::m_inst = 0; + +SQ_DirOperator::SQ_DirOperator(TQObject *parent) : TQObject(parent) +{ + m_inst = this; + + down = new SQ_Downloader(this, "SQ_Downloader [dirop]"); + + connect(down, TQ_SIGNAL(result(const KURL &)), this, TQ_SLOT(slotDownloaderResult(const KURL &))); + connect(down, TQ_SIGNAL(percents(int)), this, TQ_SLOT(slotDownloadPercents(int))); +} + +SQ_DirOperator::~SQ_DirOperator() +{} + +void SQ_DirOperator::execute(KFileItem *fi) +{ + down->kill(); + + SQ_GLWidget::window()->setOriginalURL(fi->url()); + + if(fi->url().isLocalFile()) + executePrivate(fi); + else if(SQ_LibraryHandler::instance()->maybeSupported(fi->url(), fi->mimetype()) != SQ_LibraryHandler::No) + down->start(fi); +} + +void SQ_DirOperator::slotDownloaderResult(const KURL &url) +{ + SQ_GLWidget::window()->setDownloadPercents(-1); + + if(url.isEmpty()) + return; + + KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, url); + + executePrivate(&fi); +} + +void SQ_DirOperator::executePrivate(KFileItem *fi) +{ + TQString fullpath = fi->url().path(); + + if(SQ_LibraryHandler::instance()->libraryForFile(fullpath)) + SQ_GLWidget::window()->startDecoding(fullpath); +} + +void SQ_DirOperator::slotDownloadPercents(int p) +{ + SQ_GLWidget::window()->setDownloadPercents(p); +} + +void SQ_DirOperator::del(const KURL &u, TQWidget *parent) +{ + KURL::List list; + list.append(u); + + KonqOperations::del(parent, KonqOperations::DEL, list); +} + +#include "sq_diroperator.moc" diff --git a/src/ksquirrelpart/sq_diroperator.h b/src/ksquirrelpart/sq_diroperator.h new file mode 100644 index 0000000..73eceac --- /dev/null +++ b/src/ksquirrelpart/sq_diroperator.h @@ -0,0 +1,58 @@ +/*************************************************************************** + sq_diroperator.h - description + ------------------- + begin : Thu Nov 29 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_DIROPERATOR_H +#define SQ_DIROPERATOR_H + +#include <tdefileitem.h> + +#include <tqobject.h> + +class SQ_Downloader; + +class KURL; + +class SQ_DirOperator : public TQObject +{ + TQ_OBJECT + + + public: + SQ_DirOperator(TQObject *parent = 0); + ~SQ_DirOperator(); + + static SQ_DirOperator* instance() { return m_inst; } + + void execute(KFileItem *item); + + void del(const KURL &u, TQWidget *parent = 0); + + private: + void executePrivate(KFileItem *); + + private slots: + + void slotDownloadPercents(int); + void slotDownloaderResult(const KURL &); + + private: + SQ_Downloader *down; + + static SQ_DirOperator *m_inst; +}; + +#endif diff --git a/src/ksquirrelpart/sq_downloader.cpp b/src/ksquirrelpart/sq_downloader.cpp new file mode 100644 index 0000000..e877850 --- /dev/null +++ b/src/ksquirrelpart/sq_downloader.cpp @@ -0,0 +1,143 @@ +/*************************************************************************** + sq_downloader.cpp - description + ------------------- + begin : Fri Jun 07 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <tqfile.h> + +#include <tdeio/job.h> +#include <tdefileitem.h> +#include <tdetempfile.h> + +#include "sq_libraryhandler.h" +#include "sq_downloader.h" + +#ifndef KSQUIRREL_PART +#include "sq_archivehandler.h" +#endif + +#define SQ_PREDOWNLOAD_SIZE 50 + +SQ_Downloader::SQ_Downloader(TQObject *parent, const char *name) : TQObject(parent, name), job(0), m_error(false) +{ + tmp = new KTempFile; + tmp->setAutoDelete(true); + tmp->close(); +} + +SQ_Downloader::~SQ_Downloader() +{ + clean(); + + delete tmp; +} + +void SQ_Downloader::start(KFileItem *fi) +{ + m_error = false; + mURL = fi->url(); + + emitPercents = false; + startTime = TQTime::currentTime(); + size = 0; + totalSize = fi->size(); + +#ifndef KSQUIRREL_PART + nomime = SQ_ArchiveHandler::instance()->findProtocolByMime(fi->mimetype()).isEmpty(); +#else + nomime = true; +#endif + + job = TDEIO::get(mURL, false, false); + + clean(); + + continueDownload = false; + + connect(job, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), this, TQ_SLOT(slotData(TDEIO::Job *, const TQByteArray &))); + connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotDataResult(TDEIO::Job *))); +} + +void SQ_Downloader::slotData(TDEIO::Job *job, const TQByteArray &ba) +{ + size += ba.size(); + + TQFile f(tmp->name()); + + if(f.open(IO_WriteOnly | IO_Append)) + { + f.writeBlock(ba); + f.close(); + } + + if(emitPercents || startTime.msecsTo(TQTime::currentTime()) > 1000) + { + emit percents(size); + emitPercents = true; + } + + // 50 bytes are enough to determine file type + if(size >= SQ_PREDOWNLOAD_SIZE && !continueDownload && totalSize != size) + { + // cancel download (file type is not supported) + SQ_LIBRARY *lib = SQ_LibraryHandler::instance()->libraryForFile(tmp->name()); + + if(nomime && !lib) + { + job->kill(false); // kill job & emit result + } + else + { + // nice, we can open this image/archive - continue download + continueDownload = true; + } + } +} + +void SQ_Downloader::slotDataResult(TDEIO::Job *cpjob) +{ + job = 0; + + // job error + if(cpjob->error() && cpjob->error() != TDEIO::ERR_USER_CANCELED) + { + m_error = true; + emit result(mEmptyURL); + } + else if(cpjob->error() == TDEIO::ERR_USER_CANCELED) // not supported image/archive type - + // emit empty url without errors + { + emit result(mEmptyURL); + } + else // supported image type/archive type (no errors or job killed) + { + emit result(KURL::fromPathOrURL(tmp->name())); + } +} + +void SQ_Downloader::clean() +{ + TQFile f(tmp->name()); + + if(f.open(IO_WriteOnly)) + f.close(); +} + +void SQ_Downloader::kill() +{ + if(job) job->kill(); +} + +#include "sq_downloader.moc" diff --git a/src/ksquirrelpart/sq_downloader.h b/src/ksquirrelpart/sq_downloader.h new file mode 100644 index 0000000..6b91a3f --- /dev/null +++ b/src/ksquirrelpart/sq_downloader.h @@ -0,0 +1,74 @@ +/*************************************************************************** + sq_downloader.h - description + ------------------- + begin : Fri Jun 07 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_DOWNLOADER_H +#define SQ_DOWNLOADER_H + +#include <tqobject.h> +#include <tqdatetime.h> + +#include <kurl.h> + +class KFileItem; +class KTempFile; + +namespace TDEIO { class Job; } + +class SQ_Downloader : public TQObject +{ + TQ_OBJECT + + + public: + SQ_Downloader(TQObject *parent = 0, const char *name = 0); + ~SQ_Downloader(); + + void start(KFileItem *fi); + + bool error() const; + + void clean(); + + void kill(); + + signals: + void result(const KURL &); + void percents(int); + + private slots: + void slotData(TDEIO::Job *job, const TQByteArray &data); + void slotDataResult(TDEIO::Job *); + + private: + TDEIO::Job *job; + KURL mEmptyURL, mURL; + KTempFile *tmp; + TDEIO::filesize_t totalSize, size; + bool continueDownload; + bool nomime; + bool m_error, m_lightmode; + TQTime startTime; + bool emitPercents; +}; + +inline +bool SQ_Downloader::error() const +{ + return m_error; +} + +#endif diff --git a/src/ksquirrelpart/sq_errorstring.cpp b/src/ksquirrelpart/sq_errorstring.cpp new file mode 100644 index 0000000..f762ee3 --- /dev/null +++ b/src/ksquirrelpart/sq_errorstring.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + sq_errorstring.cpp - description + ------------------- + begin : ??? ??? 26 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sq_errorstring.h" + +#include <ksquirrel-libs/error.h> + +SQ_ErrorString * SQ_ErrorString::m_instance = 0; + +SQ_ErrorString::SQ_ErrorString(TQObject *parent) : TQObject(parent) +{ + m_instance = this; + + // fill map with translated messages + messages.insert(SQE_OK, TQString::fromLatin1("OK")); + messages.insert(SQE_R_NOFILE, i18n("cannot open file for reading")); + messages.insert(SQE_R_BADFILE, i18n("file corrupted")); + messages.insert(SQE_R_NOMEMORY, i18n("no memory")); + messages.insert(SQE_R_NOTSUPPORTED, i18n("file type not supported")); + messages.insert(SQE_R_WRONGDIM, i18n("wrong image dimensions")); + messages.insert(SQE_W_NOFILE, i18n("cannot open file for writing")); + messages.insert(SQE_W_NOTSUPPORTED, i18n("write feature is not supported")); + messages.insert(SQE_W_ERROR, i18n("write error (check free space)")); + messages.insert(SQE_W_WRONGPARAMS, i18n("wrong parameters")); + messages.insert(SQE_NOTFINISHED, i18n("Editing process is not finished yet")); +} + +SQ_ErrorString::~SQ_ErrorString() +{} + +// Get string by error code. +TQString SQ_ErrorString::string(const int code) +{ + return messages[code]; +} + +TQString SQ_ErrorString::stringSN(const int code) +{ + return messages[code] + '\n'; +} diff --git a/src/ksquirrelpart/sq_errorstring.h b/src/ksquirrelpart/sq_errorstring.h new file mode 100644 index 0000000..400451d --- /dev/null +++ b/src/ksquirrelpart/sq_errorstring.h @@ -0,0 +1,56 @@ +/*************************************************************************** + sq_errorstring.h - description + ------------------- + begin : ??? ??? 26 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_ERRORSTRING_H +#define SQ_ERRORSTRING_H + +#include <tqmap.h> +#include <tqobject.h> + +#include <tdelocale.h> + +#define SQE_NOTFINISHED 10000 + +/* + * Class SQ_ErrorString will return translated string representation of + * error code. + */ + +class SQ_ErrorString : public TQObject +{ + public: + SQ_ErrorString(TQObject *parent = 0); + ~SQ_ErrorString(); + + /* + * Get string representation of error. + */ + TQString string(const int code); + + /* + * string() + "\n" + */ + TQString stringSN(const int code); + + static SQ_ErrorString* instance() { return m_instance; } + + private: + TQMap<int, TQString> messages; + static SQ_ErrorString *m_instance; +}; + +#endif diff --git a/src/ksquirrelpart/sq_externaltool.cpp b/src/ksquirrelpart/sq_externaltool.cpp new file mode 100644 index 0000000..adca2bf --- /dev/null +++ b/src/ksquirrelpart/sq_externaltool.cpp @@ -0,0 +1,245 @@ +/*************************************************************************** + sq_externaltool.cpp - description + ------------------- + begin : ??? ??? 12 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqfile.h> + +#include <kstringhandler.h> +#include <tdelocale.h> +#include <kicontheme.h> +#include <kstandarddirs.h> +#include <kprocess.h> +#include <tdemessagebox.h> + +#include "sq_iconloader.h" +#include "sq_externaltool.h" +#include "sq_popupmenu.h" +#include "sq_config.h" + +SQ_ExternalTool * SQ_ExternalTool::m_instance = 0; + +Tool::Tool() +{} + +Tool::Tool(const TQString &pix, const TQString &nam, const TQString &com) +{ + icon = pix; + name = nam; + command = com; +} + +SQ_ExternalTool::SQ_ExternalTool(TQObject *parent) : TQObject(parent), TQValueVector<Tool>() +{ + m_instance = this; + menu = new SQ_PopupMenu(0, "External tools"); + + connect(menu, TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(slotAboutToShowMenu())); + connect(menu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotActivateTool(int))); + + TQString str, tmp; + + SQ_Config::instance()->setGroup("External tools"); + + TQStringList names = SQ_Config::instance()->readListEntry("names"); + TQStringList commands = SQ_Config::instance()->readListEntry("commands"); + TQStringList icons = SQ_Config::instance()->readListEntry("icons"); + + for(TQStringList::iterator it_n = names.begin(),it_c = commands.begin(),it_i = icons.begin(); + it_n != names.end() || it_c != commands.end() || it_i != icons.end(); + ++it_n, ++it_c, ++it_i) + { + append(Tool(*it_i, *it_n, *it_c)); + } +} + +SQ_ExternalTool::~SQ_ExternalTool() +{ + delete menu; +} + +TQString SQ_ExternalTool::toolPixmap(const int i) +{ + return (*this)[i].icon; +} + +TQString SQ_ExternalTool::toolName(const int i) +{ + return (*this)[i].name; +} + +TQString SQ_ExternalTool::toolCommand(const int i) +{ + return (*this)[i].command; +} + +/* + * Recreate current popop menu. + */ +SQ_PopupMenu* SQ_ExternalTool::newPopupMenu() +{ + int id; + + // clear menu + menu->clear(); + + menu->insertTitle(i18n("No file selected")); + + // construct new menu + for(unsigned int i = 0;i < count();i++) + { + id = menu->insertItem(SQ_IconLoader::instance()->loadIcon(toolPixmap(i), TDEIcon::Desktop, TDEIcon::SizeSmall), toolName(i)); + menu->setItemParameter(id, i); + } + + return menu; +} + +/* + * Get current popup menu. + */ +SQ_PopupMenu* SQ_ExternalTool::constPopupMenu() const +{ + return menu; +} + +/* + * Write tools to config file + */ +void SQ_ExternalTool::writeEntries() +{ + // no tools ? + if(!count()) return; + + TQString num; + + // delete old group with old items + SQ_Config::instance()->deleteGroup("External tools"); + SQ_Config::instance()->setGroup("External tools"); + TQStringList names, icons, commands; + + // write items in config file + for(TQValueVector<Tool>::iterator it = begin();it != end();++it) + { + names.append((*it).name); + icons.append((*it).icon); + commands.append((*it).command); + } + + SQ_Config::instance()->writeEntry("names", names); + SQ_Config::instance()->writeEntry("commands", commands); + SQ_Config::instance()->writeEntry("icons", icons); +} + +/* + * Invoked, when user executed popup menu with external tools. + * This slot will do some useful stuff. + */ +void SQ_ExternalTool::slotAboutToShowMenu() +{ + if(!items.count()) + { + menu->changeTitle(i18n("No file selected")); + return; + } + + KFileItem *item = items.first(); + + if(!item) + { + menu->changeTitle(i18n("No file selected")); + return; + } + + // make title shorter + TQString file = KStringHandler::rsqueeze(item->name(), 30); + + // finally, change title + TQString final = (items.count() == 1 || items.count() == 0) ? file : (file + TQString::fromLatin1(" (+%1)").arg(items.count()-1)); + menu->changeTitle(final); +} + +void SQ_ExternalTool::slotActivateTool(int id) +{ + KURL::List list; + + if(items.isEmpty()) return; + + int index = menu->itemParameter(id); + + KFileItem *f = items.first(); + + while(f) + { + list.append(f->url()); + f = items.next(); + } + + items.clear(); + + if(list.empty()) return; + + KShellProcess proc; + + // get appropriate tool + Tool *tool = &at(index); + TQString comm = tool->command; + + int per_f = comm.contains("%f"); + int per_F = comm.contains("%F"); + + // %f = single file + // %F = multiple files + if(per_f && per_F) + { + KMessageBox::error(0, i18n("Command cannot contain both \"%f\" and \"%F\""), i18n("Error processing command")); + return; + } + else if(!per_f && !per_F) + { + KMessageBox::error(0, i18n("Command should contain \"%f\" or \"%F\""), i18n("Error processing command")); + return; + } + else if(per_f) + { + KURL u = list.first(); + comm.replace("%f", KShellProcess::quote(u.isLocalFile() ? u.path() : u.prettyURL())); + proc << comm; + } + else + { + TQString files; + + KURL::List::iterator itEnd = list.end(); + + for(KURL::List::iterator it = list.begin();it != itEnd;++it) + { + files.append(KShellProcess::quote((*it).isLocalFile() ? (*it).path() : (*it).prettyURL())); + files.append(" "); + } + + comm.replace("%F", files); + proc << comm; + } + + // start process + proc.start(TDEProcess::DontCare); +} + +#include "sq_externaltool.moc" diff --git a/src/ksquirrelpart/sq_externaltool.h b/src/ksquirrelpart/sq_externaltool.h new file mode 100644 index 0000000..12e6858 --- /dev/null +++ b/src/ksquirrelpart/sq_externaltool.h @@ -0,0 +1,104 @@ +/*************************************************************************** + sq_externaltool.h - description + ------------------- + begin : ??? ??? 12 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_EXTERNALTOOL_H +#define SQ_EXTERNALTOOL_H + +#include <tqstring.h> +#include <tqobject.h> +#include <tqvaluevector.h> + +#include <tdefileitem.h> + +class SQ_PopupMenu; + +struct Tool +{ + Tool(); + Tool(const TQString &, const TQString &, const TQString &); + + TQString name, command; + TQString icon; +}; + +/* + * Class which manages external tools. It store all available external tools + * in memory, and create popup menu where external tools been inserted. + */ + +class SQ_ExternalTool : public TQObject, public TQValueVector<Tool> +{ + TQ_OBJECT + + + public: + SQ_ExternalTool(TQObject *parent = 0); + ~SQ_ExternalTool(); + + /* + * Get pixmap, name or command of external tool. + */ + TQString toolPixmap(const int i); + TQString toolName(const int i); + TQString toolCommand(const int i); + + void setItems(const KFileItemList &); + + /* + * Recreate current popop menu. + */ + SQ_PopupMenu* newPopupMenu(); + + /* + * Get current popup menu. + */ + SQ_PopupMenu* constPopupMenu() const; + + /* + * Write tools to config file as TQStringLists + */ + void writeEntries(); + + static SQ_ExternalTool* instance() { return m_instance; } + + private slots: + + /* + * Invoked, when user executed popup menu with external tools. + * This slot will do some useful stuff. + */ + void slotAboutToShowMenu(); + void slotActivateTool(int); + + private: + /* + * Popup menu with all tools. + */ + SQ_PopupMenu *menu; + + KFileItemList items; + + static SQ_ExternalTool *m_instance; +}; + +inline +void SQ_ExternalTool::setItems(const KFileItemList &itms) +{ + items = itms; +} + +#endif diff --git a/src/ksquirrelpart/sq_filedialog.cpp b/src/ksquirrelpart/sq_filedialog.cpp new file mode 100644 index 0000000..5bfccdb --- /dev/null +++ b/src/ksquirrelpart/sq_filedialog.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** + sq_filedialog.cpp - description + ------------------- + begin : Mon Mar 5 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <tdefilefiltercombo.h> + +#include "sq_filedialog.h" + +SQ_FileDialog::SQ_FileDialog(const TQString &path, TQWidget *parent) + : KFileDialog(path, TQString(), parent, "select_a_file", true) +{} + +SQ_FileDialog::~SQ_FileDialog() +{} + +void SQ_FileDialog::updateCombo(bool enable) +{ + filterWidget->setEditable(enable); + + slotFilterChanged(); +} + +TQString SQ_FileDialog::nameFilter() const +{ + return filterWidget->currentText(); +} + +void SQ_FileDialog::setCurrentFilter(const TQString &f) +{ + filterWidget->setCurrentFilter(f); +} diff --git a/src/ksquirrelpart/sq_filedialog.h b/src/ksquirrelpart/sq_filedialog.h new file mode 100644 index 0000000..7fe79cb --- /dev/null +++ b/src/ksquirrelpart/sq_filedialog.h @@ -0,0 +1,39 @@ +/*************************************************************************** + sq_filedialog.h - description + ------------------- + begin : Mon Mar 5 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_FILEDIALOG_H +#define SQ_FILEDIALOG_H + +#include <tdefiledialog.h> + +/** + *@author Baryshev Dmitry + */ + +class SQ_FileDialog : public KFileDialog +{ + public: + SQ_FileDialog(const TQString &path, TQWidget *parent); + ~SQ_FileDialog(); + + TQString nameFilter() const; + void updateCombo(bool enable); + + void setCurrentFilter(const TQString &); +}; + +#endif diff --git a/src/ksquirrelpart/sq_glparts.cpp b/src/ksquirrelpart/sq_glparts.cpp new file mode 100644 index 0000000..ec55d89 --- /dev/null +++ b/src/ksquirrelpart/sq_glparts.cpp @@ -0,0 +1,219 @@ +/*************************************************************************** + sq_glparts.cpp - description + ------------------- + begin : ??? ??? 13 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "sq_glparts.h" +#include "sq_library.h" + +#include <ksquirrel-libs/fmt_codec_base.h> + +/* ***************************************************************************************** */ + +Parts::Parts() : w(0), h(0), realw(0), realh(0), m_parts(0), buffer(0) +{} + +Part::Part() : x1(0), y1(0), x2(0), y2(0), tex(0), list(0) +{} + +/* ***************************************************************************************** */ + +memoryPart::memoryPart(const int sz) : m_size(sz), m_data(0) +{} + +memoryPart::~memoryPart() +{ + del(); +} + +void memoryPart::create() +{ + m_data = new RGBA [m_size]; + +// if(m_data) +// memset(m_data, 0, m_size * sizeof(RGBA)); +} + +// Delete textures and display lists. +void Parts::removeParts() +{ + if(!m_parts.empty()) + { + int toy = tilesy.size(); + int toxy = tilesx.size() * toy; + + for(int z = 0;z < toxy;z++) + glDeleteTextures(1, &m_parts[z].tex); + + glDeleteLists(m_parts[0].list, toy); + + m_parts.clear(); + } +} + +// Create parts: generate textures and display lists. +bool Parts::makeParts() +{ + int z; + int toy = tilesy.size(); + + GLuint base = glGenLists(toy); + + if(!base) + return false; + + Part pt; + int tox = tilesx.size(); + int toxy = tox * toy; + + for(z = 0;z < toxy;z++) + { + glGenTextures(1, &pt.tex); + m_parts.push_back(pt); + } + + // calculate display list's id + for(z = 0;z < toy;z++) + m_parts[z * tox].list = base + z; + + return true; +} + +// Calculate coordinates for textures +void Parts::computeCoords() +{ + Part *p; + int index = 0; + float X, Y; + + Y = (float)h / 2.0; + + int tlsy = tilesy.size(); + int tlsx = tilesx.size(); + + for(int y = 0;y < tlsy;y++) + { + X = -(float)w / 2.0; + + for(int x = 0;x < tlsx;x++) + { + p = &m_parts[index]; + + p->x1 = X; + p->y1 = Y; + p->x2 = X + tilesx[x]; + p->y2 = Y - tilesy[y]; + + p->tx1 = 0.0; + p->tx2 = 1.0; + p->ty1 = 0.0; + p->ty2 = 1.0; + + index++; + X += tilesx[x]; + } + + Y -= tilesy[y]; + } +} + +/* ***************************************************************************************** */ + +Tab::Tab() +{ + empty(); +} + +Tab::~Tab() +{} + +void Tab::clearParts() +{ + if(broken) return; + + std::vector<Parts>::iterator itEnd = parts.end(); + + for(std::vector<Parts>::iterator it = parts.begin();it != itEnd;++it) + { + // delete textures and memory buffers + (*it).removeParts(); + (*it).deleteBuffer(); + } + + parts.clear(); + + finfo.image.clear(); + finfo.meta.clear(); +} + +void Tab::removeParts() +{ + if(broken) return; + + std::vector<Parts>::iterator itEnd = parts.end(); + + for(std::vector<Parts>::iterator it = parts.begin();it != itEnd;++it) + (*it).removeParts(); +} + +void Tab::remakeParts() +{ + if(broken) return; + + std::vector<Parts>::iterator itEnd = parts.end(); + + for(std::vector<Parts>::iterator it = parts.begin();it != itEnd;++it) + { + (*it).makeParts(); + (*it).computeCoords(); + } +} + +void Tab::empty() +{ + nullMatrix(); + + orient = -1; + rotate = 0; + fmt_size = 0; + lib = 0; + codeK = 0; + current = 0; + curangle = 0; + total = 0; + sx = sy = sw = sh = 0; + elapsed = 0; + + wm = TQWMatrix(); + + glselection = -1; + srect = TQRect(); + + manualBlocked = false; + isflippedV = isflippedH = false; + broken = false; + + m_original = KURL(); + File = TQString(); + m_File = TQString(); + quickImageInfo = TQString(); + fmt_ext = TQString(); +} + +void Tab::nullMatrix() +{ + for(int i = 0;i < 12;i++) + matrix[i] = (GLfloat)(i % 5 == 0); +} diff --git a/src/ksquirrelpart/sq_glparts.h b/src/ksquirrelpart/sq_glparts.h new file mode 100644 index 0000000..24c538c --- /dev/null +++ b/src/ksquirrelpart/sq_glparts.h @@ -0,0 +1,152 @@ +/*************************************************************************** + sq_glparts.h - description + ------------------- + begin : ??? Mar 13 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_GLPARTS_H +#define SQ_GLPARTS_H + +#include <tqgl.h> + +#include <tqwmatrix.h> +#include <tqrect.h> + +#include <kurl.h> + +#include <vector> + +#include <ksquirrel-libs/fmt_defs.h> + +struct SQ_LIBRARY; +class fmt_codec_base; + +class memoryPart +{ + public: + memoryPart(const int sz); + ~memoryPart(); + + // create/delete memory buffer + void create(); + void del(); + + bool valid() const; + RGBA *data(); + + private: + int m_size; + RGBA *m_data; +}; + +inline +RGBA* memoryPart::data() +{ + return m_data; +} + +inline +void memoryPart::del() +{ + delete [] m_data; + m_data = 0; +} + +inline +bool memoryPart::valid() const +{ + return m_data != 0; +} + +/* *************************************************************** */ + +struct Part +{ + Part(); + + float x1, y1, x2, y2, tx1, tx2, ty1, ty2; + unsigned int tex; + GLuint list; +}; + +/* *************************************************************** */ + +// one image page. All pages are stored in SQ_GLWidget::parts +struct Parts +{ + Parts(); + + int w, h, realw, realh; + + std::vector<Part> m_parts; + std::vector<int> tilesx, tilesy; + memoryPart *buffer; + + bool makeParts(); + void removeParts(); + void computeCoords(); + void deleteBuffer(); +}; + +inline +void Parts::deleteBuffer() +{ + delete buffer; + buffer = 0; +} + +/* *************************************************************** */ + +struct Tab +{ + Tab(); + ~Tab(); + + void nullMatrix(); + void empty(); + void clearParts(); + void removeParts(); + void remakeParts(); + + GLfloat matrix[12]; + GLfloat curangle; + + KURL m_original; + TQString File, m_File, quickImageInfo; + TQString fmt_ext; + + TQWMatrix wm; + TQRect srect; + + int orient; + int current; + int fmt_size; + int total; + int glselection; + int sx, sy, sw, sh; + int elapsed; + + bool rotate; + bool manualBlocked; + bool isflippedV, isflippedH; + bool broken; + + std::vector<Parts> parts; + fmt_info finfo; + + SQ_LIBRARY *lib; + fmt_codec_base *codeK; +}; + +#endif diff --git a/src/ksquirrelpart/sq_glselectionpainter.cpp b/src/ksquirrelpart/sq_glselectionpainter.cpp new file mode 100644 index 0000000..9594f28 --- /dev/null +++ b/src/ksquirrelpart/sq_glselectionpainter.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + sq_glselectionpainter.cpp - description + ------------------- + begin : Apr 4 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <tqbitmap.h> +#include <tqpainter.h> + +#include <cmath> + +#include "sq_glwidget.h" +#include "sq_glselectionpainter.h" + +static const int len = 4; +static const int len2 = 10; +static const int lenc = 2; +static const int lenc2 = lenc / 2; +static const double rad_const = 3.14159265358979323846 / 180.0; + +/* ******************************************************************* */ + +SQ_GLSelectionPainter::SQ_GLSelectionPainter(SQ_GLWidget *widget) + : w(widget), sourcew(1), sourceh(1), sw(0), sh(0), sx(0), sy(0), + angle(0), m_valid(false), m_shown(false) +{} + +SQ_GLSelectionPainter::~SQ_GLSelectionPainter() +{} + +void SQ_GLSelectionPainter::begin(Type tp, int x, int y, bool U) +{ + // end previous drawing if any + end(); + + m_type = tp; + + hackXY(x, y); + + sx = xmoveold = x; + sy = ymoveold = y; + sw = 0; + sh = 0; + + m_valid = true; + m_shown = true; + + if(U) w->updateGLA(); +} + +void SQ_GLSelectionPainter::move(int x, int y) +{ + hackXY(x, y); + + int X = TQMAX(x, xmoveold); + int Y = TQMIN(y, ymoveold); + int Xmin = TQMIN(x, xmoveold); + int Ymin = TQMAX(y, ymoveold); + + sx = Xmin; + sy = Ymin; + sw = X - Xmin; + sh = Ymin - Y; + + angle += 3; + + if(angle > 360) + angle = 0; + + // SQ_GLWidget::paintGL() will call draw() + w->updateGLA(); +} + +void SQ_GLSelectionPainter::end() +{ + m_valid = false; + m_shown = false; + + w->updateGLA(); +} + +void SQ_GLSelectionPainter::drawEllipse(float xradius, float yradius) +{ + w->makeCurrent(); + + double degInRad; + + glBegin(GL_LINE_LOOP); + glColor4f(1,0,1,1); + + for(int i = 0; i < 360; i++) + { + degInRad = rad_const * i; + glVertex2f(cos(degInRad) * xradius, sin(degInRad) * yradius); + } + + glColor4f(1,1,1,1); + glEnd(); +} + +void SQ_GLSelectionPainter::drawRect() +{ + w->makeCurrent(); + + glBegin(GL_LINE_LOOP); + glColor4f(1,0,1,1); + + glVertex2f(-sw/2, sh/2); + glVertex2f(sw/2, sh/2); + glVertex2f(sw/2, -sh/2); + glVertex2f(-sw/2, -sh/2); + + glColor4f(1,1,1,1); + glEnd(); +} + +void SQ_GLSelectionPainter::draw() +{ + if(!sw || !sh) + return; + + if(m_type == Ellipse) + drawEllipse(sw/2, sh/2); + else + drawRect(); + + // center rectangle + if(sw > lenc && sh > lenc) + { + glColor4f(1,0,1,1); + glRectf(-lenc2, lenc2, lenc2, -lenc2); + glColor4f(1,1,1,1); + } +} diff --git a/src/ksquirrelpart/sq_glselectionpainter.h b/src/ksquirrelpart/sq_glselectionpainter.h new file mode 100644 index 0000000..ea39286 --- /dev/null +++ b/src/ksquirrelpart/sq_glselectionpainter.h @@ -0,0 +1,151 @@ +/*************************************************************************** + sq_glselectionpainter.h - description + ------------------- + begin : Apr 4 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_GLSELECTIONPAINTER_H +#define SQ_GLSELECTIONPAINTER_H + +#include <tqrect.h> +#include <tqpoint.h> + +class SQ_GLWidget; + +/* + * This is a selection painter for SQ_GLWidget. + * + * Selection can be shown as rectangle and ellipse. + * + * Ellipsis selection mainly used in redeye filter. + */ + +class SQ_GLSelectionPainter +{ + public: + enum Type { Rectangle, Ellipse }; + + SQ_GLSelectionPainter(SQ_GLWidget *widget); + ~SQ_GLSelectionPainter(); + + void setSourceSize(int, int); + + TQPoint center() const; + + void draw(); + + /* + * Set selection type - rectangle or ellipse + */ + int type() const; + + /* + * when selection is drawn and visible, it's valid. + * After end() it becomes invalid. + */ + bool valid() const; + + void setVisible(bool vis); + + void begin(Type tp, int x, int y, bool U = true); + void move(int x, int y); + void setGeometry(const TQRect &rc); + void end(); + + /* + * Selected rectangle geometry + */ + TQPoint pos() const; + TQSize size() const; + + private: + void drawEllipse(float xradius, float yradius); + void drawRect(); + void hackXY(int &x, int &y); + + private: + SQ_GLWidget *w; + int sourcew, sourceh; + int sw, sh, sx, sy; + + int angle; + int xmoveold, ymoveold; + bool m_valid, m_shown; + Type m_type; +}; + +inline +TQPoint SQ_GLSelectionPainter::pos() const +{ + return valid() ? TQPoint(sourcew/2 + sx, sourceh/2 - sy) : TQPoint(); +} + +inline +TQSize SQ_GLSelectionPainter::size() const +{ + return valid() ? TQSize(sw, sh) : TQSize(); +} + +inline +int SQ_GLSelectionPainter::type() const +{ + return m_type; +} + +inline +void SQ_GLSelectionPainter::setGeometry(const TQRect &rc) +{ + int X = rc.x(), Y = rc.y(); + + hackXY(X, Y); + + sx = X; + sy = Y; + sw = rc.width(); + sh = rc.height(); +} + +inline +void SQ_GLSelectionPainter::setSourceSize(int w, int h) +{ + sourcew = w; + sourceh = h; +} + +inline +void SQ_GLSelectionPainter::setVisible(bool vis) +{ + if(m_valid) m_shown = vis; +} + +inline +bool SQ_GLSelectionPainter::valid() const +{ + return m_valid && m_shown; +} + +inline +TQPoint SQ_GLSelectionPainter::center() const +{ + return TQPoint(sx + sw/2, sy - sh/2); +} + +inline +void SQ_GLSelectionPainter::hackXY(int &x, int &y) +{ + x -= sourcew / 2; + y = sourceh / 2 - y; +} + +#endif diff --git a/src/ksquirrelpart/sq_glu.cpp b/src/ksquirrelpart/sq_glu.cpp new file mode 100644 index 0000000..8e17e31 --- /dev/null +++ b/src/ksquirrelpart/sq_glu.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** + sq_glu.cpp - description + ------------------- + begin : ??? ??? 29 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * Copyright (C) 1995-2001 Brian Paul + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sq_glu.h" + +#include <cmath> + +/* + * Replacement for gluLookAt(). + */ +void SQ_GLU::gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz) +{ + GLdouble m[16]; + GLdouble x[3], y[3], z[3]; + GLdouble mag; + + z[0] = eyex - centerx; + z[1] = eyey - centery; + z[2] = eyez - centerz; + + mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); + + if(mag) + { + z[0] /= mag; + z[1] /= mag; + z[2] /= mag; + } + + y[0] = upx; + y[1] = upy; + y[2] = upz; + + x[0] = y[1] * z[2] - y[2] * z[1]; + x[1] = -y[0] * z[2] + y[2] * z[0]; + x[2] = y[0] * z[1] - y[1] * z[0]; + + y[0] = z[1] * x[2] - z[2] * x[1]; + y[1] = -z[0] * x[2] + z[2] * x[0]; + y[2] = z[0] * x[1] - z[1] * x[0]; + + mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); + + if(mag) + { + x[0] /= mag; + x[1] /= mag; + x[2] /= mag; + } + + mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); + + if(mag) + { + y[0] /= mag; + y[1] /= mag; + y[2] /= mag; + } + +#define M(row,col) m[col*4+row] + M(0, 0) = x[0]; + M(0, 1) = x[1]; + M(0, 2) = x[2]; + M(0, 3) = 0.0; + M(1, 0) = y[0]; + M(1, 1) = y[1]; + M(1, 2) = y[2]; + M(1, 3) = 0.0; + M(2, 0) = z[0]; + M(2, 1) = z[1]; + M(2, 2) = z[2]; + M(2, 3) = 0.0; + M(3, 0) = 0.0; + M(3, 1) = 0.0; + M(3, 2) = 0.0; + M(3, 3) = 1.0; +#undef M + + glMultMatrixd(m); + glTranslated(-eyex, -eyey, -eyez); +} diff --git a/src/ksquirrelpart/sq_glu.h b/src/ksquirrelpart/sq_glu.h new file mode 100644 index 0000000..7da7a80 --- /dev/null +++ b/src/ksquirrelpart/sq_glu.h @@ -0,0 +1,50 @@ +/*************************************************************************** + sq_glu.h - description + ------------------- + begin : ??? ??? 29 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ +/* + * Mesa 3-D graphics library + * Version: 3.5 + * Copyright (C) 1995-2001 Brian Paul + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SQ_GLU_H +#define SQ_GLU_H + +#include <GL/gl.h> + +/* + * SQ_GLU is a replacement for libGLU. SQ_GLWidget uses only one method + * in original GLU library - gluLookAt(). It would be better to place it + * in standalone namespace, and remove -lGLU dependency at all. + * + * Note: Now KSquirrel doesn't use GLU, but TQt's TQGLWidget still + * depends on <GL/glu.h> + */ + +namespace SQ_GLU +{ + /* + * Replacement for gluLookAt(). + */ + void gluLookAt(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble); +}; + +#endif diff --git a/src/ksquirrelpart/sq_glview.cpp b/src/ksquirrelpart/sq_glview.cpp new file mode 100644 index 0000000..8fb909a --- /dev/null +++ b/src/ksquirrelpart/sq_glview.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + sq_glview.cpp - description + ------------------- + begin : Thu Nov 29 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <tdeglobal.h> + +#include "sq_glview.h" + +SQ_GLView * SQ_GLView::m_inst = 0; + +/***************************************/ + +SQ_TextSetter::SQ_TextSetter(TQObject *parent) : TQObject(parent) +{ + dest = "---"; +} + +SQ_TextSetter::~SQ_TextSetter() +{} + +void SQ_TextSetter::setText(const TQString &s) +{ + dest = s; + + emit changed(); +} + +/***************************************/ + +SQ_GLView::SQ_GLView() : TQObject() +{ + m_inst = this; + + map.insert("SBDecoded", new SQ_TextSetter(this)); + map.insert("SBFrame", new SQ_TextSetter(this)); + map.insert("SBLoaded", new SQ_TextSetter(this)); + map.insert("SBGLZoom", new SQ_TextSetter(this)); + map.insert("SBGLAngle", new SQ_TextSetter(this)); + map.insert("SBFile", new SQ_TextSetter(this)); + + tmp = new SQ_TextSetter(this); + + SQ_Setters::iterator itEnd = map.end(); + + for(SQ_Setters::iterator it = map.begin();it != itEnd;++it) + connect(it.data(), TQ_SIGNAL(changed()), this, TQ_SLOT(slotChanged())); +} + +SQ_GLView::~SQ_GLView() +{} + +SQ_TextSetter* SQ_GLView::sbarWidget(const TQString &name) +{ + SQ_Setters::iterator it = map.find(name); + + return (it == map.end() ? tmp : it.data()); +} + +void SQ_GLView::resetStatusBar() +{ + SQ_Setters::iterator itEnd = map.end(); + + for(SQ_Setters::iterator it = map.begin();it != itEnd;++it) + { + it.data()->blockSignals(true); + it.data()->setText("---"); + it.data()->blockSignals(false); + } + + slotChanged(); +} + +void SQ_GLView::slotChanged() +{ + TQString result; + + static const TQString &line = TDEGlobal::staticQString(" | "); + + result.append(map["SBDecoded"]->text()); + result.append(line); + + result.append(map["SBFrame"]->text()); + result.append(line); + + result.append(map["SBLoaded"]->text()); + result.append(line); + + result.append(map["SBGLZoom"]->text()); + result.append(line); + + result.append(map["SBGLAngle"]->text()); + result.append(line); + + result.append("<b>"); + result.append(map["SBFile"]->text()); + result.append("</b>"); + + emit message(result); +} + +#include "sq_glview.moc" diff --git a/src/ksquirrelpart/sq_glview.h b/src/ksquirrelpart/sq_glview.h new file mode 100644 index 0000000..01973d2 --- /dev/null +++ b/src/ksquirrelpart/sq_glview.h @@ -0,0 +1,83 @@ +/*************************************************************************** + sq_glview.h - description + ------------------- + begin : Thu Nov 29 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_GLVIEW_H +#define SQ_GLVIEW_H + +#include <tqobject.h> +#include <tqmap.h> +#include <tqstring.h> + +class SQ_TextSetter : public TQObject +{ + TQ_OBJECT + + + public: + SQ_TextSetter(TQObject *parent = 0); + ~SQ_TextSetter(); + + void setText(const TQString &); + + TQString text() const; + + signals: + void changed(); + + private: + TQString dest; +}; + +inline +TQString SQ_TextSetter::text() const +{ + return dest; +} + +/***********************************************/ + +class SQ_GLView : public TQObject +{ + TQ_OBJECT + + + public: + SQ_GLView(); + ~SQ_GLView(); + + SQ_TextSetter* sbarWidget(const TQString &); + + void resetStatusBar(); + + static SQ_GLView* window() { return m_inst; } + + signals: + void message(const TQString &); + + private slots: + void slotChanged(); + + private: + static SQ_GLView *m_inst; + + typedef TQMap<TQString, SQ_TextSetter*> SQ_Setters; + + SQ_Setters map; + SQ_TextSetter *tmp; +}; + +#endif diff --git a/src/ksquirrelpart/sq_glwidget.cpp b/src/ksquirrelpart/sq_glwidget.cpp new file mode 100644 index 0000000..0380090 --- /dev/null +++ b/src/ksquirrelpart/sq_glwidget.cpp @@ -0,0 +1,2006 @@ +/*************************************************************************** + sq_glwidget.cpp - description + ------------------- + begin : Mon Mar 15 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqeventloop.h> +#include <tqstringlist.h> +#include <tqfileinfo.h> +#include <tqdatetime.h> +#include <tqlabel.h> +#include <tqtimer.h> +#include <tqdatetime.h> +#include <tqslider.h> +#include <tqlabel.h> + +#include <tdeapplication.h> +#include <tdeaction.h> +#include <kcursor.h> +#include <kstandarddirs.h> +#include <kstatusbar.h> +#include <tdefiledialog.h> +#include <tdeglobal.h> +#include <tdelocale.h> +#include <kstringhandler.h> +#include <tdemessagebox.h> +#include <kdebug.h> +#include <tdeio/job.h> +#include <tdetempfile.h> +#include <twin.h> +#include <ktabbar.h> + +#include <cmath> +#include <cstdlib> + +#ifndef KSQUIRREL_PART +#include "ksquirrel.h" +#include "sq_widgetstack.h" +#include "sq_glview.h" +#include "sq_fileiconview.h" +#include "sq_diroperator.h" +#include "sq_hloptions.h" +#include "sq_previewwidget.h" +#include "sq_tabopendialog.h" +#endif + +#include "sq_popupmenu.h" +#include "sq_libraryhandler.h" +#include "sq_config.h" +#include "sq_glwidget_helpers.h" +#include "sq_glwidget.h" +#include "sq_glu.h" +#include "sq_codecsettings.h" +#include "sq_glselectionpainter.h" +#include "sq_utils.h" +#include "sq_errorstring.h" +#include "fmt_filters.h" + +#include <ksquirrel-libs/fileio.h> +#include <ksquirrel-libs/fmt_codec_base.h> +#include <ksquirrel-libs/fmt_utils.h> +#include <ksquirrel-libs/error.h> + +#ifdef SQ_HAVE_KEXIF +#include <libkexif/kexifdata.h> +#endif + +// is it enough ? +#define SQ_FLOAT_SIGMA 1e-5 + +#define ISFLOAT(a,b) (fabs(a - b) < SQ_FLOAT_SIGMA) +#define ISFLOAT1(a) ISFLOAT(a, 1.0) +#define ISFLOAT0(a) ISFLOAT(a, 0.0) + +#define SQ_TAB_TEXT_LENGTH 30 + +/* ***************************************************************************************** */ + +SQ_GLWidget * SQ_GLWidget::m_instance = 0; + +static const int timer_delay_file = 5; +static const double rad_const = 3.14159265358979323846 / 180.0; + +static const float SQ_WINDOW_BACKGROUND_POS = -1000.0; +static const float SQ_IMAGE_CHECKER_POS = -999.0; +static const float SQ_FIRST_FRAME_POS = -998.0; +static const float SQ_MARKS_POS = -997.0; +static const float SQ_FIRST_TILE_LAYER = -995.0; +static const float SQ_ONSCREEN_LAYER = 10000.0; + +/* ***************************************************************************************** */ + +SQ_GLWidget::SQ_GLWidget(TQWidget *parent, const char *name) : TQGLWidget(parent, name) +{ + kdDebug() << "+SQ_GLWidget" << endl; + + // init all variables... + m_instance = this; + +#ifdef KSQUIRREL_PART + connect(&t_glv, TQ_SIGNAL(message(const TQString &)), this, TQ_SIGNAL(message(const TQString &))); +#endif + + zoomMenu = 0; + selectionMenu = 0; + images = 0; + parts_broken = 0; + + ac = new TDEActionCollection(this, this, "GLWidget actionCollection"); + changed = blocked = decoded = reset_mode = false; + movetype = -1; + buffer = new RGBA [512 * 512]; + zoomFactor = 1.0; + old_id = -1; + menu = new TQPopupMenu(this); + hackResizeGL = false; + lastCopy = KURL::fromPathOrURL("/"); + oldZoom = -1; + + percentsLabel = new TQLabel(this); + percentsLabel->move(4, 4); + percentsLabel->hide(); + + tabold = tab = &taborig; + + tmp = new KTempFile; + tmp->setAutoDelete(true); + tmp->close(); + + SQ_Config::instance()->setGroup("GL view"); + zoom_type = SQ_Config::instance()->readNumEntry("zoom type", 2); + linear = SQ_Config::instance()->readBoolEntry("zoom_nice", true); + + // load background for transparent image + BGquads = TQImage(locate("data", "images/checker.png")); + + if(BGquads.isNull()) + { + BGquads = TQImage(32, 32, 32); + BGquads.setAlphaBuffer(true); + BGquads.fill(0); + } + + bindChecker = true; + + zoomfactor = SQ_Config::instance()->readNumEntry("zoom", 25); + movefactor = SQ_Config::instance()->readNumEntry("move", 5); + rotatefactor = SQ_Config::instance()->readNumEntry("angle", 90); + + // load cursors + setCursor(KCursor::arrowCursor()); + + setFocusPolicy(TQWidget::WheelFocus); + setAcceptDrops(true); + + // popup menu with image pages + images = new TDEPopupMenu; + images->setCheckable(true); + + // create actions + createActions(); + + // create toolbars + createToolbar(); + + // create tickmarks + createMarks(); + + initAccelsAndMenu(); + + enableActions(false); + + KCursor::setAutoHideCursor(this, true); + KCursor::setHideCursorDelay(2500); + +#ifndef KSQUIRREL_PART + timer_prev = new TQTimer(this); + timer_next = new TQTimer(this); + + TQ_CHECK_PTR(timer_prev); + TQ_CHECK_PTR(timer_next); + + connect(timer_prev, TQ_SIGNAL(timeout()), SQ_WidgetStack::instance(), TQ_SLOT(emitPreviousSelected())); + connect(timer_next, TQ_SIGNAL(timeout()), SQ_WidgetStack::instance(), TQ_SLOT(emitNextSelected())); +#endif + + timer_anim = new TQTimer(this); + + TQ_CHECK_PTR(timer_anim); + + connect(timer_anim, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotAnimateNext())); + + connect(images, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotSetCurrentImage(int))); + connect(images, TQ_SIGNAL(aboutToHide()), this, TQ_SLOT(slotImagesHidden())); + connect(images, TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(slotImagesShown())); + + gls = new SQ_GLSelectionPainter(this); +} + +SQ_GLWidget::~SQ_GLWidget() +{ + kdDebug() << "-SQ_GLWidget" << endl; + + delete gls; + + delete parts_broken; + + removeCurrentTabs(); + + delete selectionMenu; + delete zoomMenu; + delete images; + delete [] buffer; + delete tmp; +} + +// Initialize OpenGL context. Used internally by TQGLWidget. +void SQ_GLWidget::initializeGL() +{ + setClearColor(); + glClearDepth(1.0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + // finally, clear + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // create "broken" image + initBrokenImage(); + + initMarks(); +} + +// Resize OpenGL context. Used internally by TQGLWidget. +void SQ_GLWidget::resizeGL(int width, int height) +{ + gls->setSourceSize(width, height); + + // set new viewport + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // O(0,0) will be in the center of the window + glOrtho(-width/2, width/2, -height/2, height/2, 0.1f, 10000.0); + + // camera setup + SQ_GLU::gluLookAt(0,0,1, 0,0,0, 0,1,0); + glMatrixMode(GL_MODELVIEW); + + if(decoded && !hackResizeGL) + slotZoomIfLess(); + + hackResizeGL = false; +} + +/* + * Fill a w x h region with texture. Generate texture if needed. + */ +void SQ_GLWidget::draw_background(void *bits, unsigned int *tex, int dim, GLfloat w, GLfloat h, bool &bind, bool deleteOld) +{ + float half_w, half_h; + + half_w = w / 2.0; + half_h = h / 2.0; + + // bind texture ? + if(bind) + { + // delete old texture before binding ? + if(deleteOld) + glDeleteTextures(1, tex); + + // generate and bind texture + glGenTextures(1, tex); + glBindTexture(GL_TEXTURE_2D, *tex); + + // setup parameters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + // assign image to texture + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dim, dim, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits); + + bind = false; + } + else + glBindTexture(GL_TEXTURE_2D, *tex); + + // draw + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex2f(-half_w, half_h); + glTexCoord2f(w/(GLfloat)dim, 0.0); glVertex2f(half_w, half_h); + glTexCoord2f(w/(GLfloat)dim, h/(GLfloat)dim); glVertex2f(half_w, -half_h); + glTexCoord2f(0.0, h/(GLfloat)dim); glVertex2f(-half_w, -half_h); + glEnd(); +} + +// Redraw OpenGL context. Used internally by TQGLWidget. +void SQ_GLWidget::paintGL() +{ + int z; + + // clear + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if(gls->valid()) + { + matrix_push(); + matrix_pure_reset(); + TQPoint p = gls->center(); + + // move to selection center + MATRIX_X = p.x(); + MATRIX_Y = p.y(); + write_gl_matrix(); + + gls->draw(); + + matrix_pop(); + write_gl_matrix(); + } + + glEnable(GL_TEXTURE_2D); + + // draw window background ? + SQ_Config::instance()->setGroup("GL view"); + if(SQ_Config::instance()->readNumEntry("GL view background type", 1) == 2) + { + static bool del = false; + matrix_push(); + matrix_pure_reset(); + matrix_move_z(SQ_WINDOW_BACKGROUND_POS); + draw_background(BGpixmap.bits(), &texPixmap, BGpixmap.width(), width(), height(), changed, del); + del = true; + matrix_pop(); + write_gl_matrix(); + } + + // draw image + if(!reset_mode && decoded) + { + SQ_Config::instance()->setGroup("GL view"); + + fmt_image *im = &tab->finfo.image[tab->current]; + + // if the image is transparent, and we should draw background for image + if(im->hasalpha && SQ_Config::instance()->readBoolEntry("alpha_bkgr", true)) + { + GLfloat w = (float)im->w / 2.0, h = (float)im->h / 2.0; + + static const GLdouble eq[4][4] = + { + {0.0, 1.0, 0.0, 0.0}, + {1.0, 0.0, 0.0, 0.0}, + {0.0, -1.0, 0.0, 0.0}, + {-1.0, 0.0, 0.0, 0.0} + }; + + // we will draw background for transparent image (quads) within + // entire window, and cut off useless regions with clip planes + glPushMatrix(); + glTranslatef(-w, -h, 0.0); + glClipPlane(GL_CLIP_PLANE0, eq[0]); + glClipPlane(GL_CLIP_PLANE1, eq[1]); + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + glPopMatrix(); + glPushMatrix(); + glTranslatef(w, h, 0.0); + glClipPlane(GL_CLIP_PLANE2, eq[2]); + glClipPlane(GL_CLIP_PLANE3, eq[3]); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); + glPopMatrix(); + + // draw background + matrix_push(); + matrix_pure_reset(); + matrix_move_z(SQ_IMAGE_CHECKER_POS); + draw_background(BGquads.bits(), &texQuads, 32, width(), height(), bindChecker, !bindChecker); + matrix_pop(); + write_gl_matrix(); + + // don't need planes any more... + glDisable(GL_CLIP_PLANE3); + glDisable(GL_CLIP_PLANE2); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE0); + } + + matrix_move_z(SQ_FIRST_FRAME_POS); + + Parts *pt = tab->broken ? parts_broken : &tab->parts[tab->current]; + + // draw current image + int toy = pt->tilesy.size(); + int tox = pt->tilesx.size(); + for(z = 0;z < toy;z++) + if(glIsList(pt->m_parts[z * tox].list)) + glCallList(pt->m_parts[z * tox].list); + + // draw tickmarks ("broken" image won't have tickmarks) + if(!tab->broken && marks && SQ_Config::instance()->readBoolEntry("marks", true)) + { + GLfloat zum = getZoom(); + GLfloat x = fabsf(pt->m_parts[0].x1) * zum, y = pt->m_parts[0].y1 * zum; + GLfloat X = MATRIX_X, Y = MATRIX_Y; + + if(x < 0.0) + x = -x; + + const GLfloat ly = y+16, ry = -y-16; + const GLfloat lx = x+16, rx = -x-16; + + matrix_push(); + matrix_pure_reset(); + MATRIX_X = X; + MATRIX_Y = Y; + matrix_rotate2(tab->curangle); + matrix_move_z(SQ_MARKS_POS); + + GLfloat coords[4][8] = + { + {rx, ly, -x, ly, -x, y, rx, y}, + {x, ly, lx, ly, lx, y, x, y}, + {x, -y, lx, -y, lx, ry, x, ry}, + {rx, -y, -x, -y, -x, ry, rx, ry} + }; + + for(z = 0;z < 4;z++) + { + glBindTexture(GL_TEXTURE_2D, mark[z]); + + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex2f(coords[z][0], coords[z][1]); + glTexCoord2f(1.0, 0.0); glVertex2f(coords[z][2], coords[z][3]); + glTexCoord2f(1.0, 1.0); glVertex2f(coords[z][4], coords[z][5]); + glTexCoord2f(0.0, 1.0); glVertex2f(coords[z][6], coords[z][7]); + glEnd(); + } + + matrix_pop(); + write_gl_matrix(); + } + } + + glDisable(GL_TEXTURE_2D); + + matrixChanged(); + + if(!tab->broken && tab->total > 1) + frameChanged(); +} + +/* + * Change statusbar info according with + * current matrix (it shows current zoom & angle values). + */ +void SQ_GLWidget::matrixChanged() +{ + TQString str; + + float m = getZoom(); + float fzoom = m * 100.0; + float z = (m < 1.0) ? 1.0/m : m; + + // construct zoom + str = TQString::fromLatin1("%1% [%2:%3]") + .arg(fzoom, 0, 'f', 1) + .arg((m < 1.0)?1.0:z, 0, 'f', 1) + .arg((m > 1.0)?1.0:z, 0, 'f', 1); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBGLZoom")->setText(str); +#else + t_glv.sbarWidget("SBGLZoom")->setText(str); +#endif + + // construct rotation angle + str = TQString::fromLatin1("%1%2 %3 deg") + .arg((tab->isflippedV)?"V":"") + .arg((tab->isflippedH)?"H":"") + .arg(tab->curangle, 0, 'f', 1); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBGLAngle")->setText(str); +#else + t_glv.sbarWidget("SBGLAngle")->setText(str); +#endif +} + +/* + * Mouse wheel event. Let's load next/previous image, or + * zoom in/zoom out (depends on settings). + */ +void SQ_GLWidget::wheelEvent(TQWheelEvent *e) +{ + if(e->delta() < 0 && e->state() == TQt::NoButton) + { +#ifndef KSQUIRREL_PART + SQ_Config::instance()->setGroup("GL view"); + + // load next file in current directory + if(SQ_Config::instance()->readNumEntry("scroll", 0)) + slotNext(); + else +#endif + + slotZoomPlus(); + } + else if(e->delta() > 0 && e->state() == TQt::NoButton) + { +#ifndef KSQUIRREL_PART + SQ_Config::instance()->setGroup("GL view"); + + if(SQ_Config::instance()->readNumEntry("scroll", 0)) + slotPrev(); + else +#endif + + slotZoomMinus(); + } + // some special bindings: + // if CTRL key is pressed, zoom 2x or 0.5x + else if(e->delta() < 0 && e->state() == TQt::ControlButton) + matrix_zoom(2.0); + else if(e->delta() > 0 && e->state() == TQt::ControlButton) + matrix_zoom(0.5f); + else if(e->delta() < 0 && e->state() == TQt::ShiftButton) + slotZoomPlus(); + else if(e->delta() > 0 && e->state() == TQt::ShiftButton) + slotZoomMinus(); +} + +// User pressed mouse button down. +void SQ_GLWidget::mousePressEvent(TQMouseEvent *e) +{ + setFocus(); + + // left button, update cursor + if(e->button() == TQt::LeftButton && e->state() == TQt::NoButton && tab->glselection == -1) + { +#ifndef KSQUIRREL_PART + TQTime t = TQTime::currentTime(); + + SQ_Config::instance()->setGroup("GL view"); + int dc = SQ_Config::instance()->readNumEntry("double_click", 0); + + if(dc && clickTime.isValid() && clickTime.msecsTo(t) <= TDEApplication::doubleClickInterval()) + { + if(dc == 1) + KSquirrel::app()->closeGLWidget(); + else + toggleFullScreen(); + + return; + } + else + clickTime = t; + +#endif + setCursor(KCursor::sizeAllCursor()); + + xmoveold = e->x(); + ymoveold = e->y(); + + movetype = 1; + } + // left button + SHIFT, let's start drawing zoom frame + else if(e->button() == TQt::LeftButton && (e->state() == TQt::ShiftButton || tab->glselection != -1)) + { + // stop animation! + stopAnimation(); + + // update cursor to crosshair + setCursor(KCursor::crossCursor()); + + if(tab->glselection == SQ_GLSelectionPainter::Rectangle || tab->glselection == SQ_GLSelectionPainter::Ellipse) + gls->begin(static_cast<SQ_GLSelectionPainter::Type>(tab->glselection), e->x(), e->y()); + else + gls->begin(SQ_GLSelectionPainter::Rectangle, e->x(), e->y()); + + movetype = 2; + } + // right button - show context menu + else if(e->button() == TQt::RightButton) + menu->popup(TQCursor::pos()); + // middle button - toggle fullscreen state + else if(e->button() == TQt::MidButton) + toggleFullScreen(); +} + +// User moved mouse. +void SQ_GLWidget::mouseMoveEvent(TQMouseEvent *e) +{ + // user didn't press any mouse button before ? + if(movetype == -1 && fullscreen()) + { +#if 0 +// bool tvis = SQ_GLView::window()->toolbar()->isShown(); +// bool svis = SQ_GLView::window()->statusbar()->isShown(); + + int h = SQ_GLView::window()->toolbar()->height() + + SQ_GLView::window()->tabbar()->height(); + +#warning FIXME +#ifndef KSQUIRREL_PART + hackResizeGL = true; + SQ_GLView::window()->boxBar()->setShown((/*tvis ? false:*/(e->y() < h))); + SQ_GLView::window()->statusbar()->setShown((/*svis ? false:*/(e->y() > + height()-SQ_GLView::window()->statusbar()->height()))); +#endif +#endif + return; + } + + // left mouse button, lets move image (or matrix :-) ) + if(movetype == 1) + { + xmove = e->x(); + ymove = e->y(); + + matrix_move(xmove-xmoveold, -ymove+ymoveold); + + xmoveold = e->x(); + ymoveold = e->y(); + } + // left + SHIFT + else if(movetype == 2) + gls->move(e->x(), e->y()); +} + +// User released some mouse button. +void SQ_GLWidget::mouseReleaseEvent(TQMouseEvent *) +{ + if(movetype == -1) + return; + + // left button - restore cursor + if(movetype == 1 || (movetype == 2 && tab->glselection != -1)) // permanent selection + setCursor(KCursor::arrowCursor()); + // left button + SHIFT - zoom to selected rectangle (if needed) + else if(movetype == 2 && tab->glselection == -1) + { + setCursor(KCursor::arrowCursor()); + + TQSize sz = gls->size(); + TQPoint pt = gls->pos(); + TQRect lastRect(pt.x(), pt.y(), sz.width(), sz.height()); + + gls->end(); + + TQPoint lastC = lastRect.center(); + TQPoint O(width() / 2, height() / 2); + + if(lastRect.width() > 2 && lastRect.height() > 2) + { + bool lastReset = reset_mode; + reset_mode = true; + float X = MATRIX_X, Y = MATRIX_Y; + matrix_move(O.x() - lastC.x(), lastC.y() - O.y()); + reset_mode = lastReset; + + // try to zoom + bool zoomed = tab->broken ? false : zoomRect(lastRect); + + // not zoomed ? (zoom > maximum zoom) + if(!zoomed) + { + MATRIX_X = X; + MATRIX_Y = Y; + write_gl_matrix(); + } + } + + updateGL(); + + // start animation, if needed + if(!manualBlocked()) + startAnimation(); + } + + movetype = -1; +} + +/* + * Zoom to 'r'. Will be called after somebody used right mouse button + * to select zoom region. + */ +bool SQ_GLWidget::zoomRect(const TQRect &r) +{ + // calculate zoom factor + float factor = 1.0; + float w = (float)width(), h = (float)height(); + float factorw = w / (float)r.width(); + float factorh = h / (float)r.height(); + float t = w / h; + + if(t > (float)r.width() / (float)r.height()) + factor = factorh; + else + factor = factorw; + + // try to zoom + return matrix_zoom(factor); +} + +// Fit width. +void SQ_GLWidget::slotZoomW() +{ + zoom_type = 0; + pAZoomW->setChecked(true); + + // no image decoded + if(tab->broken || tab->finfo.image.empty()) return; + + // calculate zoom factor + float factor = (float)width() / (tab->rotate ? (float)tab->finfo.image[tab->current].h : (float)tab->finfo.image[tab->current].w); + + // "Ignore, if the image is less than window" - restore zoom factor to 1.0 + if(pAIfLess->isChecked() && (tab->finfo.image[tab->current].w < width() && tab->finfo.image[tab->current].h < height())) + factor = 1.0; + + // zoom... + internalZoom(factor); +} + +// Fit height. +void SQ_GLWidget::slotZoomH() +{ + zoom_type = 1; + pAZoomH->setChecked(true); + + if(tab->broken || tab->finfo.image.empty()) return; + + float factor = (float)height() / (tab->rotate ? (float)tab->finfo.image[tab->current].w : (float)tab->finfo.image[tab->current].h); + + if(pAIfLess->isChecked() && (tab->finfo.image[tab->current].w < width() && tab->finfo.image[tab->current].h < height())) + factor = 1.0; + + internalZoom(factor); +} + +// Fit image (e.g. width and height). +void SQ_GLWidget::slotZoomWH() +{ + zoom_type = 2; + pAZoomWH->setChecked(true); + + if(tab->broken || tab->finfo.image.empty()) return; + + float factor = 1.0; + float w = (float)width(), h = (float)height(); + float factorw = w / (tab->rotate ? (float)tab->finfo.image[tab->current].h : (float)tab->finfo.image[tab->current].w); + float factorh = h / (tab->rotate ? (float)tab->finfo.image[tab->current].w : (float)tab->finfo.image[tab->current].h); + float t = w / h; + float F = tab->rotate ? ((float)tab->finfo.image[tab->current].h / (float)tab->finfo.image[tab->current].w) : ((float)tab->finfo.image[tab->current].w / (float)tab->finfo.image[tab->current].h); + + if(t > F) + factor = factorh; + else + factor = factorw; + + if(pAIfLess->isChecked() && (tab->finfo.image[tab->current].w < width() && tab->finfo.image[tab->current].h < height())) + factor = 1.0; + + internalZoom(factor); +} + +// Previous zoom. +void SQ_GLWidget::slotZoomLast() +{ + zoom_type = 4; + pAZoomLast->setChecked(true); + + if(tab->broken || tab->finfo.image.empty()) return; + + internalZoom(zoomFactor); +} + +// Zoom 100%. +void SQ_GLWidget::slotZoom100() +{ + zoom_type = 3; + pAZoom100->setChecked(true); + + if(tab->broken || tab->finfo.image.empty()) return; + + internalZoom(1.0); +} + +// "Ignore, if the image is less than window" +void SQ_GLWidget::slotZoomIfLess() +{ + if(tab->broken || tab->finfo.image.empty()) return; + + switch(zoom_type) + { + case 0: slotZoomW(); break; + case 1: slotZoomH(); break; + case 2: slotZoomWH(); break; + case 3: break; + + default: + slotZoomLast(); + } +} + +// Zoom+ +void SQ_GLWidget::slotZoomPlus() +{ + matrix_zoom(1.0+zoomfactor/100.0); +} + +// Zoom- +void SQ_GLWidget::slotZoomMinus() +{ + matrix_zoom(1.0/(1.0+zoomfactor/100.0)); +} + +// Rotate left. +void SQ_GLWidget::slotRotateLeft() +{ + matrix_rotate(-rotatefactor); +} + +// Rotate right. +void SQ_GLWidget::slotRotateRight() +{ + matrix_rotate(rotatefactor); +} + +/* + operations with matrices are taken from GLiv =) + + thanks to Guillaume Chazarian. +*/ +void SQ_GLWidget::flip(int id, bool U) +{ + GLfloat x = MATRIX_X, y = MATRIX_Y; + MATRIX_X = 0; + MATRIX_Y = 0; + + tab->matrix[id] *= -1.0; + tab->matrix[id + 1] *= -1.0; + tab->matrix[id + 3] *= -1.0; + + MATRIX_X = x; + MATRIX_Y = y; + + write_gl_matrix(); + + if(!reset_mode && U) + updateGL(); +} + +void SQ_GLWidget::slotFlipH() +{ + if(!tab->broken) + { + tab->isflippedH = !tab->isflippedH; + flip(0); + } +} + +void SQ_GLWidget::slotFlipV() +{ + if(!tab->broken) + { + tab->isflippedV = !tab->isflippedV; + flip(4); + } +} + +void SQ_GLWidget::slotMatrixReset() +{ + if(!tab->broken) + { + oldZoom = getZoom(); + matrix_reset(false); + matrix_zoom(1.0); + } +} + +void SQ_GLWidget::write_gl_matrix() +{ + GLfloat transposed[16] = + { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + transposed[0] = MATRIX_C1; + transposed[5] = MATRIX_C2; + transposed[4] = MATRIX_S1; + transposed[1] = MATRIX_S2; + transposed[12] = MATRIX_X; + transposed[13] = MATRIX_Y; + transposed[14] = MATRIX_Z; + + glLoadMatrixf(transposed); +} + +void SQ_GLWidget::matrix_move(GLfloat x, GLfloat y) +{ + if(tab->broken) return; + + MATRIX_X += x; + MATRIX_Y += y; + + write_gl_matrix(); + + if(!reset_mode) + updateGL(); +} + +void SQ_GLWidget::matrix_move_z(GLfloat z) +{ + MATRIX_Z = z; + + write_gl_matrix(); +} + +void SQ_GLWidget::matrix_push() +{ + memcpy(saved, tab->matrix, sizeof(tab->matrix)); +} + +void SQ_GLWidget::matrix_pop() +{ + memcpy(tab->matrix, saved, sizeof(tab->matrix)); +} + +void SQ_GLWidget::matrix_reset(bool U) +{ + tab->nullMatrix(); + + tab->curangle = 0.0; + tab->isflippedH = tab->isflippedV = false; + + if(decoded) + exifRotate(U); +} + +void SQ_GLWidget::matrix_pure_reset() +{ + tab->nullMatrix(); + write_gl_matrix(); +} + +bool SQ_GLWidget::matrix_zoom(GLfloat ratio) +{ + if(tab->broken) return false; + + SQ_Config::instance()->setGroup("GL view"); + + int zoom_lim = SQ_Config::instance()->readNumEntry("zoom limit", 1); + GLfloat zoom_min, zoom_max, zoom_tobe; + + zoom_tobe = hypot(MATRIX_C1 * ratio, MATRIX_S1 * ratio) * 100.0; + + switch(zoom_lim) + { + case 2: + zoom_min = (float)SQ_Config::instance()->readNumEntry("zoom_min", 1); + zoom_max = (float)SQ_Config::instance()->readNumEntry("zoom_max", 10000); + break; + + default: // "case 1:" too + zoom_min = 1.0; + zoom_max = 10000.0; + } + + if(zoom_lim) + { + float z = getZoomPercents(); + + // zoom limit exceeded - do nothing + if((z >= zoom_max && ratio > 1.0) || (z <= zoom_min && ratio < 1.0)) + return false; + + // if the new zoom will be greater (smaller) than maximum + // (minimum) zoom - scale it. + if(ratio < 1.0 && zoom_min >= zoom_tobe) + ratio = ratio * zoom_min / zoom_tobe; + else if(ratio > 1.0 && zoom_max <= zoom_tobe) + ratio = ratio * zoom_max / zoom_tobe; + } + + GLfloat oldz = (oldZoom == -1 ? getZoom() : oldZoom); + + MATRIX_C1 *= ratio; + MATRIX_S1 *= ratio; + MATRIX_X *= ratio; + MATRIX_S2 *= ratio; + MATRIX_C2 *= ratio; + MATRIX_Y *= ratio; + + hackMatrix(); + + GLfloat z = getZoom(); + int filter = -1; + + if(ISFLOAT1(oldz) && !ISFLOAT1(z)) + filter = linear ? GL_LINEAR : GL_NEAREST; + else if(ISFLOAT1(z)) + filter = GL_NEAREST; + + // update all textures + if(filter != -1) + { + for(int i = 0;i < tab->total;i++) + { + int toxy = tab->parts[i].m_parts.size(); + + for(int j = 0;j < toxy;j++) + { + glBindTexture(GL_TEXTURE_2D, tab->parts[i].m_parts[j].tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + } + } + } + + oldZoom = -1; + write_gl_matrix(); + + changeSlider(z); + + if(!reset_mode) + updateGL(); + + return true; +} + +/* + * Floating point operations are not 100% exact. + * We should correct matrix values. + */ +void SQ_GLWidget::hackMatrix() +{ + if(ISFLOAT1(MATRIX_C1)) MATRIX_C1 = MATRIX_C1 < 0 ? -1.0 : 1.0; + else if(ISFLOAT0(MATRIX_C1)) MATRIX_C1 = 0.0; + + if(ISFLOAT1(MATRIX_C2)) MATRIX_C2 = MATRIX_C2 < 0 ? -1.0 : 1.0; + else if(ISFLOAT0(MATRIX_C2)) MATRIX_C2 = 0.0; + + if(ISFLOAT1(MATRIX_S1)) MATRIX_S1 = MATRIX_S1 < 0 ? -1.0 : 1.0; + else if(ISFLOAT0(MATRIX_S1)) MATRIX_S1 = 0.0; + + if(ISFLOAT1(MATRIX_S2)) MATRIX_S2 = MATRIX_S2 < 0 ? -1.0 : 1.0; + else if(ISFLOAT0(MATRIX_S2)) MATRIX_S2 = 0.0; + + if(ISFLOAT0(MATRIX_X)) MATRIX_X = 0.0; + if(ISFLOAT0(MATRIX_Y)) MATRIX_Y = 0.0; +} + +GLfloat SQ_GLWidget::getZoom() const +{ + return hypot(MATRIX_C1, MATRIX_S1); +} + +GLfloat SQ_GLWidget::getZoomPercents() const +{ + return getZoom() * 100.0; +} + +void SQ_GLWidget::matrix_rotate(GLfloat angle, bool U) +{ + if(tab->broken) return; + + GLfloat c1 = MATRIX_C1, c2 = MATRIX_C2, s1 = MATRIX_S1, s2 = MATRIX_S2; + + double rad = angle * rad_const; + double cosine = cos(rad); + double sine = sin(rad); + + MATRIX_C1 = c1 * cosine + s2 * sine; + MATRIX_S1 = s1 * cosine + c2 * sine; + MATRIX_S2 = -c1 * sine + s2 * cosine; + MATRIX_C2 = -s1 * sine + c2 * cosine; + + hackMatrix(); + + tab->curangle += angle; + + if(tab->curangle == 360.0 || tab->curangle == -360.0) + tab->curangle = 0.0; + else if(tab->curangle > 360.0) + tab->curangle -= 360.0; + else if(tab->curangle < -360.0) + tab->curangle += 360.0; + + write_gl_matrix(); + + if(U) + updateGL(); +} + +void SQ_GLWidget::matrix_rotate2(GLfloat angle) +{ + GLfloat c1 = MATRIX_C1, c2 = MATRIX_C2, s1 = MATRIX_S1, s2 = MATRIX_S2; + + double rad = angle * rad_const; + double cosine = cos(rad); + double sine = sin(rad); + + MATRIX_C1 = c1 * cosine + s2 * sine; + MATRIX_S1 = s1 * cosine + c2 * sine; + MATRIX_S2 = -c1 * sine + s2 * cosine; + MATRIX_C2 = -s1 * sine + c2 * cosine; + + write_gl_matrix(); +} + +/* + * Bind textures, draw them and create GL lists. + * Also show textures by executing GL lists, if 'swap' = true. + */ +bool SQ_GLWidget::showFrames(int i, Parts *p, bool swap) +{ + int z, k = 0; + const int a = p->tilesx.size() * i, b = a + p->tilesx.size(); + int filter = linear ? GL_LINEAR : GL_NEAREST; + + // for safety... + makeCurrent(); + + glEnable(GL_TEXTURE_2D); + + float zm = getZoom(); + + for(z = a;z < b;z++) + { + glBindTexture(GL_TEXTURE_2D, p->m_parts[z].tex); + + // setup texture parameters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ISFLOAT1(zm) ? GL_NEAREST : filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ISFLOAT1(zm) ? GL_NEAREST : filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + setupBits(p, buffer, i, k); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p->tilesx[k], p->tilesy[i], 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + k++; + } + + // create new display list + glNewList(p->m_parts[a].list, swap ? GL_COMPILE_AND_EXECUTE : GL_COMPILE); + + // bind & draw textures (if needed) + for(z = a;z < b;z++) + { + glBindTexture(GL_TEXTURE_2D, p->m_parts[z].tex); + + glBegin(GL_QUADS); + glTexCoord2f(p->m_parts[z].tx1, p->m_parts[z].ty1); glVertex2f(p->m_parts[z].x1, p->m_parts[z].y1); + glTexCoord2f(p->m_parts[z].tx2, p->m_parts[z].ty1); glVertex2f(p->m_parts[z].x2, p->m_parts[z].y1); + glTexCoord2f(p->m_parts[z].tx2, p->m_parts[z].ty2); glVertex2f(p->m_parts[z].x2, p->m_parts[z].y2); + glTexCoord2f(p->m_parts[z].tx1, p->m_parts[z].ty2); glVertex2f(p->m_parts[z].x1, p->m_parts[z].y2); + glEnd(); + } + + glEndList(); + + glDisable(GL_TEXTURE_2D); + + // swap buffers... + if(swap) + swapBuffers(); + + return GL_TRUE; +} + +void SQ_GLWidget::setupBits(Parts *p, RGBA *_buffer, int y, int x) +{ + TQPair<int, int> pair = SQ_GLWidget::calcRealDimensions(*p, y, x); + + int offs = p->realw * pair.second + pair.first; + RGBA *orig = p->buffer->data() + offs; + + int toy = p->tilesy[y]; + int tox = p->tilesx[x]; + + for(int j = 0;j < toy;j++) + memcpy(_buffer + tox*j, orig + p->realw*j, tox*sizeof(RGBA)); +} + +/* + * Start decoding given image. We can call it from anywhere. + */ +void SQ_GLWidget::startDecoding(const TQString &file) +{ +#ifndef KSQUIRREL_PART + if(SQ_PreviewWidget::instance()->cancel()) + SQ_WidgetStack::instance()->diroperator()->stopPreview(); +#endif + + if(reset_mode) + return; + + started.start(); + + tabold = tab; + tmptab.empty(); + tab = &tmptab; + reset_mode = true; + + timer_anim->stop(); + images->clear(); + + tab->m_File = file; // original name + tab->File = TQFile::encodeName(tab->m_File); // translated name + tab->m_original = m_original; + + TQFileInfo fm(file); + tab->fmt_ext = fm.extension(false); + tab->fmt_size = fm.size(); + +#ifndef KSQUIRREL_PART + // show window with image + KSquirrel::app()->raiseGLWidget(); +#endif + + if(m_expected.isEmpty()) + TDEApplication::eventLoop()->processEvents(TQEventLoop::ExcludeUserInput | TQEventLoop::ExcludeSocketNotifiers); + + decode(); +} + +/* + * Prepare decoding. It will find proper library for decoding, + * clear old memory buffers, etc. + */ +bool SQ_GLWidget::prepare() +{ + TQString status; + + tab = &tmptab; + + // get library from cache + SQ_LIBRARY *m_lib = SQ_LibraryHandler::instance()->libraryForFile(tab->m_File); + + if(!m_lib) + { + KMessageBox::error(this, i18n("Codec for %1 format not found").arg(tab->fmt_ext)); + reset_mode = false; + tab = tabold; + return false; + } + else + tmptab.lib = m_lib; + + enableActions(true); + + int already = -1, result = -1, i = 0; + SQ_Config::instance()->setGroup("GL view"); + +#ifndef KSQUIRREL_PART + bool use_tabs = SQ_GLView::window()->tabs(); +#endif + + bool useCurrent = false; + +#ifndef KSQUIRREL_PART + if(!use_tabs) + { + removeCurrentTabs(); + + SQ_GLView::window()->removeTabs(); + } + else + { + if(m_expected != m_original) + { + std::vector<Tab>::iterator it = tabs.begin(); + std::vector<Tab>::iterator itEnd = tabs.end(); + for(;it != itEnd;++it, ++i) + { + if((*it).m_original == m_original) + { + already = i; + useCurrent = true; + break; + } + } + } + + // 0 - new page + // 1 - replace current tab + // 2 - close all and open in a new tab + // -1 - ignore 'result' at all + if(already == -1 + && decoded + && m_expected != m_original + && !useCurrent + && SQ_Config::instance()->readBoolEntry("tabs_ask", false)) + { + SQ_TabOpenDialog tbo(this); + tbo.exec(); + result = tbo.result(); + } + } +#else + removeCurrentTabs(); +#endif + +#ifndef KSQUIRREL_PART + int curtab = SQ_GLView::window()->tabbar()->indexOf(SQ_GLView::window()->tabbar()->currentTab()); +#else + int curtab = -1; +#endif + + int curindex = (already == -1) ? curtab : already; + + if(curindex != -1 && (m_expected == m_original || result == 1 || useCurrent)) + { + if(curtab != curindex) + tabs[curtab].removeParts(); + + tabs[curindex].clearParts(); + tabs[curindex] = tmptab; + tab = &tabs[curindex]; + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->tabbar()->blockSignals(true); + SQ_GLView::window()->tabbar()->setCurrentTab(SQ_GLView::window()->tabbar()->tabAt(curindex)); + SQ_GLView::window()->tabbar()->tabAt(curindex)->setText(KStringHandler::csqueeze(tab->m_original.fileName(), SQ_TAB_TEXT_LENGTH)); + SQ_GLView::window()->tabbar()->blockSignals(false); +#endif + } + else + { + if(curindex != -1) + { + if(result == 2) + closeAllTabs(); + else + tabs[curindex].removeParts(); + } + + tabs.push_back(tmptab); + int lastId = tabs.size() - 1; + tab = &tabs[lastId]; + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->tabbar()->blockSignals(true); + SQ_GLView::window()->addPage(KStringHandler::csqueeze(tab->m_original.fileName(), SQ_TAB_TEXT_LENGTH)); + SQ_GLView::window()->tabbar()->setCurrentTab(SQ_GLView::window()->tabbar()->tabAt(lastId)); + + // TQTabBar::show will emit selected(int), + // we don't want it + emit tabCountChanged(); + SQ_GLView::window()->tabbar()->blockSignals(false); +#endif + } + + gls->setVisible(false); + + SQ_CodecSettings::applySettings(tab->lib, SQ_CodecSettings::ImageViewer); + + // determine codec + tab->codeK = tab->lib->codec; + + // start decoding! + i = tab->codeK->read_init(tab->File.ascii()); + + // oops, error... + if(i != SQE_OK) + { + decodeFailedOn0(i); + m_expected = KURL(); + return false; + } + + return true; +} + +void SQ_GLWidget::decode() +{ + // prepare decoding... + if(!prepare()) + return; + +#ifndef KSQUIRREL_PART + KSquirrel::app()->setCaption(originalURL()); +#endif + + zoomFactor = getZoom(); + matrix_pure_reset(); + matrixChanged(); + +#ifdef SQ_HAVE_KEXIF + KExifData d; + d.readFromFile(tab->m_File); + tab->orient = d.getImageQt::Orientation(); + tab->wm = SQ_Utils::exifGetMatrix(TQString(), tab->orient); + + tab->rotate = (tab->orient == KExifData::ROT_90_HFLIP || tab->orient == KExifData::ROT_90 + || tab->orient == KExifData::ROT_90_VFLIP || tab->orient == KExifData::ROT_270); +#else + tab->orient = -1; + tab->rotate = false; +#endif + + errors = 0; + +/* *********************************************************** */ + + int i, j, id; + int line, res, first_id = 0; + fmt_image *im; + memoryPart *pt; + bool progr; + + SQ_Config::instance()->setGroup("GL view"); + + // in fullscreen mode progressive loading is disabled anyway + if(fullscreen()) + progr = false; + else + progr = SQ_Config::instance()->readBoolEntry("progressiv", true); + + int allpages = SQ_Config::instance()->readNumEntry("load_pages", 0); + int pages_num = SQ_Config::instance()->readNumEntry("load_pages_number", 1); + + if(pages_num < 1) pages_num = 1; + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBFile")->setText(tab->m_original.fileName()); +#else + t_glv.sbarWidget("SBFile")->setText(tab->m_original.fileName()); +#endif + + tab->current = 0; + + bool notexpected = m_expected.isEmpty(); + m_expected = KURL(); + + // start time counting + while(true) + { + if((allpages == 1 && tab->current) || (allpages == 2 && tab->current == pages_num)) + break; + + // absolute evil, but should do... + if(notexpected) + TDEApplication::eventLoop()->processEvents(TQEventLoop::ExcludeUserInput | TQEventLoop::ExcludeSocketNotifiers); + + i = tab->codeK->read_next(); + + // something went wrong. SQE_NOTOK is a special type of error. It means + // that we decoded all pages. + if(i != SQE_OK) + { + if(i == SQE_NOTOK || tab->current) + break; + else + { + decodeFailedOn0(i); + return; + } + } + + im = tab->codeK->image(tab->current); + + Parts pp; + + // find tile size + SQ_GLWidget::findCloserTiles(im->w, im->h, pp.tilesx, pp.tilesy); + TQPair<int, int> pair = SQ_GLWidget::calcRealDimensions(pp); + pp.realw = pair.first; + pp.realh = pair.second; + + // setup current Part + pp.w = im->w; + pp.h = im->h; + + // create textures and display lists + if(!pp.makeParts()) + { + if(tab->current) + break; + else + { + KMessageBox::error(this, + i18n("Memory allocation failed for %1 of memory") + .arg(TDEIO::convertSize(pp.realw * pp.realh * sizeof(RGBA)))); + + decodeFailedOn0(SQE_R_NOMEMORY); + return; + } + } + + pt = new memoryPart(pp.realw * pp.realh); + pt->create(); + + if(!pt->valid()) + { + pp.removeParts(); + + if(tab->current) + break; + else + { + KMessageBox::error(this, i18n("Memory allocation failed")); + decodeFailedOn0(SQE_R_NOMEMORY); + return; + } + } + + line = 0; + + pp.computeCoords(); + pp.buffer = pt; + + tab->finfo = tab->codeK->information(); + + if(!tab->current) + { + tab->isflippedH = tab->isflippedV = false; + slotZoomIfLess(); + matrixChanged(); + updateCurrentFileInfo(); + } + + matrix_move_z(SQ_FIRST_TILE_LAYER+tab->current); + + for(int pass = 0;pass < im->passes;pass++) + { + if(tab->codeK->read_next_pass() != SQE_OK) + break; + + bool flip = tab->finfo.image[tab->current].needflip; + line = 0; + int tlsy = pp.tilesy.size(); + int tlsyval, offs = 0, O, iA; + + for(i = 0;i < tlsy;i++) + { + iA = flip ? (tlsy-i-1) : i; + tlsyval = pp.tilesy[iA]; + + for(j = 0;j < tlsyval;j++) + { + O = flip ? (pp.realw*(im->h - offs - j-1)) : (offs + j)*pp.realw; + res = tab->codeK->read_scanline(pp.buffer->data() + O); + errors += (int)(res != SQE_OK); + + if(++line == im->h) + break; + } + + offs += tlsyval; + + // last pass + if(pass == im->passes-1) + { +// if(!tab->current) + { + bool b = showFrames(iA, &pp, progr); + + if(!b) + kdWarning() << "Showframes failed for image " << tab->current << ", tiley " << i << endl; + } + } + + } + } + + id = images->insertItem(TQString::fromLatin1("#%1 [%2x%3@%4]").arg(tab->current+1).arg(im->w).arg(im->h).arg(im->bpp)); + + images->setItemParameter(id, tab->current); + + if(!tab->current) + { +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBDecodedI")->setPixmap(tab->lib->mime); +#endif + old_id = first_id = id; + } + + tab->parts.push_back(pp); + + calcFrameLabelWidth(); + frameChanged(); + tab->current++; + } + + tab->finfo = tab->codeK->information(); + tab->codeK->read_close(); + tab->total = tab->finfo.image.size(); + tab->current = 0; + frameChanged(); + + enableSettingsButton(!tab->lib->config.isEmpty()); + + decoded = true; + reset_mode = false; + updateGL(); + + tab->quickImageInfo = tab->lib->quickinfo; + tab->elapsed = started.elapsed(); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBLoaded")->setText(TDEGlobal::locale()->formatLong(tab->elapsed) + i18n(" ms.")); +#else + t_glv.sbarWidget("SBLoaded")->setText(TDEGlobal::locale()->formatLong(tab->elapsed) + i18n(" ms.")); +#endif + + images->setItemChecked(first_id, true); + + if(tab->finfo.animated) + TQTimer::singleShot(tab->finfo.image[tab->current].delay, this, TQ_SLOT(slotAnimateNext())); +} + +/* + * Palette changed. Let's update tickmarks and background color. + */ +void SQ_GLWidget::paletteChange(const TQPalette &oldPalette) +{ + TQGLWidget::paletteChange(oldPalette); + + SQ_Config::instance()->setGroup("GL view"); + + if(SQ_Config::instance()->readNumEntry("GL view background type", 1) == 0) + { + TQColor color = colorGroup().color(TQColorGroup::Base); + qglClearColor(color); + updateGL(); + } +} + +void SQ_GLWidget::slotFirst() +{ +#ifndef KSQUIRREL_PART + if(!reset_mode) + SQ_WidgetStack::instance()->firstFile(); +#endif +} + +void SQ_GLWidget::slotLast() +{ +#ifndef KSQUIRREL_PART + if(!reset_mode) + SQ_WidgetStack::instance()->lastFile(); +#endif +} + +void SQ_GLWidget::slotNext() +{ +#ifndef KSQUIRREL_PART + timer_next->stop(); + timer_prev->stop(); + + timer_next->start(timer_delay_file, true); +#endif +} + +void SQ_GLWidget::slotPrev() +{ +#ifndef KSQUIRREL_PART + timer_prev->stop(); + timer_next->stop(); + + timer_prev->start(timer_delay_file, true); +#endif +} + +void SQ_GLWidget::slotZoomMenu() +{ + zoomMenu->exec(TQCursor::pos()); +} + +void SQ_GLWidget::slotAnimateNext() +{ + // Some time ago we started to decode new image, but it is + // not guaranteed that animation stopped! + // + // We should return now to avoid segfaults... + if(reset_mode) + return; + +// tab->parts[tab->current].removeParts(); + + tab->current++; + + if(tab->current >= (int)tab->finfo.image.size()) + tab->current = 0; + + updateCurrentFileInfo(); + updateGL(); + + int delay = tab->finfo.image[tab->current].delay; + + timer_anim->start(delay, true); +} + +void SQ_GLWidget::startAnimation() +{ + if(!tab->finfo.animated) return; + + timer_anim->start(tab->finfo.image[tab->current].delay, true); +} + +void SQ_GLWidget::stopAnimation() +{ + timer_anim->stop(); +} + +void SQ_GLWidget::slotToggleAnimate() +{ + if(!tab->finfo.animated || gls->valid()) return; + + if(!timer_anim->isActive()) + { + tab->manualBlocked = false; + startAnimation(); + } + else + { + tab->manualBlocked = true; + stopAnimation(); + } +} + +/* + * Next image in animated sequence. Called by user (with F3). + */ +void SQ_GLWidget::nextImage() +{ + // if the image has only one page - do nothing + if(tab->total == 1) + return; + + tab->current++; + + if(tab->current >= tab->total) + tab->current = 0; + + updateGL(); + updateCurrentFileInfo(); +} + +/* + * Previous image in animated sequence. Called by user (with F2). + */ +void SQ_GLWidget::prevImage() +{ + if(tab->total == 1) + return; + + tab->current--; + + if(tab->current < 0) + tab->current = tab->total - 1; + + updateGL(); + updateCurrentFileInfo(); +} + +/* + * Jump to first/last image page. + */ +void SQ_GLWidget::jumpToImage(bool last) +{ + // if the image has only one page - do nothing + if(tab->total == 1) + return; + + tab->current = (last) ? tab->finfo.image.size() - 1 : 0; + + updateGL(); + updateCurrentFileInfo(); +} + +void SQ_GLWidget::initMarks() +{ + for(int i = 0;i < 4;i++) + { + glGenTextures(1, &mark[i]); + + glBindTexture(GL_TEXTURE_2D, mark[i]); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, mm[i].bits()); + } +} + +void SQ_GLWidget::internalZoom(const GLfloat &zF) +{ + tab->curangle = 0.0; + + oldZoom = getZoom(); + matrix_pure_reset(); + + exifRotate(false); + + matrix_zoom(zF); +} + +void SQ_GLWidget::updateFilter(bool nice) +{ + if(nice == linear) + return; + + // store + linear = nice; + + int filter = nice ? GL_LINEAR : GL_NEAREST; + Parts *pt; + + // update all textures + for(int i = 0;i < tab->total;i++) + { + pt = tab->broken ? parts_broken : &tab->parts[i]; + int toxy = pt->m_parts.size(); + + for(int j = 0;j < toxy;j++) + { + glBindTexture(GL_TEXTURE_2D, pt->m_parts[j].tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + } + } + + updateGL(); +} + +/* + * Cleanup method. + */ +void SQ_GLWidget::decodeFailedOn0(const int err_code) +{ + tab->codeK->read_close(); + tab->finfo.image.clear(); + tab->finfo.meta.clear(); + tab->total = 0; + decoded = (bool)tabs.size(); + reset_mode = false; + tab->broken = true; + tab->lib = 0; + + useBrokenImage(err_code); +} + +/* + * Force using broken image + update context. + * Show appropriate error message in statusbar. + */ +void SQ_GLWidget::useBrokenImage(const int err_index) +{ + enableSettingsButton(false); + enableActions(false); + + // save "broken" image information in 'tab->finfo' + tab->finfo.image.push_back(image_broken); + + // reset statusbar widgets + SQ_GLView::window()->resetStatusBar(); + +#ifndef KSQUIRREL_PART + // show error message instead of file name + SQ_GLView::window()->sbarWidget("SBFile")->setText(SQ_ErrorString::instance()->string(err_index)); + KSquirrel::app()->setCaption(TQString()); +#else + t_glv.sbarWidget("SBFile")->setText(SQ_ErrorString::instance()->string(err_index)); +#endif + + matrix_pure_reset(); + tab->curangle = 0; + tab->isflippedH = tab->isflippedV = false; + + changeSlider(1.0); + + // update context and show "broken" image + updateGL(); +} + +/* + * Are we in fullscreen state ? + */ +bool SQ_GLWidget::fullscreen() const +{ +#ifndef KSQUIRREL_PART + KWin::WindowInfo wi = KWin::windowInfo(SQ_GLView::window()->winId()); + + if(wi.valid()) + pAFull->setChecked((wi.state() & NET::FullScreen)); + + return pAFull->isChecked(); +#else + return false; +#endif +} + +/* + * Toggle fullscreen state. + */ +void SQ_GLWidget::toggleFullScreen() +{ +#ifndef KSQUIRREL_PART + bool fs = !fullscreen(); + + pAFull->setChecked(fs); + pAToolFull->setOn(fs); + + KSquirrel::app()->slotFullScreen(fs); +#endif +} + +void SQ_GLWidget::slotSetZoomPercents(int perc) +{ + if(tab->broken || tab->finfo.image.empty()) return; + + GLfloat z = (perc <= 20) ? (GLfloat)perc / 20 : ((GLfloat)perc - 20)/2 + 1.0; + + internalZoom(z); +} + +void SQ_GLWidget::updateFactors() +{ + zoomfactor = SQ_Config::instance()->readNumEntry("zoom", 25); + movefactor = SQ_Config::instance()->readNumEntry("move", 5); + rotatefactor = SQ_Config::instance()->readNumEntry("angle", 90); +} + +void SQ_GLWidget::slotSelectionRect() +{ + stopAnimation(); + tab->glselection = SQ_GLSelectionPainter::Rectangle; + gls->end(); +} + +void SQ_GLWidget::slotSelectionEllipse() +{ + stopAnimation(); + tab->glselection = SQ_GLSelectionPainter::Ellipse; + gls->end(); +} + +void SQ_GLWidget::slotSelectionClear() +{ + tab->glselection = -1; + gls->end(); + + pASelectionEllipse->setChecked(false); + pASelectionRect->setChecked(false); + + if(!manualBlocked()) + startAnimation(); +} + +bool SQ_GLWidget::manualBlocked() +{ + // selection is also blocks animation + return tab->manualBlocked || gls->valid(); +} + +void SQ_GLWidget::setDownloadPercents(int p) +{ + if(p < 0) + percentsLabel->hide(); + else + { + percentsLabel->setText(i18n("Downloading...") + ' ' + TDEIO::convertSize(p)); + percentsLabel->adjustSize(); + percentsLabel->show(); + } +} + +#include "sq_glwidget.moc" diff --git a/src/ksquirrelpart/sq_glwidget.h b/src/ksquirrelpart/sq_glwidget.h new file mode 100644 index 0000000..be4903f --- /dev/null +++ b/src/ksquirrelpart/sq_glwidget.h @@ -0,0 +1,620 @@ +/*************************************************************************** + sq_glwidget.h - description + ------------------- + begin : Mon Mar 15 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + + +#ifndef SQ_GLWIDGET_H +#define SQ_GLWIDGET_H + +#include <tqimage.h> +#include <tqrect.h> +#include <tqpair.h> +#include <tqdatetime.h> + +#include <kurl.h> + +#include <vector> + +#include "sq_glparts.h" + +#ifdef KSQUIRREL_PART +#include "sq_glview.h" +#endif + +class SQ_GLSelectionPainter; +struct SQ_ImageFilterOptions; +struct SQ_ImageBCGOptions; +struct RGBA; + +// parameters in GL matrix +#define MATRIX_C1 tab->matrix[0] +#define MATRIX_S1 tab->matrix[1] +#define MATRIX_X tab->matrix[3] +#define MATRIX_S2 tab->matrix[4] +#define MATRIX_C2 tab->matrix[5] +#define MATRIX_Y tab->matrix[7] +#define MATRIX_Z tab->matrix[11] + +class TDEAction; +class TDEActionCollection; +class TDEToggleAction; +class TDEPopupMenu; +class TDERadioAction; +class KTempFile; + +namespace TDEIO { class Job; } + +class TQTimer; +class TQPopupMenu; +class TQSlider; +class TQLabel; + +class SQ_ToolButtonPopup; +class SQ_ToolButton; +class SQ_ToolBar; + +/* *************************************************************** */ + +/* + * SQ_GLWidget represents a widget, which loads, shows and manipulates + * an image. + * + * It contains complex decoding method. Since OpenGL can show textures + * only with dimensions of power of 2 (32x62, 512, 256 etc.), we should divide + * decoded image into quads and only then generate textures. + * It means, that the image you see consists of several parts: + * + * |---------------------------------- + * | | | + * | tex N1 | tex N2 | + * | | | + * ----------------------------------- <= Entire image + * | | | + * | tex N3 | tex N4 | + * | | | + * ----------------------------------- + * + * + * The main class member is 'parts'. It's an array of decoded images + * and appropriate memory buffers and textures. Here comes an explanation: + * [ use monotype fonts :) ] + * + * textures & coordinates Part + * +-----------------------------------+ ##################### ################## + * | parts[2] | # # #===> # # + * | +-------------------------------------+ # # # # texture id # + * | | parts[1] | |======> ##################### # texture coords # + * | | +-------------------------------------+ | # # # # ... # + * | | | m_parts parts[0] | | # # # ################## + * | | | ##### | | ##################### + * | | | # # | | + * | | | # #===============================| + * | | | # # | + * | | | ##### | + * | | | | memory buffers + * | | | m32 | ############################### + * | | | ##### | #RGBA.#.....#.....#.....#.....# + * | | | # # | #RGBA.#.....#.....#.....#.....# + * | | | # #==================================> ############################### + * +-| | # # | #RGBA.#.....#.....#.....#.....# + * +-| ##### | #RGBA.#.....#.....#.....#.....# + * +-------------------------------------+ ############################### + * \ / + * \ / + * parts + * + * + ****************************************************************************** + * + */ + +class SQ_GLWidget : public TQGLWidget +{ + TQ_OBJECT + + + public: + SQ_GLWidget(TQWidget *parent = 0, const char *name = 0); + ~SQ_GLWidget(); + + void setDownloadPercents(int); + + void removeNonCurrentTabs(int); + + void setExpectedURL(const KURL &u); + + TQString originalURL() const; + + /* + * Start decoding given image. We can call it from anywhere. + */ + void startDecoding(const TQString &file); + void startDecoding(const KURL &url); + + void zoom(GLfloat); + + /* + * Set zoom, move and rotate factors from config. + */ + void updateFactors(); + + /* + * Set clear color for context. + */ + void setClearColor(); + + void setOriginalURL(const KURL &); + + /* + * Get zoom value, e.g. 1.5, 2.2 ... + */ + GLfloat getZoom() const; + + /* + * Get zoom value in percents, e.g. 150, 220 ... + */ + GLfloat getZoomPercents() const; + + TDEActionCollection* actionCollection() const; + + /* + * Are we in fullscreen state ? + */ + bool fullscreen() const; + + /* + * Toggle fullscreen state. + */ + void toggleFullScreen(); + + /* + * Direct call to updateGL(). + */ + void updateGLA() { updateGL(); } + + /* + * Type of zoom: fit width, fit height... + */ + int zoomType(); + + /* + * Filter is GL_LINEAR ? + */ + bool isnice(); + + /* + * Direct call to glInit(); + */ + void glInitA() { TQGLWidget::glInit(); } + + /* + * Start animation, if loaded image is animated. + */ + void startAnimation(); + + /* + * Stop animation, if loaded image is animated. + */ + void stopAnimation(); + + /* + * Is animation stopped by user ? + */ + bool manualBlocked(); + + /* + * Change statusbar info according with + * current matrix (it shows current zoom & angle values). + */ + void matrixChanged(); + + /* + * Check or uncheck 'Slideshow' button in toolbar. + */ + void updateSlideShowButton(bool toggled); + + void closeAllTabsFull(); + + static SQ_GLWidget* window() { return m_instance; } + + protected: + + /* + * Next three methods should be reimplemented in + * every TQGLWidget's subclass. + */ + void initializeGL(); + void paintGL(); + void resizeGL(int,int); + + /* + * Mouse wheel event. Let's load next/previous image, or + * zoom in/zoom out (depends on settings). + */ + void wheelEvent(TQWheelEvent *); + + /* + * Palette changed. Let's update tickmarks and background color. + */ + void paletteChange(const TQPalette &oldPalette); + + /* + * Accept drag-and-drop events. We can drop some images + * on this widget, SQ_GLWidget will try to decode first file. + * + * TODO: find first supported image and decode it ? + */ + void dragEnterEvent(TQDragEnterEvent *); + void dropEvent(TQDropEvent *); + + /* + * Mouse events. + */ + void mousePressEvent(TQMouseEvent *); + void mouseReleaseEvent(TQMouseEvent *); + void mouseMoveEvent(TQMouseEvent *); + + private: + void copyURL(); + + TQImage generatePreview(); + + bool calcSelection(); + + void changeSlider(GLfloat z = -1.0); + + void hackMatrix(); + + void enableActions(bool U); + + void initAccelsAndMenu(); + + void crop(); + void bcg(); + void filter(); + void editUpdate(); + + /* + * Save current image page to clipboard + */ + void toClipboard(); + + /* + * Save current image page to file + */ + void saveAs(); + + void enableSettingsButton(bool enab); + + /* + * Remove currently loaded textures and memory buffers. + */ + void removeCurrentParts(); + void removeCurrentTabs(); + + void closeAllTabs(); + + /* + * Since 0.6.0-final KSquirrel doesn't show error messages, + * if the image is broken or not supported. It uses "broken" image + * instead. This method does all needed init. + */ + void initBrokenImage(); + + /* + * Force using broken image + update context. + * Show appropriate error message in statusbar. + */ + void useBrokenImage(const int err_index); + + /* + * Update filter. If 'nice' is true, use GL_LINEAR + * and GL_NEAREST otherwise. + */ + void updateFilter(bool nice); + + /* + * Cleanup method. + */ + void decodeFailedOn0(const int err_code); + + /* + * Create TDEActions. + */ + void createActions(); + + /* + * Create toolbars. + */ + void createToolbar(); + + /* + * Fill a w x h region with texture. Generate texture if needed. + */ + void draw_background(void *bits, unsigned int *tex, int dim, GLfloat w, GLfloat h, bool &bind, bool deleteOld); + + void setupBits(Parts *p, RGBA *buffer, int y, int x); + + /* + * Jump to first or last image in animated sequence. + */ + void jumpToImage(bool); + + /* + * Next image in animated sequence. Called by user (with F3). + */ + void nextImage(); + + /* + * Previous image in animated sequence. Called by user (with F2). + */ + void prevImage(); + + /* + * Draw (or not) image's background. + */ + void toggleDrawingBackground(); + + /* + * Show popup menu with external tools. + */ + void showExternalTools(); + + /* + * Generate textures for tickmarks and bind them. + */ + void initMarks(); + + /* + * Load and check tickmarks from disk. + */ + void createMarks(); + + /* + * Wrapper for 'delete' key. Called from keyPressEvent(). + */ + void deleteWrapper(); + + /* + * Show current image's width, height and bpp in statusbar. + */ + void updateCurrentFileInfo(); + + /* + * Show/hide tickmarks. + */ + void toogleTickmarks(); + + /* + * Show current page number in multipaged images. + * + * For example: "3/11" means that current page is the third in current image, + * which has 11 pages. + */ + void frameChanged(); + void calcFrameLabelWidth(); + + /* + * Set current zoom to 'z'. + */ + void internalZoom(const GLfloat &z); + + /* + * Find best tile's width and height for given width and height. + */ + static void findCloserTiles(int w, int h, std::vector<int> &x, std::vector<int> &y); + static TQPair<int, int> calcRealDimensions(Parts &, int y = -1, int x = -1); + + /* + * Prepare decoding. It will find proper library for decoding, + * clear old memory buffers, etc. + */ + bool prepare(); + + /* + * Zoom to 'r'. Will be called after somebody used mouse button + * to select zoom region. Return true, if zoomed. + */ + bool zoomRect(const TQRect &r); + + /* + * Bind textures, draw them and create GL lists. + * If 'swap' it true, swap buffers. + */ + bool showFrames(int y, Parts *, bool swap); + + /* + * OpenGL-related methods, not interesting :-) + * + * Move, zoom, reset, flip and rotate current matrix. + */ + void matrix_move(GLfloat x, GLfloat y); + void matrix_move_z(GLfloat z); + bool matrix_zoom(GLfloat ratio); + void matrix_reset(bool = true); + void matrix_pure_reset(); + void matrix_push(); + void matrix_pop(); + void write_gl_matrix(); + void matrix_rotate(GLfloat angle, bool = true); + void matrix_rotate2(GLfloat angle); + void flip(int, bool = true); + void flip_h(); + void flip_v(); + void exifRotate(bool); + + signals: + void tabCountChanged(); + void message(const TQString &); + + public slots: + void slotPrint(); + + void slotSelectionEllipse(); + void slotSelectionRect(); + void slotSelectionClear(); + + private slots: + void decode(); + + void slotAccelActivated(); + + void slotChangeTab(int); + void slotCloseRequest(int); + + void slotCopyJobResult(TDEIO::Job *job); + + /* + * Slots for toolbar's actions: + * fit width, fit height, zoom+, zoom-, rotate, flip, + * first file, last file, reset... + */ + void slotShowNav(); + void slotSetZoomPercents(int); + void slotZoomW(); + void slotZoomH(); + void slotZoomWH(); + void slotZoomPlus(); + void slotZoom100(); + void slotZoomLast(); + void slotZoomMinus(); + void slotZoomIfLess(); + void slotRotateLeft(); + void slotRotateRight(); + void slotFlipV(); + void slotFlipH(); + void slotMatrixReset(); + void slotProperties(); // show image properties + void slotFirst(); + void slotLast(); + void slotNext(); + void slotPrev(); + void slotZoomMenu(); + void slotAnimateNext(); + void slotToggleAnimate(); // start/stop animation + void slotSetCurrentImage(int); + void slotShowImages(); + void slotImagesHidden(); + void slotImagesShown(); + void slotShowHelp(); + void slotShowCodecSettings(); + void slotApplyCodecSettings(); + + void slotBCG(SQ_ImageBCGOptions *); + void slotFilter(SQ_ImageFilterOptions *fltopt); + + void slotCopyResult(TDEIO::Job *); + + private: + TDEAction *pASelectionClear; + TDEToggleAction *pAFull, *pAIfLess, *pAZoomW, + *pAZoomH, *pAZoomWH, *pAZoom100, + *pAZoomLast, + *pASelectionEllipse, *pASelectionRect; + + SQ_ToolButton *pAToolQuick, *pAToolFull, *pAToolProp, *pAToolPrint; + SQ_ToolButtonPopup *pAToolZoom, *pAToolImages; + + TDEActionCollection *ac, *acMain; + TQPopupMenu *menu, *menuFile, *menuImage; + int id_saveas, id_settings, + id_f5, id_f6, id_f7, id_f8, id_del, + id_prop; + + // popup menu with zoom types (fit width, fit height, zoom 100%...) + TDEPopupMenu *zoomMenu, *selectionMenu, + + // popup menu with image pages + *images; + + TQImage BGpixmap, BGquads; + + TQTimer *timer_prev, *timer_next; + TQTimer *timer_anim; + + TQImage mm[4]; + + fmt_image image_broken; + SQ_GLSelectionPainter *gls; + + Parts *parts_broken; + + GLfloat saved[12], zoomfactor, movefactor, rotatefactor; + + unsigned int texQuads, texPixmap, mark[4]; + int xmoveold, ymoveold, xmove, ymove, + zoom_type, old_id, total, errors, movetype; + bool reset_mode, decoded, blocked, + changed, marks, linear; + float zoomFactor, oldZoom; + RGBA *buffer; + TQSlider *slider_zoom; + + KTempFile *tmp; + KURL lastCopy, m_expected, m_original; + TQTime clickTime, started; + + std::vector<Tab> tabs; + Tab *tab, *tabold; + Tab tmptab, taborig; + bool hackResizeGL, bindChecker; + + TQLabel *percentsLabel; + +#ifdef KSQUIRREL_PART + SQ_GLView t_glv; +#endif + + static SQ_GLWidget *m_instance; +}; + +inline +int SQ_GLWidget::zoomType() +{ + return zoom_type; +} + +inline +bool SQ_GLWidget::isnice() +{ + return linear; +} + +inline +TDEActionCollection* SQ_GLWidget::actionCollection() const +{ + return ac; +} + +inline +void SQ_GLWidget::setOriginalURL(const KURL &u) +{ + m_original = u; +} + +inline +TQString SQ_GLWidget::originalURL() const +{ + return tab->m_original.isLocalFile() ? tab->m_original.path() : tab->m_original.prettyURL(); +} + +inline +void SQ_GLWidget::setExpectedURL(const KURL &u) +{ + m_expected = u; +} + +#endif diff --git a/src/ksquirrelpart/sq_glwidget_helpers.cpp b/src/ksquirrelpart/sq_glwidget_helpers.cpp new file mode 100644 index 0000000..0dd96c0 --- /dev/null +++ b/src/ksquirrelpart/sq_glwidget_helpers.cpp @@ -0,0 +1,264 @@ +/*************************************************************************** + sq_glwidget_helpers.cpp - description + ------------------- + begin : 7 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqwmatrix.h> +#include <tqrect.h> +#include <tqpoint.h> +#include <tqpointarray.h> + +#include <algorithm> +#include <cstdlib> + +#include <tdetoolbar.h> + +#include <ksquirrel-libs/fmt_defs.h> + +#ifdef SQ_HAVE_KEXIF +#include <libkexif/kexifdata.h> +#endif + +#include "sq_glwidget_helpers.h" + +SQ_ToolButtonPopup::SQ_ToolButtonPopup(const TQPixmap &pix, const TQString &textLabel, TDEToolBar *parent) + : TDEToolBarButton(pix, -1, parent, 0, textLabel) +{ + setFixedWidth(SQ_ToolButton::fixedWidth()); +} + +SQ_ToolButtonPopup::~SQ_ToolButtonPopup() +{} + +SQ_ToolButton::SQ_ToolButton(const TQIconSet &iconSet, const TQString &textLabel, + TQObject *receiver, const char *slot, TDEToolBar *parent, const char *name) + : TQToolButton(iconSet, textLabel, TQString(), receiver, slot, parent, name) +{ + setFixedWidth(SQ_ToolButton::fixedWidth()); +} + +SQ_ToolButton::~SQ_ToolButton() +{} + +int SQ_GLHelpers::roundAngle(int curangle) +{ + int sign = (curangle < 0 ? -1 : 1); + curangle = std::abs(curangle); + + if((curangle > 0 && curangle < 45) || (curangle >= 315 && curangle < 360)) + curangle = 0; + else if(curangle >= 45 && curangle < 135) + curangle = 90; + else if(curangle >= 135 && curangle < 225) + curangle = 180; + else if(curangle >= 225 && curangle < 315) + curangle = 270; + + curangle *= sign; + + return curangle; +} + +void SQ_GLHelpers::subRotation(TQWMatrix &wm, int curangle, int orient) +{ + curangle = SQ_GLHelpers::roundAngle(curangle); + +#ifdef SQ_HAVE_KEXIF + switch(orient) + { + case KExifData::ROT_180: curangle -= 180; break; + case KExifData::ROT_90_HFLIP: + case KExifData::ROT_90: + case KExifData::ROT_90_VFLIP: curangle -= 90; break; + case KExifData::ROT_270: curangle -= 270; break; + + default: ; + } +#endif + + switch(curangle) + { + case -180: + case 180: wm.rotate(180); break; + + case -270: + case 90: wm.rotate(90); break; + + case -90: + case 270: wm.rotate(270); break; + + default: ; + } +} + +bool SQ_GLHelpers::normalizeSelection(int &sx, int &sy, int &sw, int &sh, int w, int h, const TQWMatrix &matr, int curangle, int orient) +{ + TQWMatrix wm = matr; + + SQ_GLHelpers::subRotation(wm, curangle, orient); + + if(!wm.isIdentity()) + { + int ax = -w/2 + sx; + int ay = h/2 - sy; + + TQPointArray pa(4), pb; + + pa.setPoint(0, ax, ay-sh); + pa.setPoint(1, ax+sw, ay-sh); + pa.setPoint(2, ax+sw, ay); + pa.setPoint(3, ax, ay); + + pb = wm.map(pa); + + int fx, fy, fx2, fy2; + fx = std::min(std::min(pb.point(0).x(), pb.point(1).x()), std::min(pb.point(2).x(), pb.point(3).x())); + fy = std::max(std::max(pb.point(0).y(), pb.point(1).y()), std::max(pb.point(2).y(), pb.point(3).y())); + + fx2 = std::max(std::max(pb.point(0).x(), pb.point(1).x()), std::max(pb.point(2).x(), pb.point(3).x())); + fy2 = std::min(std::min(pb.point(0).y(), pb.point(1).y()), std::min(pb.point(2).y(), pb.point(3).y())); + + sx = fx; + sy = fy; + sw = fx2 - fx; + sh = fy - fy2; + + sx += w/2; + sy = h/2-sy; + } + + if(sx > w || sy > h || sx + sw < 0 || sy + sh < 0) + return false; + + if(sx < 0) { sw = sw+sx; sx = 0; } + if(sy < 0) { sh = sh+sy; sy = 0; } + + if(sx + sw > w) sw = w - sx; + if(sy + sh > h) sh = h - sy; + + return (sw && sh); +} + +void SQ_GLHelpers::scanLine0(RGBA *data, RGBA *scan, int rw, int w, int h, int y, int flip) +{ + if(flip == 1) + { + data = data + rw*y + w-1; + + for(int i = 0;i < w;i++) + { + *scan = *data; + + scan++; + data--; + } + } + else if(flip == 2) + { + data = data + rw*(h-1-y); + + for(int i = 0;i < w;i++) + { + *scan = *data; + + scan++; + data++; + } + } + else + memcpy(scan, data + rw*y, w * sizeof(RGBA)); +} + +void SQ_GLHelpers::scanLine90(RGBA *data, RGBA *scan, int rw, int w, int h, int y, int flip) +{ + if(flip == 2) + { + data = data + y; + + for(int i = 0;i < h;i++) + { + *scan = *data; + + scan++; + data += rw; + } + } + else + { + data = flip == 1 ? (data + rw*(h-1) + w-y-1) : (data + rw*(h-1) + y); + + for(int i = 0;i < h;i++) + { + *scan = *data; + + scan++; + data -= rw; + } + } +} + +void SQ_GLHelpers::scanLine180(RGBA *data, RGBA *scan, int rw, int w, int h, int y, int flip) +{ + if(flip == 1) + { + data = data + rw*(h-1-y); + + memcpy(scan, data, w * sizeof(RGBA)); + } + else + { + data = flip == 2 ? (data + rw*y + w-1) : (data + rw*(h-1-y) + w-1); + + for(int i = 0;i < w;i++) + { + *scan = *data; + + scan++; + data--; + } + } +} + +void SQ_GLHelpers::scanLine270(RGBA *data, RGBA *scan, int rw, int w, int h, int y, int flip) +{ + if(flip == 2) + { + data = data + rw*(h-1) + w-y-1; + + for(int i = 0;i < h;i++) + { + *scan = *data; + + scan++; + data -= rw; + } + } + else + { + data = flip == 1 ? (data + y) : (data + w-y-1); + + for(int i = 0;i < h;i++) + { + *scan = *data; + + scan++; + data += rw; + } + } +} diff --git a/src/ksquirrelpart/sq_glwidget_helpers.h b/src/ksquirrelpart/sq_glwidget_helpers.h new file mode 100644 index 0000000..f8cfbd3 --- /dev/null +++ b/src/ksquirrelpart/sq_glwidget_helpers.h @@ -0,0 +1,74 @@ +/*************************************************************************** + sq_glwidget_helpers.h - description + ------------------- + begin : May 31 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_GLWIDGET_HELPERS +#define SQ_GLWIDGET_HELPERS + +#include <tdetoolbarbutton.h> + +class TQWMatrix; + +class TDEToolBar; + +struct RGBA; + +class SQ_ToolButtonPopup : public TDEToolBarButton +{ + public: + SQ_ToolButtonPopup(const TQPixmap &pix, const TQString &textLabel, TDEToolBar *parent); + ~SQ_ToolButtonPopup(); +}; + +class SQ_ToolButton : public TQToolButton +{ + public: + SQ_ToolButton(const TQIconSet &iconSet, const TQString &textLabel, TQObject *receiver, + const char *slot, TDEToolBar *parent, const char *name = 0); + ~SQ_ToolButton(); + + static int fixedWidth(); +}; + +inline +int SQ_ToolButton::fixedWidth() +{ + return 26; +} + +namespace SQ_GLHelpers +{ + // 0, 1, 2 + typedef void (* scanLineGetter)(RGBA *data, RGBA *, int rw, int w, int h, int y, int flip); + + void scanLine0(RGBA *, RGBA *, int, int, int, int, int); + void scanLine90(RGBA *, RGBA *, int, int, int, int, int); + void scanLine180(RGBA *, RGBA *, int, int, int, int, int); + void scanLine270(RGBA *, RGBA *, int, int, int, int, int); + + int roundAngle(int ang); + + void subRotation(TQWMatrix &wm, int curangle, int orient); + + /* + * normalize selection rectangle + * sx,sy are X and Y coordinates + * sw x sh is a selection geometry + */ + bool normalizeSelection(int &sx, int &sy, int &sw, int &sh, int w, int h, const TQWMatrix&, int curangle, int orient); +} + +#endif diff --git a/src/ksquirrelpart/sq_glwidget_stuff.cpp b/src/ksquirrelpart/sq_glwidget_stuff.cpp new file mode 100644 index 0000000..bde87c4 --- /dev/null +++ b/src/ksquirrelpart/sq_glwidget_stuff.cpp @@ -0,0 +1,1782 @@ +/*************************************************************************** + sq_glwidget_stuff.cpp - description + ------------------- + begin : Wed Oct 31 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqclipboard.h> +#include <tqslider.h> +#include <tqdragobject.h> +#include <tqtimer.h> +#include <tqlabel.h> +#include <tqpainter.h> +#include <tqpaintdevicemetrics.h> + +#include <tdeapplication.h> +#include <tdeaction.h> +#include <kstandarddirs.h> +#include <tdelocale.h> +#include <tdepopupmenu.h> +#include <ktabbar.h> +#include <kcursor.h> +#include <tdetempfile.h> +#include <tdemessagebox.h> +#include <tdefileitem.h> +#include <kprinter.h> + +#include <algorithm> + +#ifndef KSQUIRREL_PART +#include "ksquirrel.h" +#include "sq_widgetstack.h" +#endif + +#include "sq_config.h" +#include "sq_libraryhandler.h" +#include "sq_glview.h" +#include "sq_glwidget.h" +#include "sq_glwidget_helpers.h" +#include "sq_imageproperties.h" +#include "sq_helpwidget.h" +#include "sq_filedialog.h" +#include "sq_iconloader.h" +#include "sq_codecsettingsskeleton.h" +#include "sq_externaltool.h" +#include "sq_diroperator.h" +#include "sq_popupmenu.h" +#include "sq_glselectionpainter.h" +#include "sq_utils.h" +#include "sq_imagefilter.h" +#include "sq_imagebcg.h" +#include "fmt_filters.h" + +#ifdef SQ_HAVE_KEXIF +#include <libkexif/kexifdata.h> +#include <libexif/exif-data.h> +#endif + +#include <ksquirrel-libs/fmt_codec_base.h> +#include <ksquirrel-libs/error.h> + +#include "file_broken.xpm" + +// Create actions +void SQ_GLWidget::createActions() +{ + pASelectionRect = new TDEToggleAction(i18n("Rectangle"), TQPixmap(locate("data", "images/actions/glselection_rect.png")), 0, this, TQ_SLOT(slotSelectionRect()), ac, "SQ Selection Rect"); + pASelectionEllipse = new TDEToggleAction(i18n("Ellipse"), TQPixmap(locate("data", "images/actions/glselection_ellipse.png")), 0, this, TQ_SLOT(slotSelectionEllipse()), ac, "SQ Selection Ellipse"); + pASelectionClear = new TDEAction(i18n("Clear"), 0, 0, this, TQ_SLOT(slotSelectionClear()), ac, "SQ Selection Clear"); + + pAZoomW = new TDEToggleAction(i18n("Fit width"), TQPixmap(locate("data", "images/actions/zoomW.png")), 0, this, TQ_SLOT(slotZoomW()), ac, "SQ ZoomW"); + pAZoomH = new TDEToggleAction(i18n("Fit height"), TQPixmap(locate("data", "images/actions/zoomH.png")), 0, this, TQ_SLOT(slotZoomH()), ac, "SQ ZoomH"); + pAZoomWH = new TDEToggleAction(i18n("Fit image"), TQPixmap(locate("data", "images/actions/zoomWH.png")), 0, this, TQ_SLOT(slotZoomWH()), ac, "SQ ZoomWH"); + pAZoom100 = new TDEToggleAction(i18n("Zoom 100%"), TQPixmap(locate("data", "images/actions/zoom100.png")), 0, this, TQ_SLOT(slotZoom100()), ac, "SQ Zoom100"); + pAZoomLast = new TDEToggleAction(i18n("Leave previous zoom"), TQPixmap(locate("data", "images/actions/zoomlast.png")), 0, this, TQ_SLOT(slotZoomLast()), ac, "SQ ZoomLast"); + pAIfLess = new TDEToggleAction(i18n("Ignore, if image is smaller than window"), TQPixmap(locate("data", "images/actions/ifless.png")), 0, 0, 0, ac, "if less"); + + pAFull = new TDEToggleAction(TQString(), 0, 0, 0, ac, "SQ GL Full"); + + TQString squirrel_zoom_actions = TQString::fromLatin1("squirrel_zoom_actions"); + pAZoomW->setExclusiveGroup(squirrel_zoom_actions); + pAZoomH->setExclusiveGroup(squirrel_zoom_actions); + pAZoomWH->setExclusiveGroup(squirrel_zoom_actions); + pAZoom100->setExclusiveGroup(squirrel_zoom_actions); + pAZoomLast->setExclusiveGroup(squirrel_zoom_actions); + + TQString squirrel_selection_type = TQString::fromLatin1("squirrel_selection_type"); + pASelectionEllipse->setExclusiveGroup(squirrel_selection_type); + pASelectionRect->setExclusiveGroup(squirrel_selection_type); + + connect(pAIfLess, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotZoomIfLess())); + +#ifndef KSQUIRREL_PART + connect(pAFull, TQ_SIGNAL(toggled(bool)), KSquirrel::app(), TQ_SLOT(slotFullScreen(bool))); +#endif + + SQ_Config::instance()->setGroup("GL view"); + + pAIfLess->setChecked(SQ_Config::instance()->readBoolEntry("ignore", true)); +} + +void SQ_GLWidget::createToolbar() +{ + zoomMenu = new TDEPopupMenu; + +#ifndef KSQUIRREL_PART + selectionMenu = new TDEPopupMenu; + + SQ_ToolButton *pATool; + + SQ_ToolBar *toolbar = SQ_GLView::window()->toolbar(); + + pASelectionRect->plug(selectionMenu); + pASelectionEllipse->plug(selectionMenu); + selectionMenu->insertSeparator(); + pASelectionClear->plug(selectionMenu); + + // hack to show accels + selectionMenu->changeItem(pASelectionRect->itemId(0), pASelectionRect->text() + "\tCtrl+R"); + selectionMenu->changeItem(pASelectionEllipse->itemId(0), pASelectionEllipse->text() + "\tCtrl+E"); + selectionMenu->changeItem(pASelectionClear->itemId(0), pASelectionClear->text() + "\tCtrl+C"); + + pAZoom100->plug(zoomMenu); + pAZoomLast->plug(zoomMenu); + zoomMenu->insertSeparator(); + pAZoomW->plug(zoomMenu); + pAZoomH->plug(zoomMenu); + pAZoomWH->plug(zoomMenu); + zoomMenu->insertSeparator(); + pAIfLess->plug(zoomMenu); + + switch(zoom_type) + { + case 0: pAZoomW->setChecked(true); break; + case 1: pAZoomH->setChecked(true); break; + case 3: pAZoom100->setChecked(true); break; + case 4: pAZoomLast->setChecked(true); break; + + // "case 2" too + default: pAZoomWH->setChecked(true); + } + +/* + * We will create TQToolButtons and put them in toolbar. + * Of course, we can just TDEAction::plug(), BUT plugged TDEActions + * will produce buttons, which cann't be clicked twise! I think + * plugged TDEActions will treat our attempt as double-click, not two single-clicks. + * On the other hand, we can click TQToolButton as frequently as we want. + * + * Plugged TDEActions also don't know about autorepeat :( + */ + new SQ_ToolButton(TQPixmap(locate("data", "images/actions/file_first.png")), i18n("Go to first image"), this, TQ_SLOT(slotFirst()), toolbar); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/file_prev.png")), i18n("Previous image"), this, TQ_SLOT(slotPrev()), toolbar); + pATool->setAutoRepeat(true); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/file_next.png")), i18n("Next image"), this, TQ_SLOT(slotNext()), toolbar); + pATool->setAutoRepeat(true); + new SQ_ToolButton(TQPixmap(locate("data", "images/actions/file_last.png")), i18n("Go to last image"), this, TQ_SLOT(slotLast()), toolbar); + + // some toolbuttons need autorepeat... + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/zoom+.png")), i18n("Zoom +"), this, TQ_SLOT(slotZoomPlus()), toolbar); + pATool->setAutoRepeat(true); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/zoom-.png")), i18n("Zoom -"), this, TQ_SLOT(slotZoomMinus()), toolbar); + pATool->setAutoRepeat(true); + pAToolZoom = new SQ_ToolButtonPopup(TQPixmap(locate("data", "images/actions/zoom_template.png")), i18n("Zoom"), toolbar); + pAToolZoom->setPopup(zoomMenu); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/rotateL.png")), i18n("Rotate left"), this, TQ_SLOT(slotRotateLeft()), toolbar); + pATool->setAutoRepeat(true); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/rotateR.png")), i18n("Rotate right"), this, TQ_SLOT(slotRotateRight()), toolbar); + pATool->setAutoRepeat(true); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/flipV.png")), i18n("Flip vertically"), this, TQ_SLOT(slotFlipV()), toolbar); + pATool->setAutoRepeat(true); + pATool = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/flipH.png")), i18n("Flip horizontally"), this, TQ_SLOT(slotFlipH()), toolbar); + pATool->setAutoRepeat(true); + new SQ_ToolButton(TQPixmap(locate("data", "images/actions/reload.png")), i18n("Normalize"), this, TQ_SLOT(slotMatrixReset()), toolbar); + + pAToolFull = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/fullscreen.png")), i18n("Fullscreen"), pAFull, TQ_SLOT(activate()), toolbar); + pAToolFull->setToggleButton(true); + pAToolImages = new SQ_ToolButtonPopup(TQPixmap(locate("data", "images/actions/images.png")), i18n("Select image"), toolbar); + pAToolImages->setPopup(images); + SQ_ToolButtonPopup *pAToolSel = new SQ_ToolButtonPopup(TQPixmap(locate("data", "images/actions/glselection.png")), i18n("Selection"), toolbar); + pAToolSel->setPopup(selectionMenu); + pAToolQuick = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/configure.png")), i18n("Codec settings"), this, TQ_SLOT(slotShowCodecSettings()), toolbar); + pAToolQuick->setEnabled(false); + pAToolProp = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/prop.png")), i18n("Image Properties"), this, TQ_SLOT(slotProperties()), toolbar); + pAToolPrint = new SQ_ToolButton(TQPixmap(locate("data", "images/actions/print.png")), i18n("Print"), this, TQ_SLOT(slotPrint()), toolbar); + new SQ_ToolButton(TQPixmap(locate("data", "images/actions/shownav.png")), i18n("Show navigator"), this, TQ_SLOT(slotShowNav()), toolbar); + + slider_zoom = new TQSlider(1, 38, 2, 19, TQt::Horizontal, toolbar); + slider_zoom->setTickmarks(TQSlider::Below); + slider_zoom->setTickInterval(19); + connect(slider_zoom, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(slotSetZoomPercents(int))); + toolbar->insertWidget(1000, 0, slider_zoom); + toolbar->setItemAutoSized(1000); + toolbar->alignItemRight(1000); + + changeSlider(1.0); +#endif +} + +// Show image properties. +void SQ_GLWidget::slotProperties() +{ + if(tab->broken || tab->finfo.image.empty()) return; + + // Stop animation... + stopAnimation(); + + const int real_size = tab->finfo.image[tab->current].w * tab->finfo.image[tab->current].h * sizeof(RGBA); + TQString sz = TDEIO::convertSize(real_size); + TQStringList list; + + TQValueVector<TQPair<TQString,TQString> > meta; + + if(!tab->finfo.meta.empty()) + { + for(std::vector<fmt_metaentry>::iterator it = tab->finfo.meta.begin();it != tab->finfo.meta.end();++it) + { + meta.append(TQPair<TQString,TQString>((*it).group, (*it).data)); + } + } + + // save tab->current image parameters and some additioanl information + // in list + list << tab->quickImageInfo + << TQString::fromLatin1("%1x%2").arg(tab->finfo.image[tab->current].w).arg(tab->finfo.image[tab->current].h) + << TQString::fromLatin1("%1").arg(tab->finfo.image[tab->current].bpp) + << tab->finfo.image[tab->current].colorspace + << tab->finfo.image[tab->current].compression + << sz + << TQString::fromLatin1("%1").arg((double)real_size / tab->fmt_size, 0, 'f', 2) + << ((tab->finfo.image[tab->current].interlaced) ? i18n("yes") : i18n("no")) + << TQString::fromLatin1("%1").arg(errors) + << TQString::fromLatin1("%1").arg(tab->finfo.image.size()) + << TQString::fromLatin1("#%1").arg(tab->current+1) + << TQString::fromLatin1("%1").arg(tab->finfo.image[tab->current].delay); + + // create dialog and setup it + SQ_ImageProperties prop(this); + prop.setFile(tab->m_File); + prop.setURL(tab->m_original); + prop.setParams(list); + prop.setMetaInfo(meta); + + // show! + prop.exec(); + + // restore animation + if(!manualBlocked()) + startAnimation(); +} + +void SQ_GLWidget::findCloserTiles(int w, int h, std::vector<int> &x, std::vector<int> &y) +{ + static int s = 9; + static int dims[10] = { 2, 4, 8, 16, 32, 64, 128, 256, 512 }; + + int *dd[2] = { &w, &h }; + std::vector<int> *dv[2] = { &x, &y }; + int del; + + for(int ff = 0;ff < 2;ff++) + { + if(*dd[ff] == 1) *dd[ff]=2; + else if((*dd[ff])%2) (*dd[ff])++; + + while((*dd[ff]) >= 512) + { + (*dv[ff]).push_back(512); + (*dd[ff]) -= 512; + } + + for(int i = 0;i < s-1;i++) + if((*dd[ff]) >= dims[i] && (*dd[ff]) < dims[i+1]) + { + del = dims[i] + (dims[i]>>1); + + if((*dd[ff]) <= del) + { + (*dv[ff]).push_back(dims[i]); + (*dd[ff]) -= dims[i]; + } + else + { + (*dv[ff]).push_back(dims[i+1]); + (*dd[ff]) -= dims[i+1]; + } + + i = -1; + } + } +} + +TQPair<int, int> SQ_GLWidget::calcRealDimensions(Parts &p, int y, int x) +{ + int rw = 0, rh = 0; + int toy = y == -1 ? p.tilesy.size() : y; + int tox = x == -1 ? p.tilesx.size() : x; + + std::vector<int>::iterator itEnd = p.tilesx.end(); + + for(std::vector<int>::iterator it = p.tilesx.begin();it != itEnd && tox--;++it) + rw += (*it); + + itEnd = p.tilesy.end(); + + for(std::vector<int>::iterator it = p.tilesy.begin();it != itEnd && toy--;++it) + rh += (*it); + + return TQPair<int, int>(rw, rh); +} + +void SQ_GLWidget::slotShowCodecSettings() +{ + tab->lib = SQ_LibraryHandler::instance()->libraryForFile(tab->m_File); + + if(!tab->lib || tab->lib->config.isEmpty()) // oops ? + { + enableSettingsButton(false); + return; + } + + SQ_CodecSettingsSkeleton skel(this); + + connect(&skel, TQ_SIGNAL(apply()), this, TQ_SLOT(slotApplyCodecSettings())); + + skel.addSettingsWidget(tab->lib->config); + skel.setCodecInfo(tab->lib->mime, tab->lib->quickinfo); + skel.adjustSize(); + + if(skel.exec(tab->lib->settings) == TQDialog::Accepted) + tab->lib->codec->set_settings(tab->lib->settings); +} + +void SQ_GLWidget::slotApplyCodecSettings() +{ + if(tab->lib) + { + // new settings are already set by SQ_CodecSettingsSkeleton + tab->lib->codec->set_settings(tab->lib->settings); + m_original = tab->m_original; + startDecoding(TQString(tab->m_File)); + } +} + +void SQ_GLWidget::slotSetCurrentImage(int id) +{ + if(tab->total == 1) + return; + + images->setItemChecked(old_id, false); + tab->current = images->itemParameter(id); + + images->setItemChecked(id, true); + old_id = id; + + updateCurrentFileInfo(); + updateGL(); +} + +void SQ_GLWidget::slotImagesShown() +{ + if(tab->finfo.animated) + { + if(!timer_anim->isActive()) + blocked = false; + else + { + stopAnimation(); + blocked = true; + } + } + + images->setItemChecked(old_id, false); + int id = images->idAt(tab->current); + images->setItemChecked(id, true); + old_id = id; +} + +void SQ_GLWidget::slotShowImages() +{ + images->exec(TQCursor::pos()); +} + +void SQ_GLWidget::slotImagesHidden() +{ + if(blocked && tab->finfo.animated) + startAnimation(); +} + +void SQ_GLWidget::slotShowHelp() +{ + SQ_HelpWidget help_w(this); + + help_w.exec(); +} + +void SQ_GLWidget::showExternalTools() +{ + bool v_ogorogde_buzina_a_v_kieve_dzyadka = SQ_ExternalTool::instance()->constPopupMenu()->isEnabled(); + SQ_ExternalTool::instance()->constPopupMenu()->setEnabled(true); + + KFileItemList items; + KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, tab->m_original); + + if(!tab->m_original.isEmpty()) + { + items.append(&fi); + SQ_ExternalTool::instance()->setItems(items); + } + + SQ_ExternalTool::instance()->constPopupMenu()->exec(TQCursor::pos()); + SQ_ExternalTool::instance()->constPopupMenu()->setEnabled(v_ogorogde_buzina_a_v_kieve_dzyadka); +} + +// Delete current image (user pressed 'Delete' key). +void SQ_GLWidget::deleteWrapper() +{ + if(tab->m_original.isEmpty()) + return; + +#ifndef KSQUIRREL_PART + KFileItemList list; + KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, tab->m_original); + list.append(&fi); + SQ_WidgetStack::instance()->diroperator()->del(list, this); +#else + SQ_DirOperator::instance()->del(tab->m_original, this); +#endif +} + +void SQ_GLWidget::enableSettingsButton(bool enab) +{ +#ifndef KSQUIRREL_PART + pAToolQuick->setEnabled(enab); +#endif + + menuImage->setItemEnabled(id_settings, enab); +} + +void SQ_GLWidget::saveAs() +{ + if(!tab->lib || tab->finfo.image.empty()) // nothing to save + return; + + SQ_Config::instance()->setGroup("GL view"); + TQString lastPath = SQ_Config::instance()->readEntry("saveasPath"); + TQString lastFilt = SQ_Config::instance()->readEntry("saveasFilter"); + + if(lastPath.isEmpty()) + { + KURL u = tab->m_original; + u.cd(".."); + lastPath = u.prettyURL(); + } + + SQ_FileDialog d(lastPath, this); + + // set filter: writable codecs without *.* + d.setFilter(SQ_LibraryHandler::instance()->allFiltersFileDialogString(false, false)); + d.setOperationMode(KFileDialog::Saving); + d.setSelection(tab->m_original.fileName()); + d.setCurrentFilter(lastFilt); + d.updateCombo(false); + + if(d.exec() == TQDialog::Rejected || d.selectedURL().isEmpty()) + return; + + KURL url = d.selectedURL(); + + // cut off file name + KURL u = url; + u.cd(".."); + SQ_Config::instance()->writeEntry("saveasPath", u.prettyURL()); + SQ_Config::instance()->writeEntry("saveasFilter", d.nameFilter()); + + TQString path = url.isLocalFile() ? url.path() : tmp->name(); + + SQ_LIBRARY *wlib = SQ_LibraryHandler::instance()->libraryByName(d.nameFilter()); + + if(!wlib || !wlib->writestatic) + { + KMessageBox::error(this, i18n("Sorry, could not perform write operation\nfor codec \"%1\"").arg(d.nameFilter())); + return; + } + + SQ_GLHelpers::scanLineGetter scgetter; + int flp = 0; + int curangle = SQ_GLHelpers::roundAngle((int)tab->curangle); + + fmt_image im = tab->finfo.image[tab->current]; + +/* + * The easiest way to rotate image is to use TQImage + TQImage::xForm(), + * but this method is VERY memory inefficient. We will use our own tranformation + * routins... Yes, they will be a little bit slower, but they require only + * one scaline in stack. + */ + + int w = im.w, h = im.h; + int rw = tab->parts[tab->current].realw; + +#ifdef SQ_HAVE_KEXIF + switch(tab->orient) + { + case KExifData::HFLIP: + case KExifData::ROT_90_HFLIP: + flp = 1; + break; + + case KExifData::VFLIP: + case KExifData::ROT_90_VFLIP: + flp = 2; + break; + + default: ; + } +#endif + + switch(curangle) + { + case -270: + case 90: scgetter = SQ_GLHelpers::scanLine90; std::swap(w, h); break; + + case -180: + case 180: scgetter = SQ_GLHelpers::scanLine180; break; + + case -90: + case 270: scgetter = SQ_GLHelpers::scanLine270; std::swap(w, h); break; + + default: scgetter = SQ_GLHelpers::scanLine0; + } + + RGBA *scan = new RGBA[w]; + RGBA *data = tab->parts[tab->current].buffer->data(); + + fmt_image im2 = im; + im2.w = w; + im2.h = h; + + fmt_writeoptions opt; + opt.interlaced = false; + opt.alpha = im.hasalpha; + opt.bitdepth = im.bpp; + opt.compression_scheme = (wlib->opt.compression_scheme & CompressionNo) ? CompressionNo : CompressionInternal; + opt.compression_level = wlib->opt.compression_def; + + int err = wlib->codec->write_init(TQString(TQFile::encodeName(path)).ascii(), im2, opt); + + if(err != SQE_OK) + { + KMessageBox::error(this, i18n("Error writing image")); + delete [] scan; + return; + } + + err = wlib->codec->write_next(); + + if(err != SQE_OK) + { + KMessageBox::error(this, i18n("Error writing image")); + delete [] scan; + return; + } + + wlib->codec->write_next_pass(); + + int H = im2.h; + int Y0 = wlib->opt.needflip ? (-H+1):0; + int Y = wlib->opt.needflip ? 1:H; + int f; + + for(int j = Y0;j < Y;j++) + { + f = (j < 0) ? -j : j; + + scgetter(data, scan, rw, im.w, im.h, f, flp); + + err = wlib->codec->write_scanline(scan); + + if(err != SQE_OK) + { + wlib->codec->write_close(); + KMessageBox::error(this, i18n("Error writing image")); + delete [] scan; + return; + } + } + + wlib->codec->write_close(); + delete [] scan; + + // copy to non-local directory + if(!url.isLocalFile()) + { + // src dst perm overwrite resume progress + TDEIO::Job *j = TDEIO::file_copy(path, url, -1, true, false, false); + + connect(j, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotCopyResult(TDEIO::Job *))); + } +} + +void SQ_GLWidget::slotCopyResult(TDEIO::Job *job) +{ + if(job->error()) + { + if(KMessageBox::questionYesNoCancel(this, job->errorString() + '\n' + i18n("Try another location?")) == KMessageBox::Yes) + { + SQ_FileDialog d(TQString(), this); + + // set filter: writable codecs without *.* + d.setFilter(SQ_LibraryHandler::instance()->allFiltersFileDialogString(false, false)); + d.setOperationMode(KFileDialog::Saving); + d.updateCombo(false); + + int result = d.exec(); + + if(result == TQDialog::Rejected || d.selectedURL().isEmpty()) + return; + + TDEIO::Job *j = TDEIO::file_copy(tmp->name(), d.selectedURL(), -1, true, false, false); + connect(j, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotCopyResult(TDEIO::Job *))); + } + } +} + +void SQ_GLWidget::toClipboard() +{ + if(!decoded || tab->broken) + return; + + TQImage im((uchar *)tab->parts[tab->current].buffer->data(), tab->parts[tab->current].realw, tab->parts[tab->current].realh, 32, 0, 0, TQImage::LittleEndian); + + im = im.swapRGB(); + + // image doesn't have extra regions + if(tab->parts[tab->current].realw == tab->parts[tab->current].w && tab->parts[tab->current].realh == tab->parts[tab->current].h) + TDEApplication::clipboard()->setImage(im, TQClipboard::Clipboard); + else + TDEApplication::clipboard()->setImage(im.copy(0, 0, tab->parts[tab->current].w, tab->parts[tab->current].h), TQClipboard::Clipboard); +} + +void SQ_GLWidget::bcg() +{ + if(tab->broken || tab->finfo.image.empty()) return; + + SQ_ImageBCG _bcg(this); + + stopAnimation(); + + _bcg.setPreviewImage(generatePreview()); + + connect(&_bcg, TQ_SIGNAL(bcg(SQ_ImageBCGOptions *)), this, TQ_SLOT(slotBCG(SQ_ImageBCGOptions *))); + + _bcg.exec(); + + if(!manualBlocked()) + startAnimation(); +} + +void SQ_GLWidget::filter() +{ + if(tab->broken || tab->finfo.image.empty()) return; + + SQ_ImageFilter flt(this); + + stopAnimation(); + + flt.setPreviewImage(generatePreview()); + + connect(&flt, TQ_SIGNAL(filter(SQ_ImageFilterOptions *)), this, TQ_SLOT(slotFilter(SQ_ImageFilterOptions *))); + + flt.exec(); + + if(!manualBlocked()) + startAnimation(); +} + +void SQ_GLWidget::slotFilter(SQ_ImageFilterOptions *filtopt) +{ + TQImage im((uchar *)tab->parts[tab->current].buffer->data(), tab->parts[tab->current].realw, tab->parts[tab->current].realh, 32, 0, 0, TQImage::LittleEndian); + TQImage img = gls->valid() ? im.copy(tab->sx, tab->sy, tab->sw, tab->sh) : im; + + fmt_filters::image image = + gls->valid() ? fmt_filters::image((unsigned char *)img.bits(), img.width(), img.height()) + : fmt_filters::image((unsigned char *)img.bits(), tab->parts[tab->current].w, tab->parts[tab->current].h, img.width(), img.height()); + + fmt_filters::rgba c = fmt_filters::white; + + switch(filtopt->type) + { + case F::fblend: fmt_filters::blend(image, filtopt->rgb1, filtopt->_float); break; + case F::fblur: fmt_filters::blur(image, filtopt->_double1, filtopt->_double2);break; + case F::fdesaturate: fmt_filters::desaturate(image, filtopt->_float); break; + case F::fdespeckle: fmt_filters::despeckle(image); break; + case F::fedge: fmt_filters::edge(image, filtopt->_double1); break; + case F::femboss: fmt_filters::emboss(image, filtopt->_double1, filtopt->_double2); break; + case F::fequalize: fmt_filters::equalize(image); break; + case F::ffade: fmt_filters::fade(image, filtopt->rgb1, filtopt->_float); break; + case F::fflatten: fmt_filters::flatten(image, filtopt->rgb1, filtopt->rgb2); break; + case F::fimplode: fmt_filters::implode(image, filtopt->_double1, c); break; + case F::fnegative: fmt_filters::negative(image); break; + case F::fnoise: fmt_filters::noise(image, (fmt_filters::NoiseType)filtopt->_uint); break; + case F::foil: fmt_filters::oil(image, filtopt->_double1); break; + case F::fshade: fmt_filters::shade(image, filtopt->_bool, filtopt->_double1, filtopt->_double2); break; + case F::fsharpen: fmt_filters::sharpen(image, filtopt->_double1, filtopt->_double2); break; + case F::fsolarize: fmt_filters::solarize(image, filtopt->_double1); break; + case F::fspread: fmt_filters::spread(image, filtopt->_uint); break; + case F::fswapRGB: fmt_filters::swapRGB(image, filtopt->_uint); break; + case F::fswirl: fmt_filters::swirl(image, filtopt->_double1, c); break; + case F::fthreshold: fmt_filters::threshold(image, filtopt->_uint); break; + case F::fgray: fmt_filters::gray(image); break; + case F::fredeye: fmt_filters::redeye(image, image.w, image.h, 0, 0, filtopt->_uint); break; + } + + if(gls->valid()) bitBlt(&im, tab->sx, tab->sy, &img, 0, 0, img.width(), img.height()); + + editUpdate(); + + SQ_ImageFilter::instance()->setPreviewImage(generatePreview()); +} + +void SQ_GLWidget::slotBCG(SQ_ImageBCGOptions *bcgopt) +{ + TQImage im((uchar *)tab->parts[tab->current].buffer->data(), tab->parts[tab->current].realw, tab->parts[tab->current].realh, 32, 0, 0, TQImage::LittleEndian); + TQImage img = gls->valid() ? im.copy(tab->sx, tab->sy, tab->sw, tab->sh) : im; + + fmt_filters::image image = + gls->valid() ? fmt_filters::image((unsigned char *)img.bits(), img.width(), img.height()) + : fmt_filters::image((unsigned char *)img.bits(), tab->parts[tab->current].w, tab->parts[tab->current].h, img.width(), img.height()); + if(bcgopt->b) + fmt_filters::brightness(image, bcgopt->b); + + if(bcgopt->c) + fmt_filters::contrast(image, bcgopt->c); + + if(bcgopt->g != 100) + fmt_filters::gamma(image, (double)bcgopt->g / 100.0); + + if(bcgopt->red || bcgopt->green || bcgopt->blue) + fmt_filters::colorize(image, bcgopt->red, bcgopt->green, bcgopt->blue); + + if(gls->valid()) bitBlt(&im, tab->sx, tab->sy, &img, 0, 0, img.width(), img.height()); + + editUpdate(); + + SQ_ImageBCG::instance()->setPreviewImage(generatePreview()); +} + +bool SQ_GLWidget::calcSelection() +{ + TQSize sz = gls->size(); + TQPoint pt = gls->pos(); + + float z = getZoom(); + float x = pt.x(), y = pt.y(), w = sz.width(), h = sz.height(); + x = x - (float)width()/2 - MATRIX_X + (float)tab->parts[tab->current].w/2 * z; + y = y - (float)height()/2 + MATRIX_Y + (float)tab->parts[tab->current].h/2 * z; + + int sx = (int)(x/z + 0.5); + int sy = (int)(y/z + 0.5); + int sw = (int)(w/z + 0.5); + int sh = (int)(h/z + 0.5); + + if(!sw || !sh) + { + gls->end(); + return false; + } + else + { + if(SQ_GLHelpers::normalizeSelection(sx, + sy, + sw, + sh, + tab->parts[tab->current].w, + tab->parts[tab->current].h, + tab->wm, + (int)tab->curangle, + tab->orient)) + { + tab->srect = TQRect(pt, sz); + tab->sx = sx; + tab->sy = sy; + tab->sw = sw; + tab->sh = sh; + } + else + return false; + } + + return true; +} + +TQImage SQ_GLWidget::generatePreview() +{ + TQImage im((uchar *)tab->parts[tab->current].buffer->data(), tab->parts[tab->current].realw, tab->parts[tab->current].realh, 32, 0, 0, TQImage::LittleEndian); + TQImage img, ret; + + if(gls->valid() && calcSelection()) + img = im.copy(tab->sx, tab->sy, tab->sw, tab->sh); + else + { + if(tab->parts[tab->current].realw == tab->parts[tab->current].w && tab->parts[tab->current].realh == tab->parts[tab->current].h) + img = im; + else + img = im.copy(0, 0, tab->parts[tab->current].w, tab->parts[tab->current].h); + } + + ret = SQ_Utils::scaleImage((unsigned char *)img.bits(), img.width(), img.height(), 160).swapRGB(); + + SQ_Utils::exifRotate(TQString(), ret, tab->orient); + + return ret; +} + +void SQ_GLWidget::editUpdate() +{ + int tlsy = tab->parts[tab->current].tilesy.size(); + + glDeleteLists(tab->parts[tab->current].m_parts[0].list, tlsy); + + for(int i = 0;i < tlsy;i++) + showFrames(i, &tab->parts[tab->current], false); + + updateGL(); +} + +void SQ_GLWidget::slotShowNav() +{ +#ifndef KSQUIRREL_PART + KSquirrel::app()->activate(); +#endif +} + +void SQ_GLWidget::initAccelsAndMenu() +{ + TQPopupMenu *menuRotate = new TQPopupMenu(menu); + TQPopupMenu *menuZoom = new TQPopupMenu(menu); + TQPopupMenu *menuMove = new TQPopupMenu(menu); + +#ifndef KSQUIRREL_PART + TQPopupMenu *menuWindow = new TQPopupMenu(menu); +#endif + + menuImage = new TQPopupMenu(menu); + menuFile = new TQPopupMenu(menu); + + menu->insertItem(SQ_IconLoader::instance()->loadIcon("icons", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("File"), menuFile); + menu->insertItem(SQ_IconLoader::instance()->loadIcon("view_orientation", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("Rotate"), menuRotate); + menu->insertItem(SQ_IconLoader::instance()->loadIcon("viewmag", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("Zoom"), menuZoom); + menu->insertItem(i18n("Move"), menuMove); + +#ifndef KSQUIRREL_PART + menu->insertItem(i18n("Window"), menuWindow); +#endif + + menu->insertItem(i18n("Image"), menuImage); + +#define SQ_ADD_KACTION(b) \ + (new TDEAction(TQString(), b, this, TQ_SLOT(slotAccelActivated()), ac, TQString::fromLatin1("action_%1").arg(b))) + + id_saveas = menuFile->insertItem(SQ_IconLoader::instance()->loadIcon("document-save-as", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("Save As...") + "\tS", SQ_ADD_KACTION(TQt::Key_S), TQ_SLOT(activate())); + +#ifndef KSQUIRREL_PART + menuFile->insertSeparator(); + menuFile->insertItem(TQPixmap(locate("data", "images/menu/next16.png")), i18n("Next") + "\tPageDown", SQ_ADD_KACTION(TQt::Key_PageDown), TQ_SLOT(activate())); + menuFile->insertItem(TQPixmap(locate("data", "images/menu/prev16.png")), i18n("Previous") + "\tPageUp", SQ_ADD_KACTION(TQt::Key_PageUp), TQ_SLOT(activate())); + menuFile->insertItem(TQPixmap(locate("data", "images/menu/first16.png")), i18n("First") + "\tHome", SQ_ADD_KACTION(TQt::Key_Home), TQ_SLOT(activate())); + menuFile->insertItem(TQPixmap(locate("data", "images/menu/last16.png")), i18n("Last") + "\tEnd", SQ_ADD_KACTION(TQt::Key_End), TQ_SLOT(activate())); +#endif + + menuFile->insertSeparator(); + id_f5 = menuFile->insertItem(i18n("Copy to...") + "\tF5", SQ_ADD_KACTION(TQt::Key_F5), TQ_SLOT(activate())); + id_f6 = menuFile->insertItem(i18n("Move to...") + "\tF6", SQ_ADD_KACTION(TQt::Key_F7), TQ_SLOT(activate())); + id_f7 = menuFile->insertItem(i18n("Copy to last folder") + "\tF7", SQ_ADD_KACTION(TQt::Key_F6), TQ_SLOT(activate())); + id_f8 = menuFile->insertItem(i18n("Move to last folder") + "\tF8", SQ_ADD_KACTION(TQt::Key_F8), TQ_SLOT(activate())); + menuFile->insertSeparator(); + id_del = menuFile->insertItem(i18n("Delete") + "\tDelete", SQ_ADD_KACTION(TQt::Key_Delete), TQ_SLOT(activate())); + + menuRotate->insertItem(TQPixmap(locate("data", "images/menu/rotateLeft16.png")), i18n("Rotate left") + "\tCtrl+Left", SQ_ADD_KACTION(TQt::Key_Left+CTRL), TQ_SLOT(activate())); + menuRotate->insertItem(TQPixmap(locate("data", "images/menu/rotateRight16.png")), i18n("Rotate right") + "\tCtrl+Right", SQ_ADD_KACTION(TQt::Key_Right+CTRL), TQ_SLOT(activate())); + menuRotate->insertSeparator(); + menuRotate->insertItem(TQPixmap(locate("data", "images/menu/18016.png")), i18n("Rotate 180'") + "\tCtrl+Up", SQ_ADD_KACTION(TQt::Key_Up+CTRL), TQ_SLOT(activate())); + menuRotate->insertSeparator(); + menuRotate->insertItem(i18n("Rotate 1' left") + "\tAlt+Left", SQ_ADD_KACTION(TQt::Key_Left+ALT), TQ_SLOT(activate())); + menuRotate->insertItem(i18n("Rotate 1' right") + "\tAlt+Right", SQ_ADD_KACTION(TQt::Key_Right+ALT), TQ_SLOT(activate())); + + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom+16.png")), i18n("Zoom +") + "\t+", SQ_ADD_KACTION(TQt::Key_Plus), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom-16.png")), i18n("Zoom -") + "\t-", SQ_ADD_KACTION(TQt::Key_Minus), TQ_SLOT(activate())); + menuZoom->insertItem(i18n("Zoom 2x") + "\tCtrl++", SQ_ADD_KACTION(TQt::Key_Plus+CTRL), TQ_SLOT(activate())); + menuZoom->insertItem(i18n("Zoom 1/2x") + "\tCtrl+-", SQ_ADD_KACTION(TQt::Key_Minus+CTRL), TQ_SLOT(activate())); + menuZoom->insertSeparator(); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom10016.png")), TQString::fromLatin1("100%") + "\t1", SQ_ADD_KACTION(TQt::Key_1), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom20016.png")), TQString::fromLatin1("200%") + "\t2", SQ_ADD_KACTION(TQt::Key_2), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom30016.png")), TQString::fromLatin1("300%") + "\t3", SQ_ADD_KACTION(TQt::Key_3), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom50016.png")), TQString::fromLatin1("500%") + "\t5", SQ_ADD_KACTION(TQt::Key_5), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom70016.png")), TQString::fromLatin1("700%") + "\t7", SQ_ADD_KACTION(TQt::Key_7), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom90016.png")), TQString::fromLatin1("900%") + "\t9", SQ_ADD_KACTION(TQt::Key_9), TQ_SLOT(activate())); + menuZoom->insertItem(TQPixmap(locate("data", "images/menu/zoom100016.png")), TQString::fromLatin1("1000%") + "\t0", SQ_ADD_KACTION(TQt::Key_0), TQ_SLOT(activate())); + + menuMove->insertItem(TQPixmap(locate("data", "images/menu/moveLeft16.png")), i18n("Move left") + "\tRight", SQ_ADD_KACTION(TQt::Key_Right), TQ_SLOT(activate())); + menuMove->insertItem(TQPixmap(locate("data", "images/menu/moveRight16.png")), i18n("Move right") + "\tLeft", SQ_ADD_KACTION(TQt::Key_Left), TQ_SLOT(activate())); + menuMove->insertItem(TQPixmap(locate("data", "images/menu/moveUp16.png")), i18n("Move up") + "\tDown", SQ_ADD_KACTION(TQt::Key_Down), TQ_SLOT(activate())); + menuMove->insertItem(TQPixmap(locate("data", "images/menu/moveDown16.png")), i18n("Move down") + "\tUp", SQ_ADD_KACTION(TQt::Key_Up), TQ_SLOT(activate())); + + menuImage->insertItem(TQPixmap(locate("data", "images/menu/animate16.png")), i18n("Start/stop animation") + "\tA", SQ_ADD_KACTION(TQt::Key_A), TQ_SLOT(activate())); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/background16.png")), i18n("Hide/show background") + "\tB", SQ_ADD_KACTION(TQt::Key_B), TQ_SLOT(activate())); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/tickmarks16.png")), i18n("Hide/show tickmarks") + "\tK", SQ_ADD_KACTION(TQt::Key_K), TQ_SLOT(activate())); + menuImage->insertSeparator(); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/flipV16.png")), i18n("Flip vertically") + "\tV", SQ_ADD_KACTION(TQt::Key_V), TQ_SLOT(activate())); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/flipH16.png")), i18n("Flip horizontally") + "\tH", SQ_ADD_KACTION(TQt::Key_H), TQ_SLOT(activate())); + menuImage->insertSeparator(); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/page116.png")), i18n("First page") + "\tF1", SQ_ADD_KACTION(TQt::Key_F1), TQ_SLOT(activate())); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/page216.png")), i18n("Previous page") + "\tF2", SQ_ADD_KACTION(TQt::Key_F2), TQ_SLOT(activate())); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/page316.png")), i18n("Next page") + "\tF3", SQ_ADD_KACTION(TQt::Key_F3), TQ_SLOT(activate())); + menuImage->insertItem(TQPixmap(locate("data", "images/menu/page416.png")), i18n("Last page") + "\tF4", SQ_ADD_KACTION(TQt::Key_F4), TQ_SLOT(activate())); + menuImage->insertSeparator(); + menuImage->insertItem(i18n("Copy file url") + "\tF9", SQ_ADD_KACTION(TQt::Key_F9), TQ_SLOT(activate())); + menuImage->insertItem(i18n("To clipboard") + "\tQ", SQ_ADD_KACTION(TQt::Key_Q), TQ_SLOT(activate())); + menuImage->insertItem(i18n("Print") + "\tCtrl+P", SQ_ADD_KACTION(TQt::Key_P+CTRL), TQ_SLOT(activate())); + menuImage->insertSeparator(); + id_settings = menuImage->insertItem(SQ_IconLoader::instance()->loadIcon("configure", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("Codec settings") + "\tC", SQ_ADD_KACTION(TQt::Key_C), TQ_SLOT(activate())); + menuImage->setItemEnabled(id_settings, false); + menuImage->insertSeparator(); + menuImage->insertItem(i18n("Color balance...") + "\tD", SQ_ADD_KACTION(TQt::Key_D), TQ_SLOT(activate())); + menuImage->insertItem(i18n("Apply filter...") + "\tU", SQ_ADD_KACTION(TQt::Key_U), TQ_SLOT(activate())); + + menuImage->insertItem(i18n("Crop") + "\tY", SQ_ADD_KACTION(TQt::Key_Y), TQ_SLOT(activate())); + +#ifndef KSQUIRREL_PART + menuWindow->insertItem(TQPixmap(locate("data", "images/menu/fullscreen16.png")), i18n("Fullscreen") + "\tF", SQ_ADD_KACTION(TQt::Key_F), TQ_SLOT(activate())); + menuWindow->insertSeparator(); + menuWindow->insertItem(i18n("Previous tab") + "\tShift+Left", SQ_ADD_KACTION(TQt::Key_Left+SHIFT), TQ_SLOT(activate())); + menuWindow->insertItem(i18n("Next tab") + "\tShift+Right", SQ_ADD_KACTION(TQt::Key_Right+SHIFT), TQ_SLOT(activate())); + menuWindow->insertSeparator(); + menuWindow->insertItem(i18n("Close tab") + "\tW", SQ_ADD_KACTION(TQt::Key_W), TQ_SLOT(activate())); + + menuWindow->insertItem(i18n("Close all tabs") + "\tCtrl+W", SQ_ADD_KACTION(TQt::Key_W+CTRL), TQ_SLOT(activate())); +#endif + + menu->insertSeparator(); + menu->insertItem(TQPixmap(locate("data", "images/menu/reset16.png")), i18n("Reset") + "\tR", SQ_ADD_KACTION(TQt::Key_R), TQ_SLOT(activate())); + id_prop = menu->insertItem(TQPixmap(locate("data", "images/menu/prop16.png")), i18n("Properties") + "\tP", SQ_ADD_KACTION(TQt::Key_P), TQ_SLOT(activate())); + menu->insertSeparator(); + menu->insertItem(i18n("Hotkeys") + "\t/", SQ_ADD_KACTION(TQt::Key_Slash), TQ_SLOT(activate())); + +#ifndef KSQUIRREL_PART + menu->insertSeparator(); + menu->insertItem(TQPixmap(locate("data", "images/menu/close16.png")), i18n("Close") + "\tX", SQ_ADD_KACTION(TQt::Key_X), TQ_SLOT(activate())); +#endif + + SQ_ADD_KACTION(TQt::Key_Down+CTRL); + SQ_ADD_KACTION(TQt::Key_Equal); + SQ_ADD_KACTION(TQt::Key_Equal+CTRL); + SQ_ADD_KACTION(TQt::Key_N); + SQ_ADD_KACTION(TQt::Key_Space); + SQ_ADD_KACTION(TQt::Key_BackSpace); + SQ_ADD_KACTION(TQt::Key_Escape); + SQ_ADD_KACTION(TQt::Key_Return); + SQ_ADD_KACTION(TQt::Key_Enter); + SQ_ADD_KACTION(TQt::Key_Z); + SQ_ADD_KACTION(TQt::Key_I); + SQ_ADD_KACTION(TQt::Key_E); + +#ifndef KSQUIRREL_PART + SQ_ADD_KACTION(TQt::Key_R+CTRL); + SQ_ADD_KACTION(TQt::Key_E+CTRL); + SQ_ADD_KACTION(TQt::Key_C+CTRL); +#endif + + SQ_ADD_KACTION(TQt::Key_Menu); + SQ_ADD_KACTION(TQt::Key_M); + SQ_ADD_KACTION(TQt::Key_4); + SQ_ADD_KACTION(TQt::Key_6); + SQ_ADD_KACTION(TQt::Key_8); + SQ_ADD_KACTION(TQt::Key_Comma); + SQ_ADD_KACTION(TQt::Key_Period); + SQ_ADD_KACTION(TQt::Key_Asterisk); + SQ_ADD_KACTION(TQt::Key_L); +} + + +void SQ_GLWidget::slotAccelActivated() +{ + TDEAction *accel = static_cast<TDEAction *>(const_cast<TQObject *>(sender())); + + TDEShortcut ks = accel->shortcut(); + + if(!ks.compare(TQt::Key_Left)) matrix_move(movefactor, 0); + else if(!ks.compare(TQt::Key_Right)) matrix_move(-movefactor, 0); + else if(!ks.compare(TQt::Key_Up)) matrix_move(0, -movefactor); + else if(!ks.compare(TQt::Key_Down)) matrix_move(0, movefactor); + else if(!ks.compare(TQt::Key_Equal) || + !ks.compare(TQt::Key_Plus)) slotZoomPlus(); + else if(!ks.compare(TQt::Key_Minus)) slotZoomMinus(); + else if(!ks.compare(TQt::Key_Equal+CTRL) || + !ks.compare(TQt::Key_Plus+CTRL)) matrix_zoom(2.0f); + else if(!ks.compare(TQt::Key_Minus+CTRL)) matrix_zoom(0.5f); + else if(!ks.compare(TQt::Key_Q)) toClipboard(); + else if(!ks.compare(TQt::Key_V)) slotFlipV(); + else if(!ks.compare(TQt::Key_H)) slotFlipH(); + else if(!ks.compare(TQt::Key_Left+CTRL)) slotRotateLeft(); + else if(!ks.compare(TQt::Key_Right+CTRL)) slotRotateRight(); + else if(!ks.compare(TQt::Key_R)) slotMatrixReset(); + else if(!ks.compare(TQt::Key_Up+CTRL)) matrix_rotate(180.0f); + else if(!ks.compare(TQt::Key_Down+CTRL)) matrix_rotate(-180.0f); + else if(!ks.compare(TQt::Key_Left+ALT)) matrix_rotate(-1.0f); + else if(!ks.compare(TQt::Key_Right+ALT)) matrix_rotate(1.0f); + +#ifndef KSQUIRREL_PART + else if(!ks.compare(TQt::Key_Left+SHIFT)) SQ_GLView::window()->leftTab(); + else if(!ks.compare(TQt::Key_Right+SHIFT)) SQ_GLView::window()->rightTab(); + else if(!ks.compare(TQt::Key_W)) slotCloseRequest(SQ_GLView::window()->tabbar()->indexOf(SQ_GLView::window()->tabbar()->currentTab())); + else if(!ks.compare(TQt::Key_W+CTRL)) closeAllTabsFull(); +#else + else if(!ks.compare(TQt::Key_W)) closeAllTabsFull(); +#endif + + else if(!ks.compare(TQt::Key_N)) updateFilter(!linear); + else if(!ks.compare(TQt::Key_P)) slotProperties(); + else if(!ks.compare(TQt::Key_C)) slotShowCodecSettings(); + +#ifndef KSQUIRREL_PART + else if(!ks.compare(TQt::Key_PageDown) || + !ks.compare(TQt::Key_Space)) slotNext(); + else if(!ks.compare(TQt::Key_PageUp) || + !ks.compare(TQt::Key_BackSpace)) slotPrev(); + else if(!ks.compare(TQt::Key_X) || + !ks.compare(TQt::Key_Escape) || + !ks.compare(TQt::Key_Return) || + !ks.compare(TQt::Key_Enter)) KSquirrel::app()->closeGLWidget(); + else if(!ks.compare(TQt::Key_Home)) slotFirst(); + else if(!ks.compare(TQt::Key_End)) slotLast(); + else if(!ks.compare(TQt::Key_F)) toggleFullScreen(); +#endif + + else if(!ks.compare(TQt::Key_Z)) slotZoomMenu(); + else if(!ks.compare(TQt::Key_S)) saveAs(); + else if(!ks.compare(TQt::Key_A)) slotToggleAnimate(); + else if(!ks.compare(TQt::Key_I)) slotShowImages(); + else if(!ks.compare(TQt::Key_F1)) jumpToImage(false); + else if(!ks.compare(TQt::Key_F2)) prevImage(); + else if(!ks.compare(TQt::Key_F3)) nextImage(); + else if(!ks.compare(TQt::Key_F4)) jumpToImage(true); + else if(!ks.compare(TQt::Key_F5) || !ks.compare(TQt::Key_F6)) + { + // select a directory + KURL url = KFileDialog::getExistingURL(lastCopy.prettyURL(), this); + + if(url.isEmpty()) + return; + + lastCopy = url; + TDEIO::Job *job; + + if(!ks.compare(TQt::Key_F5)) + job = TDEIO::copy(tab->m_original, url); + else + job = TDEIO::move(tab->m_original, url); + + job->setWindow(this); + connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotCopyJobResult(TDEIO::Job *))); + } + else if(!ks.compare(TQt::Key_F7) || !ks.compare(TQt::Key_F8)) + { + TDEIO::Job *job; + + if(!ks.compare(TQt::Key_F6)) + job = TDEIO::copy(tab->m_original, lastCopy); + else + job = TDEIO::move(tab->m_original, lastCopy); + + job->setWindow(this); + connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotCopyJobResult(TDEIO::Job *))); + } + else if(!ks.compare(TQt::Key_F9)) copyURL(); + else if(!ks.compare(TQt::Key_Slash)) slotShowHelp(); + else if(!ks.compare(TQt::Key_B)) toggleDrawingBackground(); + else if(!ks.compare(TQt::Key_K)) toogleTickmarks(); + else if(!ks.compare(TQt::Key_E)) showExternalTools(); + else if(!ks.compare(TQt::Key_Delete)) deleteWrapper(); + else if(!ks.compare(TQt::Key_D)) bcg(); + else if(!ks.compare(TQt::Key_U)) filter(); + else if(!ks.compare(TQt::Key_Y)) crop(); + +#ifndef KSQUIRREL_PART + else if(!ks.compare(TQt::Key_R+CTRL)) slotSelectionRect(); + else if(!ks.compare(TQt::Key_E+CTRL)) slotSelectionEllipse(); + else if(!ks.compare(TQt::Key_C+CTRL)) slotSelectionClear(); +#endif + + else if(!ks.compare(TQt::Key_P+CTRL)) slotPrint(); + else if(!ks.compare(TQt::Key_Menu) || + !ks.compare(TQt::Key_M)) menu->exec(TQCursor::pos()); + else if(!ks.compare(TQt::Key_Comma)) slotZoomW(); + else if(!ks.compare(TQt::Key_Period)) slotZoomH(); + else if(!ks.compare(TQt::Key_Asterisk)) slotZoomWH(); + else if(!ks.compare(TQt::Key_L)) + { + bool b = pAIfLess->isChecked(); + pAIfLess->setChecked(!b); + slotZoomIfLess(); + } + else + { + int val = -1; + + if(!ks.compare(TQt::Key_1)) val = 1; + else if(!ks.compare(TQt::Key_2)) val = 2; + else if(!ks.compare(TQt::Key_3)) val = 3; + else if(!ks.compare(TQt::Key_4)) val = 4; + else if(!ks.compare(TQt::Key_5)) val = 5; + else if(!ks.compare(TQt::Key_6)) val = 6; + else if(!ks.compare(TQt::Key_7)) val = 7; + else if(!ks.compare(TQt::Key_8)) val = 8; + else if(!ks.compare(TQt::Key_9)) val = 9; + else if(!ks.compare(TQt::Key_0)) val = 10; + + if(val != -1) + { + if(tab->broken || tab->finfo.image.empty()) + return; + + zoom(val); + } + } +} + +void SQ_GLWidget::zoom(GLfloat val) +{ + oldZoom = getZoom(); + matrix_reset(false); + matrix_zoom(val); +} + +void SQ_GLWidget::slotCopyJobResult(TDEIO::Job *job) +{ + if(job->error()) + job->showErrorDialog(this); +} + +void SQ_GLWidget::exifRotate(bool U) +{ +#ifdef SQ_HAVE_KEXIF + switch(tab->orient) + { + // flipping + case KExifData::HFLIP: tab->isflippedH = !tab->isflippedH; flip(0, U); break; + case KExifData::VFLIP: tab->isflippedV = !tab->isflippedV; flip(4, U); break; + + // rotating + case KExifData::ROT_90: matrix_rotate(90, U); break; + case KExifData::ROT_180: matrix_rotate(180, U); break; + case KExifData::ROT_270: matrix_rotate(270, U); break; + + // flipping & rotating + case KExifData::ROT_90_HFLIP: tab->isflippedH = !tab->isflippedH; flip(0, false); matrix_rotate(90, U); break; + case KExifData::ROT_90_VFLIP: tab->isflippedV = !tab->isflippedV; flip(4, false); matrix_rotate(90, U); break; + + // normal rotation or unspecified + default: if(U) updateGL(); + } +#else + if(U) + updateGL(); +#endif +} + +void SQ_GLWidget::enableActions(bool U) +{ +#ifndef KSQUIRREL_PART + pASelectionRect->setEnabled(U); + pASelectionEllipse->setEnabled(U); + pASelectionClear->setEnabled(U); + pAToolProp->setEnabled(U); + pAToolPrint->setEnabled(U); +#endif + + menuFile->setItemEnabled(id_f5, U); + menuFile->setItemEnabled(id_f6, U); + menuFile->setItemEnabled(id_f7, U); + menuFile->setItemEnabled(id_f8, U); + menuFile->setItemEnabled(id_del, U); + menuFile->setItemEnabled(id_saveas, U); + + menu->setItemEnabled(id_prop, U); + + menuImage->setEnabled(U); +} + +void SQ_GLWidget::crop() +{ + if(tab->broken + || tab->finfo.image.empty() + || !gls->valid() + || !calcSelection() + || (tab->sw == tab->parts[tab->current].w && tab->sh == tab->parts[tab->current].h)) + return; + + const int RW = tab->parts[tab->current].realw; + RGBA *img = tab->parts[tab->current].buffer->data() + tab->sy * RW + tab->sx; + + Parts pp; + memoryPart *pt; + + SQ_GLWidget::findCloserTiles(tab->sw, tab->sh, pp.tilesx, pp.tilesy); + TQPair<int, int> pair = SQ_GLWidget::calcRealDimensions(pp); + pp.realw = pair.first; + pp.realh = pair.second; + pp.w = tab->sw; + pp.h = tab->sh; + + if(!pp.makeParts()) + { + KMessageBox::error(this, + i18n("Memory allocation failed for %1 of memory") + .arg(TDEIO::convertSize(pp.realw * pp.realh * sizeof(RGBA)))); + return; + } + + pt = new memoryPart(pp.realw * pp.realh); + pt->create(); + + if(!pt->valid()) + { + pp.removeParts(); + return; + } + + memset(pt->data(), 0, pp.realw * pp.realh * sizeof(RGBA)); + + for(int i = 0;i < tab->sh;i++) + memcpy(pt->data()+i*pp.realw, img + i*RW, tab->sw * sizeof(RGBA)); + + pp.computeCoords(); + pp.buffer = pt; + + tab->parts[tab->current].removeParts(); + tab->parts[tab->current].deleteBuffer(); + tab->finfo.image[tab->current].w = tab->sw; + tab->finfo.image[tab->current].h = tab->sh; + + int tlsy = pp.tilesy.size(); + for(int i = 0;i < tlsy;i++) + showFrames(i, &pp, false); + + tab->parts[tab->current] = pp; + + slotSelectionClear(); + updateCurrentFileInfo(); + tab->isflippedH = tab->isflippedV = false; + slotZoomIfLess(); + matrixChanged(); +} + +void SQ_GLWidget::slotChangeTab(int id) +{ +#ifndef KSQUIRREL_PART + id = SQ_GLView::window()->tabbar()->indexOf(id); + + Tab *newtab = (id == -1) ? &taborig : &tabs[id]; + + if(tab == newtab) + return; + + if(tab) + { + tab->removeParts(); + gls->setVisible(false); + } + + tab = newtab; + + images->clear(); + old_id = -1; + stopAnimation(); + + enableSettingsButton(id != -1 && tab->lib && !tab->lib->config.isEmpty()); + enableActions(!tab->broken && id != -1); + + if(id == -1) + { + SQ_GLView::window()->resetStatusBar(); + KSquirrel::app()->setCaption(TQString()); + decoded = false; + changeSlider(1.0); + } + else + { + changeSlider(); + KSquirrel::app()->setCaption(originalURL()); + enableActions(!tab->broken); + + if(!tab->broken) + { + SQ_GLView::window()->sbarWidget("SBDecodedI")->setPixmap(tab->lib->mime); + + // fill menu + std::vector<fmt_image>::iterator itEnd = tab->finfo.image.end(); + std::vector<fmt_image>::iterator it = tab->finfo.image.begin(); + int mid, i = 0, first_id = 0; + + for(;it != itEnd;++it, ++i) + { + mid = images->insertItem(TQString::fromLatin1("#%1 [%2x%3@%4]").arg(i+1).arg((*it).w).arg((*it).h).arg((*it).bpp)); + images->setItemParameter(mid, i); + + if(i == tab->current) + old_id = first_id = mid; + } + + images->setItemChecked(first_id, true); + updateCurrentFileInfo(); + frameChanged(); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBFile")->setText(tab->m_original.fileName(false)); + SQ_GLView::window()->sbarWidget("SBLoaded")->setText(TDEGlobal::locale()->formatLong(tab->elapsed) + i18n(" ms.")); +#else + t_glv.sbarWidget("SBFile")->setText(tab->m_original.fileName(false)); + t_glv.sbarWidget("SBLoaded")->setText(TDEGlobal::locale()->formatLong(tab->elapsed) + i18n(" ms.")); +#endif + } + else + SQ_GLView::window()->resetStatusBar(); + + std::vector<Parts>::iterator itp = tab->parts.begin(); + std::vector<Parts>::iterator itpEnd = tab->parts.end(); + int tlsy; + + tab->remakeParts(); + + if(tab->glselection != -1) + { + if(!gls->valid()) + gls->begin(static_cast<SQ_GLSelectionPainter::Type>(tab->glselection), 0, 0, false); + + gls->setGeometry(tab->srect); + } + else + gls->end(); + + gls->setVisible(tab->glselection != -1); + + for(;itp != itpEnd;++itp) + { + tlsy = (*itp).tilesy.size(); + + for(int i = 0;i < tlsy;i++) + showFrames(i, &(*itp), false); + } + + if(!manualBlocked()) + startAnimation(); + } + + matrixChanged(); + updateGL(); +#endif +} + +void SQ_GLWidget::slotCloseRequest(int index) +{ +#ifndef KSQUIRREL_PART + if(index < 0) + return; + + SQ_GLView::window()->tabbar()->blockSignals(true); + + // prevent matrix from changing. When tab count == 1, + // SQ_GLView will hide tabbar and SQ_GLWIdget will be resized. + // We don't want it. + if(SQ_GLView::window()->tabbar()->count() == 2) + hackResizeGL = true; + + SQ_GLView::window()->removePage(index); + emit tabCountChanged(); + SQ_GLView::window()->tabbar()->blockSignals(false); + + // workaround bug in KTabBar + TQMouseEvent ev(TQEvent::MouseMove, + TQCursor::pos(), + SQ_GLView::window()->tabbar()->mapFromGlobal(TQCursor::pos()), + TQt::NoButton, + TQt::NoButton); + + TDEApplication::sendEvent(SQ_GLView::window()->tabbar(), &ev); + + std::vector<Tab>::iterator itEnd = tabs.end(); + std::vector<Tab>::iterator it = tabs.begin(); + int i = 0; + + for(;(it != itEnd && i != index);++it, ++i) + ; + + (*it).clearParts(); + tabs.erase(it); + tab = 0; + + gls->setVisible(false); + + slotChangeTab(SQ_GLView::window()->tabbar()->currentTab()); +#endif +} + +void SQ_GLWidget::initBrokenImage() +{ + memoryPart *pt; + TQImage broken = TQPixmap(file_broken_xpm).convertToImage().swapRGB(); + broken.setAlphaBuffer(true); + + parts_broken = new Parts; + + // setup parts_broken. It will have only one 64x64 tile + parts_broken->tilesx.push_back(broken.width()); + parts_broken->tilesy.push_back(broken.height()); + parts_broken->realw = broken.width(); + parts_broken->realh = broken.height(); + parts_broken->w = broken.width(); + parts_broken->h = broken.height(); + parts_broken->makeParts(); + parts_broken->computeCoords(); + + pt = new memoryPart(broken.width() * broken.width()); + pt->create(); + + memcpy(pt->data(), broken.bits(), broken.numBytes()); + + parts_broken->buffer = pt; + + showFrames(0, parts_broken, false); + + image_broken.w = parts_broken->w; + image_broken.h = parts_broken->h; + image_broken.bpp = broken.depth(); + image_broken.compression = "-"; + image_broken.colorspace = "RGBA"; + image_broken.hasalpha = false; + + // we don't need memory buffer any more... + parts_broken->deleteBuffer(); +} + +// Accept drop events. +void SQ_GLWidget::dropEvent(TQDropEvent *e) +{ + TQStringList files; + + if(TQUriDrag::decodeLocalFiles(e, files)) + { + // go through array and find first supported image format + for(TQStringList::iterator it = files.begin();it != files.end();++it) + { + if(SQ_LibraryHandler::instance()->libraryForFile(*it)) + { + KURL u = KURL::fromPathOrURL(*it); + m_expected = u; + m_original = u; + startDecoding(u); + break; + } + } + } +} + +// Accept drag events. +void SQ_GLWidget::dragEnterEvent(TQDragEnterEvent *e) +{ + e->accept(TQUriDrag::canDecode(e)); +} + +/* + * Set clear color for context. + */ +void SQ_GLWidget::setClearColor() +{ + TQColor color; + TQString path; + + SQ_Config::instance()->setGroup("GL view"); + + switch(SQ_Config::instance()->readNumEntry("GL view background type", 1)) + { + // system color + case 0: + color = colorGroup().color(TQColorGroup::Base); + break; + + // custom color + case 1: + color.setNamedColor(SQ_Config::instance()->readEntry("GL view background", "#4e4e4e")); + break; + + // repeated texture + case 2: + path = SQ_Config::instance()->readEntry("GL view custom texture", ""); + BGpixmap.load(path); + + if(BGpixmap.isNull()) + { + SQ_Config::instance()->writeEntry("GL view background type", 0); + setClearColor(); + return; + } + + BGpixmap.convertDepth(32); + BGpixmap = BGpixmap.swapRGB(); + + changed = true; + break; + + default: ; + } + + // update clear color + qglClearColor(color); + + if(decoded) + updateGL(); +} + +void SQ_GLWidget::removeCurrentParts() +{ + // if tab->broken, 'tab->parts' has no members + if(decoded && !tab->broken) + { + std::vector<Parts>::iterator itEnd = tab->parts.end(); + + for(std::vector<Parts>::iterator it = tab->parts.begin();it != itEnd;++it) + { + // delete textures and memory buffers + (*it).removeParts(); + (*it).deleteBuffer(); + } + + tab->parts.clear(); + } +} + +void SQ_GLWidget::removeCurrentTabs() +{ + std::vector<Tab>::iterator itEnd = tabs.end(); + + for(std::vector<Tab>::iterator it = tabs.begin();it != itEnd;++it) + (*it).clearParts(); + + tabs.clear(); + tab = &taborig; +} + +void SQ_GLWidget::removeNonCurrentTabs(int index) +{ + std::vector<Tab>::iterator itEnd = tabs.end(); + Tab tm; + int i = 0; + + for(std::vector<Tab>::iterator it = tabs.begin();it != itEnd;++it, ++i) + { + if(i == index) + { + tm = *it; + continue; + } + + (*it).clearParts(); + } + + tabs.clear(); + tabs.push_back(tm); + tab = &tabs[0]; +} + +void SQ_GLWidget::startDecoding(const KURL &url) +{ + startDecoding(url.path()); +} + +// Show/hide background for transparent image. +void SQ_GLWidget::toggleDrawingBackground() +{ + SQ_Config::instance()->setGroup("GL view"); + + bool b = SQ_Config::instance()->readBoolEntry("alpha_bkgr", true); + + b = !b; + + SQ_Config::instance()->writeEntry("alpha_bkgr", b); + + updateGL(); +} + +void SQ_GLWidget::createMarks() +{ + mm[0] = TQImage(locate("data", "images/marks/mark_1.png")); + mm[1] = TQImage(locate("data", "images/marks/mark_2.png")); + mm[2] = TQImage(locate("data", "images/marks/mark_3.png")); + mm[3] = TQImage(locate("data", "images/marks/mark_4.png")); + + marks = (mm[0].isNull() || mm[1].isNull() || mm[2].isNull() || mm[3].isNull()) ? false : true; + + if(!marks) + return; + + for(int i = 0;i < 4;i++) + { + mm[i] = mm[i].convertDepth(32); + mm[i].setAlphaBuffer(true); + } +} + +/* + * Show current image's width, height and bpp in statusbar. + */ +void SQ_GLWidget::updateCurrentFileInfo() +{ + TQString status = TQString::fromLatin1("%1x%2@%3") + .arg(tab->finfo.image[tab->current].w) + .arg(tab->finfo.image[tab->current].h) + .arg(tab->finfo.image[tab->current].bpp); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBDecoded")->setText(status); +#else + t_glv.sbarWidget("SBDecoded")->setText(status); +#endif +} + +// Show/hide tickmarks around the image. +void SQ_GLWidget::toogleTickmarks() +{ + SQ_Config::instance()->setGroup("GL view"); + + bool b = SQ_Config::instance()->readBoolEntry("marks", true); + + b = !b; + + SQ_Config::instance()->writeEntry("marks", b); + + updateGL(); +} + +void SQ_GLWidget::changeSlider(GLfloat z1) +{ +#ifndef KSQUIRREL_PART + GLfloat z = z1 < 0 ? getZoom() : z1; + + int i_zoom = (int)(z * 100); + + slider_zoom->blockSignals(true); + slider_zoom->setValue((i_zoom <= 100) ? i_zoom/5 : (19+i_zoom/50)); + slider_zoom->blockSignals(false); +#endif +} + +void SQ_GLWidget::calcFrameLabelWidth() +{ +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBFrame")->setFixedWidth( + SQ_GLView::window()->sbarWidget("SBFrame")->fontMetrics() + .boundingRect(TQString::fromLatin1("0%1/0%2").arg(tab->total).arg(tab->total)).width()); +#endif +} + +/* + * Show current page number in multipaged images. + * + * For example: "3/11" means that current page is the third in current image, + * which has 11 pages. + */ +void SQ_GLWidget::frameChanged() +{ +#ifndef KSQUIRREL_PART + SQ_GLView::window()->sbarWidget("SBFrame")->setText(TQString::fromLatin1("%1/%2").arg(tab->current+1).arg(tab->total)); +#else + t_glv.sbarWidget("SBFrame")->setText(TQString::fromLatin1("%1/%2").arg(tab->current+1).arg(tab->total)); +#endif +} + +void SQ_GLWidget::closeAllTabs() +{ + removeCurrentTabs(); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->removeTabs(); +#endif +} + +void SQ_GLWidget::closeAllTabsFull() +{ + stopAnimation(); + + closeAllTabs(); + +#ifndef KSQUIRREL_PART + SQ_GLView::window()->resetStatusBar(); + SQ_GLView::window()->tabbar()->hide(); + + KSquirrel::app()->setCaption(TQString()); +#endif + + decoded = false; + m_original = KURL(); + m_expected = KURL(); + + images->clear(); + old_id = -1; + + enableSettingsButton(false); + enableActions(false); + changeSlider(1.0); + + updateGL(); +} + +void SQ_GLWidget::slotPrint() +{ + if(!decoded || tab->broken) + return; + + TQImage im((uchar *)tab->parts[tab->current].buffer->data(), tab->parts[tab->current].realw, tab->parts[tab->current].realh, 32, 0, 0, TQImage::LittleEndian); + TQImage img; + + if(gls->valid() && calcSelection()) + img = TQImage(im.copy(tab->sx, tab->sy, tab->sw, tab->sh)).swapRGB(); + else + { + if(tab->parts[tab->current].realw == tab->parts[tab->current].w && tab->parts[tab->current].realh == tab->parts[tab->current].h) + img = im.swapRGB(); + else + img = TQImage(im.copy(0, 0, tab->parts[tab->current].w, tab->parts[tab->current].h)).swapRGB(); + } + + img.setAlphaBuffer(true); + + KPrinter printer; + + printer.setCreator("KSquirrel"); + + if(printer.setup(this)) + { + TQPainter p(&printer); + + TQPaintDeviceMetrics mt(&printer); + + TQSize sz(img.width(), img.height()); + + if(img.width() > mt.width() || img.height() > mt.height()) + sz.scale(mt.width(), mt.height(), TQSize::ScaleMin); + + int cp = printer.numCopies(); + + for(int i = 0;i < cp;i++) + { + p.drawImage(TQRect((mt.width()-sz.width())/2, (mt.height()-sz.height())/2, sz.width(), sz.height()), img); + + if(i < cp-1) + printer.newPage(); + } + } +} + +void SQ_GLWidget::copyURL() +{ + if(!decoded || tab->broken) + return; + + TQApplication::clipboard()->setText(tab->m_original.prettyURL()); +} diff --git a/src/ksquirrelpart/sq_helpwidget.ui b/src/ksquirrelpart/sq_helpwidget.ui new file mode 100644 index 0000000..cb2a4bc --- /dev/null +++ b/src/ksquirrelpart/sq_helpwidget.ui @@ -0,0 +1,334 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>SQ_HelpWidget</class> +<widget class="TQDialog"> + <property name="name"> + <cstring>SQ_HelpWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>512</width> + <height>430</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Hotkeys</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQWidgetStack" row="1" column="0"> + <property name="name"> + <cstring>widgetStack1</cstring> + </property> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string><p align=center><table><tr><td><b><p align=right>Esc,X,Return</p></b></td><td>close</td></tr><tr><td><b><p align=right>Middle click, F</p></b></td><td>fullscreen</td></tr><tr><td><b><p align=right>Z</p></b></td><td>show 'Zoom' menu</td></tr><tr><td><b><p align=right>/</p></b></td><td>show this help</td></tr><tr><td><b><p align=right>Right click, M, ContextMenu</p></b></td><td>show context menu</td></tr><tr><td><b><p align=right>N</p></b></td><td>toggle filter</td></tr><tr><td><b><p align=right>Shift + Left button</p></b></td><td>select a region</td></tr><tr><td><b><p align=right>Shift + Left</p></b></td><td>previous tab</td></tr><tr><td><b><p align=right>Shift + Right</p></b></td><td>next tab</td></tr><tr><td><b><p align=right>W</p></b></td><td>close tab</td></tr></table></p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string><p align=center><table><tr><td><b><p align=right>Space, Page Down</p></b></td><td>next image</td></tr><tr><td><b><p align=right>Backspace, Page Up</p></b></td><td>previous image</td></tr><tr><td><b><p align=right>Home</p></b></td><td>first image</td></tr><tr><td><b><p align=right>End</p></b></td><td>last image</td></tr></table></p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>2</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string><p align=center><table><tr><td><b><p align=right>Left, Right, Up, Down</p></b></td><td>move the image</td></tr><tr><td><b><p align=right>Ctrl + Left</p></b></td><td>rotate left</td></tr><tr><td><b><p align=right>Ctrl + Right</p></b></td><td>rotate right</td></tr><tr><td><b><p align=right>Ctrl + Up/Down</p></b></td><td>rotate for 180 degrees up/down</td></tr><tr><td><b><p align=right>Alt + Left/Right</p></b></td><td>rotate for 1 degree left/right</td></tr></table</p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>3</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string><p align=center><table><tr><td><b><p align=right>+/-</p></b></td><td>zoom Nx</td></tr><tr><td><b><p align=right>Ctrl + +/-</p></b></td><td>zoom 2x/0.5x</td></tr><tr><td><b><p align=right>Scroll</p></b></td><td>load next/prev file OR zoom+/zoom-</td></tr><tr><td><b><p align=right>Shift + Scroll</p></b></td><td>zoom+/zoom-</td></tr><tr><td><b><p align=right>Ctrl + Scroll</p></b></td><td>zoom+ 2x/zoom- 2x</td></tr><tr><td><b><p align=right>1..9</p></b></td><td>zoom 1..9x</td></tr><tr><td><b><p align=right>0</p></b></td><td>zoom 10x</td></tr><tr><td><b><p align=right>comma</p></b></td><td>fit width</td></tr><tr><td><b><p align=right>period</p></b></td><td>fit height</td></tr><tr><td><b><p align=right>*</p></b></td><td>fit image</td></tr></table</p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>4</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string><p align=center><table><tr><td><p align=right><b>S</b></p></td><td>save as</td></tr><tr><td><p align=right><b>V</b></p></td><td>flip vertically</td></tr><tr><td><p align=right><b>H</b></p></td><td>flip horizontally</td></tr><tr><td><p align=right><b>R</b></p></td><td>reset</td></tr><tr><td><p align=right><b>P</b></p></td><td>image properties</td></tr><tr><td><p align=right><b>C</b></p></td><td>codec settings</td></tr><tr><td><p align=right><b>L</b></p></td><td>ignore zoom if image is smaller than window</td></tr><tr><td><p align=right><b>I</b></p></td><td>menu with images</td></tr><tr><td><p align=right><b>A</b></p></td><td>stop/start animation</td></tr><tr><td><p align=right><b>B</b></p></td><td>toggle drawing background for transparent images</td></tr><tr><td><p align=right><b>K</b></p></td><td>toggle drawing tickmarks</td></tr><tr><td><p align=right><b>E</b></p></td><td>show menu with external tools</td></tr><tr><td><p align=right><b>Y</b></p></td><td>crop</td></tr><tr><td><p align=right><b>F1</b></p></td><td>first image in multi-paged image</td></tr><tr><td><p align=right><b>F2</b></p></td><td>previous</td></tr><tr><td><p align=right><b>F3</b></p></td><td>next</td></tr><tr><td><p align=right><b>F4</b></p></td><td>last</td></tr></table></p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + </widget> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>buttonGroup</cstring> + </property> + <property name="title"> + <string></string> + </property> + <property name="exclusive"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQPushButton" row="0" column="0"> + <property name="name"> + <cstring>pushButton3</cstring> + </property> + <property name="focusPolicy"> + <enum>NoFocus</enum> + </property> + <property name="text"> + <string>General</string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="on"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="buttonGroupId"> + <number>0</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="1"> + <property name="name"> + <cstring>pushButton3_2</cstring> + </property> + <property name="focusPolicy"> + <enum>NoFocus</enum> + </property> + <property name="text"> + <string>Filing</string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="buttonGroupId"> + <number>1</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="2"> + <property name="name"> + <cstring>pushButton3_3</cstring> + </property> + <property name="focusPolicy"> + <enum>NoFocus</enum> + </property> + <property name="text"> + <string>Moving</string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="buttonGroupId"> + <number>2</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="4"> + <property name="name"> + <cstring>pushButton3_5</cstring> + </property> + <property name="focusPolicy"> + <enum>NoFocus</enum> + </property> + <property name="text"> + <string>Current image</string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="buttonGroupId"> + <number>4</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="3"> + <property name="name"> + <cstring>pushButton3_4</cstring> + </property> + <property name="focusPolicy"> + <enum>NoFocus</enum> + </property> + <property name="text"> + <string>Zoom</string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="buttonGroupId"> + <number>3</number> + </property> + </widget> + </grid> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>buttonGroup</sender> + <signal>clicked(int)</signal> + <receiver>widgetStack1</receiver> + <slot>raiseWidget(int)</slot> + </connection> +</connections> +<tabstops> + <tabstop>pushButton3</tabstop> + <tabstop>pushButton3_2</tabstop> + <tabstop>pushButton3_3</tabstop> + <tabstop>pushButton3_5</tabstop> + <tabstop>pushButton3_4</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">tqtooltip.h</include> + <include location="local" impldecl="in implementation">sq_config.h</include> + <include location="local" impldecl="in implementation">sq_helpwidget.ui.h</include> +</includes> +<functions> + <function access="private" specifier="non virtual">init()</function> + <function access="private" specifier="non virtual">destroy()</function> + <function returnType="bool">event( TQEvent * e )</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/ksquirrelpart/sq_helpwidget.ui.h b/src/ksquirrelpart/sq_helpwidget.ui.h new file mode 100644 index 0000000..c0f2673 --- /dev/null +++ b/src/ksquirrelpart/sq_helpwidget.ui.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you want to add, delete, or rename functions or slots, use +** TQt Designer to update this file, preserving your code. +** +** You should not define a constructor or destructor in this file. +** Instead, write your code in functions called init() and destroy(). +** These will automatically be called by the form's constructor and +** destructor. +*****************************************************************************/ + +/* + * SQ_HelpWidget is a helper widget. It shows hotkeys, which + * are accepted by SQ_GLWidget. Called from SQ_GLWidget. + */ + +void SQ_HelpWidget::init() +{ + setPalette(TQToolTip::palette()); + SQ_Config::instance()->setGroup("GL view"); + + int pg = SQ_Config::instance()->readNumEntry("help_id", 0); + + buttonGroup->setButton(pg); + widgetStack1->raiseWidget(pg); +} + +void SQ_HelpWidget::destroy() +{ + SQ_Config::instance()->setGroup("GL view"); + SQ_Config::instance()->writeEntry("help_id", buttonGroup->selectedId()); +} + +bool SQ_HelpWidget::event(TQEvent *e) +{ + if(e->type() == TQEvent::WindowDeactivate + || e->type() == TQEvent::MouseButtonPress + || e->type() == TQEvent::KeyPress) + { + reject(); + } + + return TQDialog::event(e); +} diff --git a/src/ksquirrelpart/sq_iconloader.cpp b/src/ksquirrelpart/sq_iconloader.cpp new file mode 100644 index 0000000..c8c9ec8 --- /dev/null +++ b/src/ksquirrelpart/sq_iconloader.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + sq_iconloader.cpp - description + ------------------- + begin : ??? Aug 20 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tdeglobal.h> +#include <kiconloader.h> + +#include "sq_iconloader.h" +#include "sq_iconloader_pixmaps.h" + +SQ_IconLoader * SQ_IconLoader::m_instance = 0; + +SQ_IconLoader::SQ_IconLoader(TQObject *parent) : TQObject(parent) +{ + m_instance = this; + + fillPixmaps(); +} + +SQ_IconLoader::~SQ_IconLoader() +{} + +TQPixmap SQ_IconLoader::loadIcon(const TQString& name, TDEIcon::Group group, int size) const +{ + // try to load from installed icon theme + TQPixmap p = TDEGlobal::iconLoader()->loadIcon(name, group, size, TDEIcon::DefaultState, 0, true); + + // requested pixmap not found, let's + // try to find it in our pixmaps + if(p.isNull()) + { + if(name == "move_task_up") + p = pixmap_up; + else if(name == "move_task_down") + p = pixmap_down; + else if(name == "display" && size == 32) + p = pixmap_display; + else if(name == "folder" && size == 32) + p = pixmap_folder; + else if(name == "images" && size == 32) + p = pixmap_images; + else if(name == "binary" && size == 32) + p = pixmap_binary; + else if(name == "edit" && size == 32) + p = pixmap_edit; + else + p = TDEGlobal::iconLoader()->loadIcon("unknown", group, size); + } + + return p; +} + +/* + * Internal. Load all pixmaps. + */ +void SQ_IconLoader::fillPixmaps() +{ + pixmap_up = TQPixmap(xpm_up); + pixmap_down = TQPixmap(xpm_down); + pixmap_display = TQPixmap(xpm_display); + pixmap_folder = TQPixmap(xpm_folder); + pixmap_images = TQPixmap(xpm_images); + pixmap_binary = TQPixmap(xpm_binary); + pixmap_edit = TQPixmap(xpm_edit); +} diff --git a/src/ksquirrelpart/sq_iconloader.h b/src/ksquirrelpart/sq_iconloader.h new file mode 100644 index 0000000..dec6a6e --- /dev/null +++ b/src/ksquirrelpart/sq_iconloader.h @@ -0,0 +1,58 @@ +/*************************************************************************** + sq_iconloader.h - description + ------------------- + begin : ??? Aug 20 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_ICONLOADER_H +#define SQ_ICONLOADER_H + +#include <tqobject.h> +#include <tqpixmap.h> + +#include <kicontheme.h> + +/* + * SQ_IconLoader represents an icon loader. It tries to load pixmap from + * installed icon theme. If icon was not found, it uses internal pixmaps + * instead. + */ + +class SQ_IconLoader : public TQObject +{ + public: + SQ_IconLoader(TQObject *parent = 0); + ~SQ_IconLoader(); + + TQPixmap loadIcon(const TQString &name, TDEIcon::Group group = TDEIcon::Desktop, int size = 16) const; + + private: + static SQ_IconLoader *m_instance; + + /* + * Internal. Load all pixmaps. + */ + void fillPixmaps(); + + public: + static SQ_IconLoader* instance() { return m_instance; } + + private: + TQPixmap pixmap_up, pixmap_down, + pixmap_display, pixmap_folder, + pixmap_images, pixmap_binary, + pixmap_edit; +}; + +#endif diff --git a/src/ksquirrelpart/sq_iconloader_pixmaps.h b/src/ksquirrelpart/sq_iconloader_pixmaps.h new file mode 100644 index 0000000..0bc6183 --- /dev/null +++ b/src/ksquirrelpart/sq_iconloader_pixmaps.h @@ -0,0 +1,2557 @@ +/*************************************************************************** + sq_iconloader_pixmaps.h - description + ------------------- + begin : 3 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_ICONLOADER_PIXMAPS +#define SQ_ICONLOADER_PIXMAPS + +static const char * xpm_up[] = { +"22 22 139 2", +" c None", +". c #AE5300", +"+ c #AD5204", +"@ c #B35E10", +"# c #EBD4BF", +"$ c #C78851", +"% c #AD5203", +"& c #F0DDBF", +"* c #FFED80", +"= c #FAEDBF", +"- c #BD7331", +"; c #FFE330", +"> c #FFD900", +", c #FFD710", +"' c #FAECBF", +") c #F0D99F", +"! c #FFE420", +"~ c #FFDC00", +"{ c #FFD700", +"] c #FFD300", +"^ c #FFD210", +"/ c #FAEBBF", +"( c #BD7330", +"_ c #F0DA9F", +": c #FFE410", +"< c #FFDE00", +"[ c #FFDA00", +"} c #FFD600", +"| c #FFD100", +"1 c #FFCD00", +"2 c #FFCC10", +"3 c #FAE9BF", +"4 c #BD7332", +"5 c #FAF0BF", +"6 c #FFE710", +"7 c #FFE100", +"8 c #FFDD00", +"9 c #FFD800", +"0 c #FFD400", +"a c #FFD000", +"b c #FFCB00", +"c c #FFC700", +"d c #FFC710", +"e c #FAE8BF", +"f c #B25D12", +"g c #AE5302", +"h c #FFE910", +"i c #FFE400", +"j c #FFDF00", +"k c #FFDB00", +"l c #FFD200", +"m c #FFCE00", +"n c #FFCA00", +"o c #FFC500", +"p c #FFC100", +"q c #FFC110", +"r c #F0D29F", +"s c #AD5202", +"t c #FAEE8F", +"u c #FFEC10", +"v c #FFE600", +"w c #FFE200", +"x c #FFD500", +"y c #FFCC00", +"z c #FFC800", +"A c #FFC400", +"B c #FFBF00", +"C c #FFBB00", +"D c #FFBB10", +"E c #F0D19F", +"F c #FAEF8F", +"G c #FFED00", +"H c #FFE900", +"I c #FFE500", +"J c #FFE000", +"K c #FFCF00", +"L c #FFC600", +"M c #FFC200", +"N c #FFBE00", +"O c #FFB900", +"P c #FFB500", +"Q c #FFB610", +"R c #F0CF9F", +"S c #B25C15", +"T c #F5E78E", +"U c #FBE802", +"V c #FBE402", +"W c #FBDF02", +"X c #FBDB02", +"Y c #FDDB01", +"Z c #FFC900", +"` c #FFC000", +" . c #F6B104", +".. c #F6AD04", +"+. c #F6A904", +"@. c #F6A504", +"#. c #F5A514", +"$. c #D9A36E", +"%. c #B46107", +"&. c #BC7008", +"*. c #BC6F08", +"=. c #BC6E08", +"-. c #DEA404", +";. c #FFC300", +">. c #D58508", +",. c #BD6506", +"'. c #BD6406", +"). c #BD6306", +"!. c #B95E06", +"~. c #AE5301", +"{. c #D79700", +"]. c #FFBD00", +"^. c #CD7A08", +"/. c #D79600", +"(. c #FFBC00", +"_. c #D79500", +":. c #FFBA00", +"<. c #CD7908", +"[. c #D79400", +"}. c #FFB800", +"|. c #CD7808", +"1. c #D79300", +"2. c #FFB700", +"3. c #CD7708", +"4. c #D79200", +"5. c #FFB300", +"6. c #CD7608", +"7. c #D79100", +"8. c #FFB600", +"9. c #F9AB03", +"0. c #C07008", +"a. c #EDB008", +"b. c #EDAD08", +"c. c #EDA908", +"d. c #EDA608", +"e. c #EDA208", +"f. c #ED9F08", +"g. c #ED9B08", +"h. c #C16807", +" . . + ", +" . @ # $ % ", +" . @ & * = - % ", +" . @ & ; > , ' - % ", +" . @ ) ! ~ { ] ^ / - % ", +" . ( _ : < [ } | 1 2 3 4 + ", +" . ( 5 6 7 8 9 0 a b c d e f g ", +" . ( 5 h i j k { l m n o p q r f s ", +" . ( t u v w < > x | y z A B C D E f s ", +". ( F G H I J ~ 9 ] K b L M N O P Q R S g ", +"g T U V W X Y [ } l 1 Z o ` ...+.@.#.$.+ ", +"% %.&.*.*.=.-.> 0 a y c ;.B >.,.,.'.).!.~. ", +" . . . . . {.{ ] m n L p ].^.. . . . . ", +" . /.x | 1 z A ` (.^.. ", +" . _.0 K b c ;.N :.<.. ", +" . [.l m Z o p ].}.|.. ", +" . 1.a y z A B C 2.|.. ", +" . 1.K n L M N O P 3.. ", +" . 4.1 Z o ` (.}.5.6.. ", +" . 7.y c ;.B :.8.9.6.. ", +" ~.0.a.b.c.d.e.f.g.h.. ", +" ~.g g g g g g g ~. "}; + +static const char * xpm_down[] = { +"22 22 138 2", +" c None", +". c #AE5300", +"+ c #C78950", +"@ c #FFFABF", +"# c #FFF9BF", +"$ c #FFF8BF", +"% c #FFF7BF", +"& c #FFF6BF", +"* c #FFF4BF", +"= c #FFF3BF", +"- c #D7A000", +"; c #FFEA00", +"> c #FFE600", +", c #FFE100", +"' c #FFDD00", +") c #FFD800", +"! c #FFD400", +"~ c #FFCF00", +"{ c #D79000", +"] c #D79F00", +"^ c #FFE800", +"/ c #FFE400", +"( c #FFDF00", +"_ c #FFDB00", +": c #FFD700", +"< c #FFD200", +"[ c #FFCE00", +"} c #D78F00", +"| c #FFE700", +"1 c #FFE200", +"2 c #FFDE00", +"3 c #FFD900", +"4 c #FFD500", +"5 c #FFD000", +"6 c #FFCC00", +"7 c #D78E00", +"8 c #D79E00", +"9 c #FFE500", +"0 c #FFDC00", +"a c #FFD300", +"b c #FFCA00", +"c c #D78D00", +"d c #D79D00", +"e c #FFE300", +"f c #FFDA00", +"g c #FFD600", +"h c #FFCD00", +"i c #FFC900", +"j c #D78C00", +"k c #D79C00", +"l c #FFCB00", +"m c #FFC700", +"n c #D78B00", +"o c #D79B00", +"p c #FFE000", +"q c #FFC500", +"r c #D78A00", +"s c #D79A00", +"t c #FFD100", +"u c #FFC800", +"v c #FFC300", +"w c #BB6F2A", +"x c #C27E40", +"y c #E1AD10", +"z c #FFC600", +"A c #FFC200", +"B c #E19A10", +"C c #B86920", +"D c #D9AF6C", +"E c #F8E843", +"F c #FFF140", +"G c #FFEE40", +"H c #FFEA40", +"I c #FFE110", +"J c #FFC000", +"K c #FFC010", +"L c #FFC940", +"M c #FFC640", +"N c #FFC240", +"O c #FCBB41", +"P c #EAC7A3", +"Q c #B25B01", +"R c #E1B707", +"S c #FBE302", +"T c #FFBE00", +"U c #FFBA00", +"V c #FFB500", +"W c #FFB100", +"X c #FCA902", +"Y c #EA9207", +"Z c #BA5F02", +"` c #E2B506", +" . c #FCDF02", +".. c #FFC100", +"+. c #FFBD00", +"@. c #FFB800", +"#. c #FFB400", +"$. c #FCAC02", +"%. c #EA9407", +"&. c #B25A01", +"*. c #E2B106", +"=. c #FCD902", +"-. c #FFC400", +";. c #FFBF00", +">. c #FFBB00", +",. c #FFB700", +"'. c #FCAE02", +"). c #EA9707", +"!. c #BA6002", +"~. c #EABA07", +"{. c #FCD302", +"]. c #FFB900", +"^. c #FCB102", +"/. c #EA9907", +"(. c #BA6702", +"_. c #EAB607", +":. c #FCCD02", +"<. c #FFBC00", +"[. c #FCB302", +"}. c #E29206", +"|. c #BA6102", +"1. c #BA6602", +"2. c #EAB107", +"3. c #FECA01", +"4. c #FBB502", +"5. c #E29306", +"6. c #B25801", +"7. c #BA6502", +"8. c #ECB006", +"9. c #FEC401", +"0. c #F8B403", +"a. c #E19407", +"b. c #BA6402", +"c. c #ECAB06", +"d. c #F5B305", +"e. c #E19507", +"f. c #C26E03", +"g. c #DD9206", +" . . . . . . . . . ", +" . + @ # $ % & * = + . ", +" . - ; > , ' ) ! ~ { . ", +" . ] ^ / ( _ : < [ } . ", +" . ] | 1 2 3 4 5 6 7 . ", +" . 8 9 , 0 ) a ~ b c . ", +" . d e ( f g < h i j . ", +" . k 1 ' 3 ! 5 l m n . ", +" . o p _ : a [ b q r . ", +" . . . . . s 2 f 4 t 6 u v r . . . . . ", +". w x x x x y ' ) ! ~ l z A B x x x x C . ", +". D E F G H I _ g < h i q J K L M N O P . ", +". Q R S > 1 2 3 4 5 6 m v T U V W X Y Z . ", +" . Q ` .p 0 : a [ b z ..+.@.#.$.%.Z . ", +" . &.*.=.f g t h u -.;.>.,.'.).!.. ", +" . &.~.{.! 5 l m A T ].^./.!.. ", +" . (._.:.[ i q ..<.[.}.|.. ", +" . 1.2.3.u v ;.4.5.6.. ", +" . 7.8.9.A 0.a.6.. ", +" . b.c.d.e.6.. ", +" . f.g.6.. ", +" . . . "}; + +static const char * xpm_binary[] = { +"32 32 246 2", +" c None", +". c #6E6E6E", +"+ c #8E8F8F", +"@ c #898A8B", +"# c #88898B", +"$ c #88898A", +"% c #87888A", +"& c #86878A", +"* c #868789", +"= c #878889", +"- c #878789", +"; c #868788", +"> c #858688", +", c #858687", +"' c #848687", +") c #848587", +"! c #858586", +"~ c #6A6A6A", +"{ c #706F6F", +"] c #F6FAFF", +"^ c #E7EFFF", +"/ c #F0F5FF", +"( c #E9F0FE", +"_ c #E8F0FE", +": c #E3ECFD", +"< c #E4EDFD", +"[ c #DFEAFB", +"} c #E8F0FD", +"| c #E6EFFC", +"1 c #E2ECFB", +"2 c #E1EBFB", +"3 c #D5E3F8", +"4 c #D3E1F8", +"5 c #D1E1F7", +"6 c #D0DFF6", +"7 c #CEDFF6", +"8 c #CDDEF5", +"9 c #CBDDF5", +"0 c #CADCF5", +"a c #C9DBF4", +"b c #C7DAF3", +"c c #C6D9F3", +"d c #C4D8F2", +"e c #C2D7F2", +"f c #C1D6F2", +"g c #E7EEF6", +"h c #696968", +"i c #6F6F6F", +"j c #F3F7FF", +"k c #A0BDF9", +"l c #E1EAFC", +"m c #C8D9F9", +"n c #BBD1F6", +"o c #D7E4FA", +"p c #B6CDF4", +"q c #D0DFF8", +"r c #AEC7F1", +"s c #CBDBF6", +"t c #BAD0F3", +"u c #A7C3EF", +"v c #9ABBEC", +"w c #4E87DC", +"x c #4F86DC", +"y c #4983D9", +"z c #437FD6", +"A c #3D7CD5", +"B c #3878D2", +"C c #3374D1", +"D c #2E72D0", +"E c #296ECE", +"F c #236ACC", +"G c #1C67C9", +"H c #1762C6", +"I c #105EC4", +"J c #0A5AC5", +"K c #E3EAF4", +"L c #F4F8FF", +"M c #9DBCF8", +"N c #C2D4F9", +"O c #ACC6F5", +"P c #A3C0F3", +"Q c #A4C0F1", +"R c #9FBDF0", +"S c #97B9EE", +"T c #99B9ED", +"U c #8FB3EB", +"V c #7EA7E7", +"W c #709EE3", +"X c #578DDE", +"Y c #548BDD", +"Z c #4E87DA", +"` c #4983D7", +" . c #4380D6", +".. c #3E7CD3", +"+. c #3978D2", +"@. c #3476D1", +"#. c #2D72CF", +"$. c #296ECD", +"%. c #236BCB", +"&. c #1E67C9", +"*. c #1763C6", +"=. c #1160C7", +"-. c #E4EBF5", +";. c #6F6F6E", +">. c #FEFFFF", +",. c #E7EFFE", +"'. c #E2EAFC", +"). c #E1EBFC", +"!. c #DEE9FA", +"~. c #DDE8FA", +"{. c #DBE6F9", +"]. c #DEE9FC", +"^. c #DAE6FA", +"/. c #D8E4F8", +"(. c #D8E5F7", +"_. c #D6E3F7", +":. c #D6E2F5", +"<. c #D3E0F3", +"[. c #D1DFF2", +"}. c #D0DEF1", +"|. c #CDDBF0", +"1. c #CCDBEF", +"2. c #CBDAEE", +"3. c #C8D8ED", +"4. c #C7D7ED", +"5. c #C7D8ED", +"6. c #C4D4EB", +"7. c #C0D1E9", +"8. c #C1D3EC", +"9. c #F4F6F8", +"0. c #686868", +"a. c #FFFFFF", +"b. c #FEFEFE", +"c. c #EDECE9", +"d. c #F5F5F3", +"e. c #FEFDFB", +"f. c #FFFEFC", +"g. c #FFFFFC", +"h. c #FFFFFB", +"i. c #FFFEFB", +"j. c #FFFDFA", +"k. c #FFFDF9", +"l. c #FEFCF8", +"m. c #FFFCF8", +"n. c #FCFAF6", +"o. c #EBE8E5", +"p. c #FBF8F4", +"q. c #FCF9F5", +"r. c #FEFAF6", +"s. c #F9F9F8", +"t. c #E1E1E1", +"u. c #BDBDBD", +"v. c #C1C1C1", +"w. c #FAFAFA", +"x. c #F6F6F6", +"y. c #B4B4B4", +"z. c #F2F2F2", +"A. c #FCFCFC", +"B. c #F9F9F9", +"C. c #F7F7F7", +"D. c #F8F8F8", +"E. c #CFCFCF", +"F. c #B6B6B6", +"G. c #D2D2D2", +"H. c #F5F5F5", +"I. c #CACACA", +"J. c #E2E2E2", +"K. c #BEBEBE", +"L. c #EFEFEF", +"M. c #FBFBFB", +"N. c #ECECEC", +"O. c #BCBCBC", +"P. c #D3D3D3", +"Q. c #C2C2C2", +"R. c #F4F4F4", +"S. c #B1B1B1", +"T. c #DEDEDE", +"U. c #BABABA", +"V. c #E3E3E3", +"W. c #F1F1F1", +"X. c #EEEEEE", +"Y. c #FDFDFD", +"Z. c #F0F0F0", +"`. c #F3F3F3", +" + c #EDEDED", +".+ c #E7E7E7", +"++ c #E6E6E6", +"@+ c #C0C0C0", +"#+ c #D8D8D8", +"$+ c #DADADA", +"%+ c #D1D1D1", +"&+ c #E0E0E0", +"*+ c #DFDFDF", +"=+ c #C6C6C6", +"-+ c #A6A6A6", +";+ c #E8E8E8", +">+ c #B5B5B5", +",+ c #EAEAEA", +"'+ c #D4D4D4", +")+ c #DCDCDC", +"!+ c #D5D5D5", +"~+ c #B2B2B2", +"{+ c #CDCDCD", +"]+ c #C3C3C3", +"^+ c #DDDDDD", +"/+ c #D0D0D0", +"(+ c #EBEBEB", +"_+ c #B3B3B3", +":+ c #A7A7A7", +"<+ c #A4A4A4", +"[+ c #D9D9D9", +"}+ c #C7C7C7", +"|+ c #BFBFBF", +"1+ c #DBDBDB", +"2+ c #979797", +"3+ c #909090", +"4+ c #6D6D6D", +"5+ c #ACACAC", +"6+ c #939393", +"7+ c #A9A9A9", +"8+ c #949494", +"9+ c #E4E4E4", +"0+ c #929292", +"a+ c #8E8E8E", +"b+ c #8D8D8D", +"c+ c #8F8F8F", +"d+ c #8C8C8C", +"e+ c #676767", +"f+ c #A2A2A2", +"g+ c #D6D6D6", +"h+ c #9C9C9C", +"i+ c #BBBBBB", +"j+ c #C5C5C5", +"k+ c #717171", +"l+ c #E9E9E9", +"m+ c #CBCBCB", +"n+ c #AFAFAF", +"o+ c #ABABAB", +"p+ c #CECECE", +"q+ c #707070", +"r+ c #B9B9B9", +"s+ c #B0B0B0", +"t+ c #E5E5E5", +"u+ c #6C6C6C", +"v+ c #959595", +"w+ c #8A8A8A", +" . + @ # # # $ $ % % & * * * = - * * ; ; ; > > , , ' ) > ! ~ ", +" { ] ^ / ( _ _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h ", +" i j k l m n o p q r s t u v w x y z A B C D E F G H I J K h ", +" i L M N O P P Q R S T U V W X Y Z ` ...+.@.#.$.%.&.*.=.-.h ", +" ;.>.,.'.).2 !.~.{.].^./.(._.(.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0. ", +" . a.a.a.a.a.a.a.b.c.d.a.a.a.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.0. ", +" . a.a.a.a.a.a.a.t.u.v.w.a.x.y.z.A.B.B.C.C.x.D.E.F.G.H.z.D.0. ", +" . a.a.a.a.a.a.a.I.J.K.L.a.M.y.N.A.B.D.C.C.x.D.O.P.Q.R.L.D.0. ", +" . a.a.a.a.a.a.a.R.u.G.a.b.H.S.T.b.D.D.D.x.x.C.J.U.V.W.X.D.0. ", +" . a.a.a.Y.b.a.a.a.a.a.Y.A.A.R.B.w.D.B.Z.B.x.R.x.`.`. +Z.B.0. ", +" . a.a.a.U..+a.a.a.b.b.Y.b.++@+#+w.w.$+u.%+R.C.&+U.Z. +W.B.0. ", +" . a.a.a.O.*+a.a.b.Y.Y.A.a.=+P.@+H.w.v.#+-+Z.C.;+>+,+X.W.B.0. ", +" . a.a.a.Q.'+a.b.b.Y.A.A.b.V.O.P.B.B.)+O.!+R.x.V.~+J.Z.z.B.0. ", +" . a.a.a.B.M.a.b.Y.Y.A.M.w.Y.C.B.D.x.B.`.C.R.z.L.L.L.L.`.B.0. ", +" . a.a.H.Q.{+A.b.Y.A.M.M.M.R.]+W.D.D.++Q.`.`.Z.Z.W.W.Z.R.B.0. ", +" . a.a.^+/+v.(+a.Y.M.M.M.w.C.~+N.D.D.;+_+z.z.W.W.W.W.W.H.B.0. ", +" . a.a.`.Q.I.w.Y.A.A.M.B.w.`.:+$+w.D.V.<+[+x.z.z.`.z.z.x.B.0. ", +" . a.B.Y.C.w.b.Y.Y.b.w.B.B.x.X.Z.H.`.z.,+Z.`.z.R.x.z.z.x.B.0. ", +" . a.R.`.x.D.D.w.z.}+`.D.D.L.|+X.R.H.^+_+1+H.C.&+U.R.H.D.B.0. ", +" . a.x.H.R.R.R.H.Z.>+ +x.x.L.2+;+D.C.~+{+3+Z.w.t.<+H.x.B.B.0. ", +" 4+a.x.H.H.H.H.x.Z.5+/+D.C.W.6+'+M.D.=+7+F.`.B.&+8+9+D.B.B.0. ", +" 4+a.C.x.M.D.x.x.H.z.L.x.C.z.)+(+D.C.R.$+C.D.C.`.N.R.B.A.w.0. ", +" 4+a.C.D.@+9+B.C.Z.Q.W.C.x.C.M.D.x.x.D.M.0+a+a+a+b+b+b+c+d+e+ ", +" 4+a.w.A.f+g+Y.w.z.f+X.w.D.D.D.D.D.D.D.B.c+(+D.x.H.H.M.H.i ", +" 4+a.w.M.h+i+Y.w.Z.0+j+A.D.D.D.D.D.D.D.B.c+L.A.A.b.a.M.k+ ", +" 4+a.w.B.++l+w.w.x.J.l+w.B.w.b.M.B.B.B.w.c+,+H.H.M.B.k+ ", +" 4+a.A.D.m+[+A.A.R.K.g+Y.M.B.g+L.A.w.w.M.c+++L.R.`.k+ ", +" 4+a.a.!+i+n+.+a.|+{+o+(+a.p+7+i+w.M.w.M.a+V.L. +q+ ", +" 4+a.a.*+~+n+X.a.I.r+o+W.a.r+@+s+C.A.M.A.a+9+.+q+ ", +" 4+a.a.a.)+.+a.a.Y.E.t+a.a.x.@+t+a.a.a.a.3+&+i ", +" u+v+6+0+8+6+0+0+6+8+8+0+0+6+v+6+0+0+0+6+w+. ", +" "}; +static const char * xpm_display[] = { +"32 32 488 2", +" c None", +". c #868686", +"+ c #9E9E9E", +"@ c #9D9D9D", +"# c #9C9C9C", +"$ c #9B9B9B", +"% c #9A9A9A", +"& c #666666", +"* c #949494", +"= c #FDFDFD", +"- c #FFFFFF", +"; c #F1F1F1", +"> c #717171", +", c #EAEAEA", +"' c #FFFFFD", +") c #FFFFFC", +"! c #FFFFFA", +"~ c #FFFEFA", +"{ c #FFFEF9", +"] c #FFFDF9", +"^ c #FFFCF9", +"/ c #FFFCF8", +"( c #FEFEFE", +"_ c #C8C8C8", +": c #F5F5F5", +"< c #D7D8DB", +"[ c #7087AE", +"} c #7D98BE", +"| c #8AA7CA", +"1 c #8CA9CB", +"2 c #8FACCD", +"3 c #92B0D0", +"4 c #95B3D2", +"5 c #98B6D4", +"6 c #9BB9D6", +"7 c #9EBCD7", +"8 c #A0BED8", +"9 c #A0BFD8", +"0 c #9BB9D4", +"a c #98B6D3", +"b c #95B3D1", +"c c #92AFCF", +"d c #8EACCD", +"e c #8BA8CA", +"f c #87A5C9", +"g c #85A2C7", +"h c #758FB7", +"i c #899CC0", +"j c #F8F9FA", +"k c #D3D3D3", +"l c #F4F4F4", +"m c #C6C9D0", +"n c #083FA5", +"o c #2A6ECA", +"p c #3B80D5", +"q c #4287D9", +"r c #488EDD", +"s c #4F95E2", +"t c #579DE6", +"u c #5EA4EB", +"v c #64ABEF", +"w c #6AB1F3", +"x c #6EB5F5", +"y c #6EB6F6", +"z c #6DB4F5", +"A c #69B1F2", +"B c #63AAEF", +"C c #5DA3EA", +"D c #559CE6", +"E c #4F94E1", +"F c #478DDC", +"G c #4084D7", +"H c #397ED3", +"I c #3478D0", +"J c #1A5DBF", +"K c #2C5CB7", +"L c #F3F5F8", +"M c #D2D2D2", +"N c #F6F6F6", +"O c #C8CCD3", +"P c #225DB7", +"Q c #397BD1", +"R c #4081D3", +"S c #4788D8", +"T c #4D8FDB", +"U c #5395DF", +"V c #599BE3", +"W c #5EA2E7", +"X c #64A7EA", +"Y c #68ABED", +"Z c #6AAEEF", +"` c #6BAFEF", +" . c #6AAEEE", +".. c #63A7EA", +"+. c #5FA1E6", +"@. c #5294DF", +"#. c #4B8DDB", +"$. c #4586D6", +"%. c #3F80D2", +"&. c #3879CE", +"*. c #2C6EC8", +"=. c #3F73C5", +"-. c #F0F2F6", +";. c #FFFEFD", +">. c #CDD0D7", +",. c #2B66BC", +"'. c #3576CE", +"). c #3D7DD1", +"!. c #4384D5", +"~. c #498AD8", +"{. c #4E90DC", +"]. c #5395E0", +"^. c #5D9FE5", +"/. c #60A3E8", +"(. c #62A5E9", +"_. c #62A4E9", +":. c #60A3E7", +"<. c #5C9FE6", +"[. c #589AE2", +"}. c #4E8FDC", +"|. c #4182D3", +"1. c #3B7CD0", +"2. c #3575CC", +"3. c #296BC7", +"4. c #467AC9", +"5. c #EAEBEF", +"6. c #F1F0EF", +"7. c #CECECE", +"8. c #F8F8F8", +"9. c #CED1D8", +"0. c #2560B9", +"a. c #3072CB", +"b. c #3F7FD2", +"c. c #488AD8", +"d. c #4D8FDC", +"e. c #5294DE", +"f. c #5597E0", +"g. c #589BE2", +"h. c #5A9CE3", +"i. c #599CE3", +"j. c #5597E1", +"k. c #5193DE", +"l. c #4D8EDB", +"m. c #4889D8", +"n. c #4283D4", +"o. c #3C7CD1", +"p. c #3777CD", +"q. c #3271C9", +"r. c #2667C4", +"s. c #4276C6", +"t. c #E1E3E7", +"u. c #E4E3E1", +"v. c #CACACA", +"w. c #F9F9F9", +"x. c #CED2D9", +"y. c #1550AF", +"z. c #2C6CC7", +"A. c #3474CB", +"B. c #3979CE", +"C. c #3D7ED1", +"D. c #4282D4", +"E. c #4788D7", +"F. c #4B8CDA", +"G. c #5092DD", +"H. c #4A8BD9", +"I. c #4687D7", +"J. c #4182D4", +"K. c #3C7DD1", +"L. c #3272CA", +"M. c #2E6DC7", +"N. c #1F5FBF", +"O. c #3467BE", +"P. c #E1E3E6", +"Q. c #E3E2E1", +"R. c #CCCCCC", +"S. c #FBFBFB", +"T. c #D2D6DC", +"U. c #0740A5", +"V. c #1656B9", +"W. c #2F6FC8", +"X. c #3373CB", +"Y. c #3F80D3", +"Z. c #4889D7", +"`. c #4587D6", +" + c #4283D5", +".+ c #3B7BD0", +"++ c #3676CD", +"@+ c #3171C9", +"#+ c #2968C3", +"$+ c #0949B1", +"%+ c #2C5EB7", +"&+ c #E1E0DF", +"*+ c #FCFCFC", +"=+ c #D4D7DE", +"-+ c #0841A5", +";+ c #003BA8", +">+ c #1654B7", +",+ c #2B6BC5", +"'+ c #3171CA", +")+ c #3878CE", +"!+ c #3E7FD1", +"~+ c #3A7BD0", +"{+ c #3878CD", +"]+ c #3070C9", +"^+ c #2C6BC6", +"/+ c #2362C0", +"(+ c #0F4DB2", +"_+ c #0037A6", +":+ c #2D60B9", +"<+ c #E0E2E5", +"[+ c #DFDEDC", +"}+ c #D6D9E0", +"|+ c #0942A6", +"1+ c #003CA9", +"2+ c #0341AB", +"3+ c #0F4DB4", +"4+ c #1E5DBD", +"5+ c #2A69C5", +"6+ c #3374CB", +"7+ c #3676CC", +"8+ c #3778CD", +"9+ c #3576CC", +"0+ c #2C6CC6", +"a+ c #2463C0", +"b+ c #1552B7", +"c+ c #0642AD", +"d+ c #003CA8", +"e+ c #0038A6", +"f+ c #DFE1E4", +"g+ c #DCDBDA", +"h+ c #D7DBE2", +"i+ c #0B44A9", +"j+ c #0443AE", +"k+ c #0C4AB1", +"l+ c #0F4DB3", +"m+ c #1250B5", +"n+ c #1857B9", +"o+ c #205FBE", +"p+ c #2766C2", +"q+ c #2A6AC5", +"r+ c #2E6EC7", +"s+ c #2E6EC8", +"t+ c #2D6DC7", +"u+ c #2767C3", +"v+ c #2161BF", +"w+ c #1A59BA", +"x+ c #114FB4", +"y+ c #0A48B0", +"z+ c #0744AD", +"A+ c #0441AB", +"B+ c #0038A7", +"C+ c #DEDFE2", +"D+ c #D9D8D7", +"E+ c #D9DDE4", +"F+ c #114BAD", +"G+ c #0B4AB2", +"H+ c #1452B6", +"I+ c #1B5ABB", +"J+ c #1F5EBD", +"K+ c #2261C0", +"L+ c #2464C1", +"M+ c #2767C2", +"N+ c #2968C4", +"O+ c #2969C4", +"P+ c #2665C1", +"Q+ c #2262C0", +"R+ c #1756B8", +"S+ c #1351B5", +"T+ c #0A47B0", +"U+ c #003BA9", +"V+ c #DBDDE0", +"W+ c #D6D5D4", +"X+ c #DCE0E6", +"Y+ c #1852B2", +"Z+ c #1250B6", +"`+ c #1B59BB", +" @ c #205EBD", +".@ c #2766C3", +"+@ c #2B6AC6", +"@@ c #2D6EC7", +"#@ c #3070C8", +"$@ c #3272C9", +"%@ c #2867C3", +"&@ c #1A58BA", +"*@ c #1653B7", +"=@ c #114EB4", +"-@ c #0242AE", +";@ c #3063BB", +">@ c #DADCDF", +",@ c #D4D3D2", +"'@ c #DDE1E8", +")@ c #1E58B6", +"!@ c #1857BA", +"~@ c #2160BF", +"{@ c #2665C2", +"]@ c #2F6EC8", +"^@ c #3372CA", +"/@ c #3A7BCF", +"(@ c #3B7BCF", +"_@ c #3677CD", +":@ c #2B6BC6", +"<@ c #215FBE", +"[@ c #1C5ABB", +"}@ c #1654B8", +"|@ c #0848B2", +"1@ c #3567BF", +"2@ c #D9DBDE", +"3@ c #D1D1CF", +"4@ c #DEE2E8", +"5@ c #235DB9", +"6@ c #1D5EBF", +"7@ c #3E7FD2", +"8@ c #4284D4", +"9@ c #4484D5", +"0@ c #0E4EB5", +"a@ c #396CC1", +"b@ c #D8D9DC", +"c@ c #CFCECD", +"d@ c #CDCDCD", +"e@ c #DEE1E7", +"f@ c #2763BC", +"g@ c #2364C2", +"h@ c #3372CB", +"i@ c #4B8DDA", +"j@ c #4C8EDB", +"k@ c #4C8EDA", +"l@ c #498BD9", +"m@ c #3D7ED2", +"n@ c #3373CA", +"o@ c #1353B8", +"p@ c #3C70C3", +"q@ c #D6D8DB", +"r@ c #CDCCCA", +"s@ c #DBDFE5", +"t@ c #1F5EBC", +"u@ c #1C60C2", +"v@ c #266AC7", +"w@ c #2D71CB", +"x@ c #3377CF", +"y@ c #397DD3", +"z@ c #3E83D7", +"A@ c #4389DA", +"B@ c #478DDD", +"C@ c #4A90DE", +"D@ c #4C92DF", +"E@ c #4489DB", +"F@ c #3F85D7", +"G@ c #3A7FD4", +"H@ c #3379D0", +"I@ c #2D71CC", +"J@ c #2063C3", +"K@ c #195CBF", +"L@ c #0A4FB7", +"M@ c #356CC3", +"N@ c #D5D7DA", +"O@ c #CAC9C8", +"P@ c #E9ECEF", +"Q@ c #88AADC", +"R@ c #86ABDF", +"S@ c #8CB1E2", +"T@ c #90B5E4", +"U@ c #93B8E6", +"V@ c #96BBE8", +"W@ c #99BFEA", +"X@ c #9DC2EB", +"Y@ c #9FC4EE", +"Z@ c #A0C6EE", +"`@ c #A1C6EF", +" # c #A0C5EE", +".# c #9EC4ED", +"+# c #9CC2EC", +"@# c #92B7E5", +"## c #8EB3E3", +"$# c #8AAFE0", +"%# c #87ABDD", +"&# c #83A7DC", +"*# c #7BA0D7", +"=# c #92AFDD", +"-# c #D6D7D9", +";# c #C6C6C5", +"># c #CBCBCB", +",# c #FDFDFC", +"'# c #F4F6F8", +")# c #F6F7F8", +"!# c #F4F3F3", +"~# c #F1F2F2", +"{# c #F0F0F0", +"]# c #EFEEEF", +"^# c #EDEDEC", +"/# c #EBEBEB", +"(# c #E9EAEA", +"_# c #E8E8E8", +":# c #E6E6E6", +"<# c #E3E3E3", +"[# c #E2E2E2", +"}# c #E1E1E1", +"|# c #DFDFDF", +"1# c #DCDCDC", +"2# c #DBDBDB", +"3# c #D9D9D9", +"4# c #D7D8D7", +"5# c #D5D6D6", +"6# c #D4D3D3", +"7# c #D0D0D1", +"8# c #CFCFCF", +"9# c #C4C4C4", +"0# c #FBFAFA", +"a# c #F9F7F7", +"b# c #F6F6F4", +"c# c #F4F4F3", +"d# c #ECEBEA", +"e# c #E9E9E8", +"f# c #E8E7E7", +"g# c #E6E5E5", +"h# c #E4E2E3", +"i# c #E2E1E0", +"j# c #E0DFDD", +"k# c #DEDDDC", +"l# c #DBDBDA", +"m# c #D8D9D8", +"n# c #D6D6D5", +"o# c #D4D4D3", +"p# c #D2D2D1", +"q# c #D0CFCF", +"r# c #CECCCC", +"s# c #CBCAC9", +"t# c #A5A5A5", +"u# c #ACACAC", +"v# c #C9C9C9", +"w# c #C7C7C7", +"x# c #D5D5D5", +"y# c #D1D1D1", +"z# c #C1C1C1", +"A# c #B4B4B4", +"B# c #B9B9B9", +"C# c #BBBBBB", +"D# c #BABABA", +"E# c #B8B8B8", +"F# c #BCBCBC", +"G# c #595959", +"H# c #D0D0D0", +"I# c #C3C3C3", +"J# c #C2C2C2", +"K# c #BFBFBF", +"L# c #BEBEBE", +"M# c #878787", +"N# c #3A3A3A", +"O# c #8B8B8B", +"P# c #C6C6C6", +"Q# c #E7E7E7", +"R# c #F3F3F3", +"S# c #5E5E5E", +"T# c #FAFAFA", +"U# c #F2F2F2", +"V# c #DADADA", +"W# c #A8A8A8", +"X# c #787878", +"Y# c #ECECEC", +"Z# c #DDDDDD", +"`# c #E5E5E5", +" $ c #E4E4E4", +".$ c #DEDEDE", +"+$ c #4C4C4C", +"@$ c #F7F7F7", +"#$ c #EDEDED", +"$$ c #D8D8D8", +"%$ c #D7D7D7", +"&$ c #393939", +"*$ c #808080", +"=$ c #EFEFEF", +"-$ c #EEEEEE", +";$ c #D6D6D6", +">$ c #686868", +",$ c #414141", +"'$ c #898989", +")$ c #D4D4D4", +"!$ c #B5B5B5", +"~$ c #757575", +"{$ c #2D2D2D", +"]$ c #454545", +"^$ c #848484", +"/$ c #A4A4A4", +"($ c #A6A6A6", +"_$ c #A3A3A3", +":$ c #979797", +"<$ c #7E7E7E", +"[$ c #606060", +"}$ c #3C3C3C", +" . + @ @ @ @ @ @ @ @ @ # # # # # # # # # $ $ $ % % % $ & ", +" * = - - - - - - - - - - - - - - - - - - - - - - - - - - ; > ", +" , - - ' ) ! ! ! ~ { ] ] ^ / / / ] ] ] ] { { { { { ! ) ( - _ ", +" : - < [ } | 1 2 3 4 5 6 7 8 9 8 7 0 a b c d e f g h i j - k ", +" l - m n o p q r s t u v w x y z A B C D E F G H I J K L - M ", +" N - O P Q R S T U V W X Y Z ` .Y ..+.V @.#.$.%.&.*.=.-.;.M ", +" N - >.,.'.).!.~.{.].V ^./.(.(._.:.<.[.U }.S |.1.2.3.4.5.6.7. ", +" 8.- 9.0.a.&.b.!.c.d.e.f.g.h.h.i.[.j.k.l.m.n.o.p.q.r.s.t.u.v. ", +" w.- x.y.z.A.B.C.D.E.F.d.G.k.k.k.G.T H.I.J.K.p.L.M.N.O.P.Q.R. ", +" S.- T.U.V.W.X.p.1.Y.!.$.S ~.~.~.Z.`. +%..+++@+M.#+$+%+P.&+R. ", +" *+- =+-+;+>+,+'+2.)+1.!+%.R R R %.C.~+{+A.]+^+/+(+_+:+<+[+R. ", +" *+- }+|+1+2+3+4+5+]+6+7+8+)+)+{+p.9+X.]+0+a+b+c+d+e+:+f+g+R. ", +" = - h+i+j+k+l+m+n+o+p+q+M.r+s+s+t+,+u+v+w+x+y+z+A+B+:+C+D+R. ", +" ( - E+F+G+H+n+I+J+K+L+M+N+O+O+N+u+P+Q+J+I+R+S+l+T+U+:+V+W+R. ", +" - - X+Y+Z+`+ @/+.@+@@@#@@+$@$@@+#@M.,+%@a+J+&@*@=@-@;@>@,@R. ", +" - - '@)@!@~@{@q+]@^@7+B./@(@(@/@B._@X.W.:@{@<@[@}@|@1@2@3@R. ", +" - - 4@5@6@u+t+@+++/@7@R 8@9@9@8@J.7@.+p.'+0+.@v+[@0@a@b@c@d@ ", +" - - e@f@g@z.h@{+).n.I.c.i@j@k@F.l@I.n.m@&.n@0+.@~@o@p@q@r@R. ", +" - - s@t@u@v@w@x@y@z@A@B@C@D@D@C@r E@F@G@H@I@v@J@K@L@M@N@O@R. ", +" - - P@Q@R@S@T@U@V@W@X@Y@Z@`@`@ #.#+#W@V@@###$#%#&#*#=#-#;#># ", +" - ,#'#)#N !#~#{#]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#M 7#8#_ 9#R. ", +" 7.- ( ,#0#a#b#c#6.d#e#f#g#h#i#j#k#l#m#n#W+W+o#p#q#r#s#_ 2#t# ", +" u#M d@R.>#v#9#w#x#k M y#8#7.d@R.>#v.v.z#A#B#C#D#B#E#F#* ", +" G#w#H#>#v#w#9#I#J#K#L#L#M#N# ", +" O#P#/#H#:#/#_#_#_#Q#Q#_#/#x#:#R#A#S# ", +" y#- - - ; 2#/#: w.w.T#8.U#V#k w.- - - W# ", +" X#- = S.w.N Y#Z#|#`#:# $1#7.v#R..$*+S.- - +$ ", +" S#@$@$U#U#; #$, <#1#2#$$%$2#|#Q#; U#U#T#Y#&$ ", +" *$[#=$=$Y#, , , , , , , /#Y#Y##$=$-$;$>$ ", +" ,$'$C#%$[#<#<# $ $ $ $<#<#[#)$!$~${$ ", +" ]$& ^$% /$($($_$:$<$[$}$ ", +" "}; +static const char * xpm_edit[] = { +"32 32 281 2", +" c None", +". c #C4D0E5", +"+ c #9DAAC1", +"@ c #FBFFFF", +"# c #FFFFFF", +"$ c #FEFFFF", +"% c #F5FAFF", +"& c #EDF3FE", +"* c #E4EBF9", +"= c #D8E1F2", +"- c #C2D0E9", +"; c #A7B2C4", +"> c #FCFFFF", +", c #F8FDFF", +"' c #F2F7FF", +") c #EAF1FD", +"! c #E1E9F7", +"~ c #D5DFF0", +"{ c #DBAC55", +"] c #F2C584", +"^ c #E6AE84", +"/ c #DD9A6F", +"( c #EDF4FE", +"_ c #E6EDFA", +": c #DBD6D4", +"< c #F5BC00", +"[ c #FEE43E", +"} c #FEE8C3", +"| c #FEECD3", +"1 c #EEC5A3", +"2 c #F8FCFF", +"3 c #F1F7FF", +"4 c #E9EFFC", +"5 c #E6B76B", +"6 c #FEE600", +"7 c #FECA00", +"8 c #FEB610", +"9 c #FEC451", +"0 c #FECB93", +"a c #C15B1D", +"b c #FAFEFF", +"c c #F3F9FF", +"d c #EBEAED", +"e c #F5C40F", +"f c #FEB600", +"g c #FEAF00", +"h c #FE9610", +"i c #F98219", +"j c #AF725E", +"k c #F5F9FF", +"l c #EDC07F", +"m c #FDDE00", +"n c #FED201", +"o c #FEB001", +"p c #FEAC01", +"q c #FE871C", +"r c #E1701E", +"s c #CED1E2", +"t c #9EABC1", +"u c #F7FBFF", +"v c #F5C120", +"w c #FEBB07", +"x c #FEB306", +"y c #FE9C0E", +"z c #AF684C", +"A c #98A9C5", +"B c #FDFFFF", +"C c #F3CF9F", +"D c #FDE005", +"E c #FEDB06", +"F c #FEB70D", +"G c #FEB30C", +"H c #FE8C1C", +"I c #E06510", +"J c #B5B1C1", +"K c #B4C3DC", +"L c #AEBEDB", +"M c #8495B1", +"N c #F5B824", +"O c #FEE80D", +"P c #FEC613", +"Q c #FEB913", +"R c #FEA918", +"S c #FE8E23", +"T c #C7805B", +"U c #BBC9E0", +"V c #B9C6DF", +"W c #B5C5E0", +"X c #FBE1BF", +"Y c #FCDC15", +"Z c #FEE117", +"` c #FEBE1C", +" . c #FEBD19", +".. c #FE9929", +"+. c #E9781D", +"@. c #BFA9AC", +"#. c #C2CFE5", +"$. c #C1CDE4", +"%. c #BDCBE5", +"&. c #F8C449", +"*. c #FEEB22", +"=. c #FED123", +"-. c #FEC023", +";. c #FEB128", +">. c #FE9A34", +",. c #CD7947", +"'. c #C9D4E9", +"). c #C7D2E7", +"!. c #C6D2E6", +"~. c #C3D0E8", +"{. c #FDEACF", +"]. c #F9D121", +"^. c #FEE72C", +"/. c #FEC42E", +"(. c #FEC32A", +"_. c #FEA938", +":. c #F59031", +"<. c #C5A5A3", +"[. c #CED9EC", +"}. c #CCD7EA", +"|. c #CBD7EA", +"1. c #C8D5EC", +"2. c #F8CE6C", +"3. c #FEED39", +"4. c #FED837", +"5. c #FEC835", +"6. c #FEBE37", +"7. c #FEA645", +"8. c #D06F31", +"9. c #D2DCEF", +"0. c #D0DBED", +"a. c #CEDAF0", +"b. c #FEF1DF", +"c. c #F9C828", +"d. c #FEEC44", +"e. c #FECE3F", +"f. c #FECA3C", +"g. c #FEB649", +"h. c #F9A247", +"i. c #C9A098", +"j. c #D9E2F3", +"k. c #D7E1F2", +"l. c #D4DEF0", +"m. c #D4DDEF", +"n. c #D2DEF2", +"o. c #F3CD87", +"p. c #FEF054", +"q. c #FEE04D", +"r. c #FECE48", +"s. c #FECA47", +"t. c #FEB258", +"u. c #D87833", +"v. c #DEE6F5", +"w. c #DDE5F4", +"x. c #DBE4F3", +"y. c #D8E1F1", +"z. c #D5E0F4", +"A. c #F2F1EF", +"B. c #FAD148", +"C. c #FEF15F", +"D. c #FED654", +"E. c #FED150", +"F. c #FEC35B", +"G. c #F9AF58", +"H. c #CC947F", +"I. c #E1E9F8", +"J. c #DDE6F4", +"K. c #DCE5F4", +"L. c #DAE4F3", +"M. c #D9E3F6", +"N. c #F6FBFF", +"O. c #F5D193", +"P. c #FDEC66", +"Q. c #FEE766", +"R. c #FED55C", +"S. c #FED259", +"T. c #FEBF6B", +"U. c #E2914A", +"V. c #E0DFE9", +"W. c #E4EBF8", +"X. c #E2EAF8", +"Y. c #DFE7F7", +"Z. c #7C8CA8", +"`. c #F9FEFF", +" + c #F8C74E", +".+ c #FEF37A", +"++ c #FEDC69", +"@+ c #FED864", +"#+ c #FECF6B", +"$+ c #FEC573", +"%+ c #CD8968", +"&+ c #E7EEFB", +"*+ c #E5ECF9", +"=+ c #E3EBF9", +"-+ c #DBE3F1", +";+ c #D2D9E9", +">+ c #CBD2E3", +",+ c #C6CFE3", +"'+ c #7786A3", +")+ c #F9FDFF", +"!+ c #F5B651", +"~+ c #FEEE86", +"{+ c #FEDC70", +"]+ c #FEDA6E", +"^+ c #FECE7D", +"/+ c #E4964E", +"(+ c #E2D8DC", +"_+ c #E3E9F6", +":+ c #D8DEED", +"<+ c #CFD7E5", +"[+ c #CCD2E2", +"}+ c #CAD1E2", +"|+ c #CAD1E1", +"1+ c #C8D1E5", +"2+ c #EEAB59", +"3+ c #FEEBCE", +"4+ c #FEE4A4", +"5+ c #FEDD8D", +"6+ c #FBD08B", +"7+ c #CB9373", +"8+ c #D7DCEA", +"9+ c #D2D8E6", +"0+ c #CFD6E5", +"a+ c #CED5E4", +"b+ c #CDD4E4", +"c+ c #C9D0E2", +"d+ c #C9D2E5", +"e+ c #E7A259", +"f+ c #F8E7D0", +"g+ c #C0856A", +"h+ c #D0D0DA", +"i+ c #D4DAE7", +"j+ c #D0D7E5", +"k+ c #CDD4E3", +"l+ c #CCD3E3", +"m+ c #F7FDFF", +"n+ c #C6966D", +"o+ c #F5DBC0", +"p+ c #B67252", +"q+ c #D3D2DB", +"r+ c #D8DDE9", +"s+ c #D5DAE8", +"t+ c #D1D8E6", +"u+ c #CBD2E2", +"v+ c #CAD2E5", +"w+ c #936D5C", +"x+ c #978585", +"y+ c #B88571", +"z+ c #D9DFE9", +"A+ c #D8DEE9", +"B+ c #D7DCE9", +"C+ c #D5DAE7", +"D+ c #CDD3E4", +"E+ c #CCD4E7", +"F+ c #8D6050", +"G+ c #AA7A69", +"H+ c #DBE0E9", +"I+ c #D3D9E7", +"J+ c #CFD5E4", +"K+ c #D4DBEA", +"L+ c #DFE9FA", +"M+ c #F4F9FC", +"N+ c #BF968A", +"O+ c #E2E6EE", +"P+ c #DADFE9", +"Q+ c #D6DBE8", +"R+ c #D9DFEC", +"S+ c #DFE6F3", +"T+ c #E3EBF8", +"U+ c #E0E9FB", +"V+ c #F7FCFF", +"W+ c #F4F9FF", +"X+ c #F2F8FF", +"Y+ c #F0F6FF", +"Z+ c #EBF1FC", +"`+ c #E7EEFA", +" @ c #E4ECF9", +".@ c #E1E8F7", +"+@ c #E0EAFC", +"@@ c #E9F0FC", +"#@ c #F4FDFF", +". . . . . . . . . . . . . . . + ", +". @ # # # # # # # # $ % & * = - ; ", +". > # # # # # # # # , ' ) ! ~ { ] ^ / ", +". > # # # # # # # # @ % ( _ : < [ } | 1 ", +". > # # # # # # # # $ 2 3 4 5 6 7 8 9 0 a ", +". > # # # # # # # # # b c d e 6 f g h i j ", +". > # # # # # # # # # > k l m n o p q r s t ", +". > # # # # # # # # # > u v 6 w x y q z A A A ", +". > # # # # # # # # # B C D E F G H I J K L M ", +". > # # # # # # # # # # N O P Q R S T U V W M ", +". > # # # # # # # # # X Y Z ` ...+.@.#.$.%.M ", +". > # # # # # # # # # &.*.=.-.;.>.,.'.).!.~.M ", +". > # # # # # # # # {.].^./.(._.:.<.[.}.|.1.M ", +". > # # # # # # # # 2.3.4.5.6.7.8.~ 9.0.0.a.M ", +". > # # # # # # # b.c.d.e.f.g.h.i.j.k.l.m.n.M ", +". > # # # # # # B o.p.q.r.s.t.u.v.w.x.= y.z.M ", +". > # # # # # > A.B.C.D.E.F.G.H.I.v.J.K.L.M.M ", +". > # # # # # N.O.P.Q.R.S.T.U.V.W.X.Y.v.J.l.Z. ", +". > # # # # `., +.+++@+#+$+%+&+*+=+-+;+>+,+'+ ", +". > # # # # )+, !+~+{+]+^+/+(+_+:+<+[+}+|+1+'+ ", +". > # # # > `.`.2+3+4+5+6+7+8+9+0+a+b+}+c+d+'+ ", +". > # # # > `., e+| | f+g+h+i+9+j+0+k+l+>+d+'+ ", +". > # # # @ `.m+n+| o+p+q+r+s+9+t+0+a+u+l+v+'+ ", +". > # # $ b `., w+x+y+z+A+B+C+9+j+0+D+u+l+E+Z. ", +". > # # $ b `., F+G+H+z+A+r+i+I+j+0+J+K+-+L+M ", +". > # # > b , M+N+O+P+z+A+Q+i+9+R+S+T+X.! U+M ", +". > # # `.`., V+W+W+X+3 Y+Z+W.`+_ @X.X..@+@M ", +". > # # `.`., V+W+W+X+3 Y+& ) @@_ @X.X..@+@M ", +". #@# # `.`., V+W+W+X+3 Y+& ) @@_ @X.X..@+@M ", +". M M M M M M M M M M M M M M M M M M M M M M ", +" ", +" "}; +static const char * xpm_folder[] = { +"32 32 465 2", +" c None", +". c #2F69EF", +"+ c #1650E9", +"@ c #3D76F2", +"# c #5E91FD", +"$ c #104AEB", +"% c #3F7AF4", +"& c #5E93FD", +"* c #0043FF", +"= c #0541F5", +"- c #1243E3", +"; c #3776F5", +"> c #95B9FE", +", c #0047FF", +"' c #003BFF", +") c #0D3DE5", +"! c #B0B0D3", +"~ c #D6D6E9", +"{ c #C6C6E0", +"] c #AEAED1", +"^ c #2C6FF7", +"/ c #85AFFC", +"( c #0651FF", +"_ c #0046FF", +": c #0042FF", +"< c #0039FF", +"[ c #0434F3", +"} c #0D38DB", +"| c #CECEE4", +"1 c #FEFEFF", +"2 c #F9F9FC", +"3 c #E0E0EE", +"4 c #CBCBE3", +"5 c #A7AED8", +"6 c #2E74F9", +"7 c #8EB5FA", +"8 c #135FFF", +"9 c #054FFF", +"0 c #0041FF", +"a c #002DFF", +"b c #082FE3", +"c c #B8B8D8", +"d c #F0F6FF", +"e c #4687FB", +"f c #B9D3FD", +"g c #6797F2", +"h c #4E80EE", +"i c #2E68F0", +"j c #1255F7", +"k c #0040FF", +"l c #0037FF", +"m c #002BFF", +"n c #0020FB", +"o c #082BD6", +"p c #D8D8EA", +"q c #488CFD", +"r c #91BBFD", +"s c #91BCFF", +"t c #7AABFF", +"u c #6CA0FF", +"v c #5C90FB", +"w c #4C7FF3", +"x c #4172EE", +"y c #2B5AEF", +"z c #1740F5", +"A c #001CFF", +"B c #021EEB", +"C c #0524CE", +"D c #BFBFDC", +"E c #629FFF", +"F c #95BFFE", +"G c #9FC8FF", +"H c #88B6FF", +"I c #78A9FF", +"J c #6A9FFF", +"K c #6196FF", +"L c #5E92FF", +"M c #5E8EFF", +"N c #5A84FC", +"O c #5070F5", +"P c #445BEE", +"Q c #1B34F3", +"R c #031FD6", +"S c #B6B6D6", +"T c #E2E2EF", +"U c #498EFE", +"V c #C0DDFF", +"W c #97C2FF", +"X c #85B3FF", +"Y c #76A7FF", +"Z c #699CFF", +"` c #6095FF", +" . c #5E91FF", +".. c #5E8DFF", +"+. c #5E86FF", +"@. c #5E7FFF", +"#. c #4A60F1", +"$. c #0822FA", +"%. c #0018F9", +"&. c #0119CB", +"*. c #C5C5DF", +"=. c #FBFBFD", +"-. c #5495FD", +";. c #B9D8FE", +">. c #92BEFE", +",. c #82B1FE", +"'. c #73A4FE", +"). c #669AFE", +"!. c #5E92FE", +"~. c #5D90FE", +"{. c #5D8BFE", +"]. c #5E85FF", +"^. c #5A78FC", +"/. c #3249EC", +"(. c #0017FE", +"_. c #0017FF", +":. c #0017EE", +"<. c #0013C4", +"[. c #ECECF5", +"}. c #F8F8FB", +"|. c #4689FC", +"1. c #B6D6FD", +"2. c #8FBCFD", +"3. c #7FAEFD", +"4. c #6FA2FD", +"5. c #6498FD", +"6. c #5C91FD", +"7. c #5C8EFD", +"8. c #5C89FD", +"9. c #5E84FF", +"0. c #4B67F2", +"a. c #1129EF", +"b. c #0016FA", +"c. c #0014DF", +"d. c #0011C0", +"e. c #CFCFE5", +"f. c #FDFDFE", +"g. c #F6F6FA", +"h. c #E7EDFA", +"i. c #4587FB", +"j. c #B3D3FD", +"k. c #8CB8FD", +"l. c #7BABFD", +"m. c #6D9FFD", +"n. c #6196FD", +"o. c #5B90FD", +"p. c #5B8DFD", +"q. c #5A80FC", +"r. c #304FEB", +"s. c #0017E3", +"t. c #0017F1", +"u. c #0019FF", +"v. c #4157DE", +"w. c #BBBBD9", +"x. c #F3F3F9", +"y. c #E4EBF9", +"z. c #98BFFC", +"A. c #9AC4FC", +"B. c #88B6FC", +"C. c #78A8FC", +"D. c #6A9CFC", +"E. c #5F93FC", +"F. c #5A8EFC", +"G. c #5A8CFC", +"H. c #5E89FF", +"I. c #4F72F5", +"J. c #1E46F4", +"K. c #1139F9", +"L. c #0828F1", +"M. c #0017E7", +"N. c #0019EF", +"O. c #A6B8FE", +"P. c #4A5DD8", +"Q. c #F1F1F7", +"R. c #E2E8F7", +"S. c #468BFD", +"T. c #97C0FD", +"U. c #AED2FB", +"V. c #96C0FB", +"W. c #85B2FB", +"X. c #75A6FB", +"Y. c #679AFB", +"Z. c #5D91FB", +"`. c #598DFB", +" + c #5C8CFD", +".+ c #5C87FD", +"++ c #395FEE", +"@+ c #153FF8", +"#+ c #1640FF", +"$+ c #133DFF", +"%+ c #0B39FD", +"&+ c #8EA6FA", +"*+ c #FCFCFE", +"=+ c #1F34CC", +"-+ c #C2C2DD", +";+ c #F0F0F7", +">+ c #EEEEF6", +",+ c #E0E6F6", +"'+ c #478CFD", +")+ c #9BC4FD", +"!+ c #BDDEFB", +"~+ c #A6CCFB", +"{+ c #92BDFB", +"]+ c #81AFFB", +"^+ c #72A2FB", +"/+ c #6598FB", +"(+ c #5B8FFB", +"_+ c #588CFB", +":+ c #5D8DFE", +"<+ c #5078F5", +"[+ c #2551F3", +"}+ c #1541FB", +"|+ c #113FFF", +"1+ c #0B3CFF", +"2+ c #557CFE", +"3+ c #FCFCFD", +"4+ c #E8EBFA", +"5+ c #1328C8", +"6+ c #EBEBF4", +"7+ c #468CFD", +"8+ c #A1C8FE", +"9+ c #D1ECFB", +"0+ c #B5D8FA", +"a+ c #A1C9FA", +"b+ c #8FB9FA", +"c+ c #7DABFA", +"d+ c #6EA0FA", +"e+ c #6295FA", +"f+ c #588DFA", +"g+ c #5A8DFC", +"h+ c #5B8BFE", +"i+ c #3964F0", +"j+ c #1146F9", +"k+ c #0D40FE", +"l+ c #0B3DFF", +"m+ c #F9F9FD", +"n+ c #CFD0F1", +"o+ c #091CC2", +"p+ c #C8C8E1", +"q+ c #E9E9F3", +"r+ c #E8E8F3", +"s+ c #3D87FF", +"t+ c #EDF9FD", +"u+ c #D5EBFB", +"v+ c #BDD8FB", +"w+ c #A3C6FB", +"x+ c #8EB6FB", +"y+ c #7BA7FB", +"z+ c #6999FB", +"A+ c #5A8DFB", +"B+ c #4E83FB", +"C+ c #4980FE", +"D+ c #396DFA", +"E+ c #1C53F7", +"F+ c #0F46FD", +"G+ c #0C3FFF", +"H+ c #4872FE", +"I+ c #F8F8FC", +"J+ c #F8F8FD", +"K+ c #D8DBF5", +"L+ c #1528C6", +"M+ c #F7F7FB", +"N+ c #E7E7F2", +"O+ c #E6E6F1", +"P+ c #73A6F9", +"Q+ c #A1C6FD", +"R+ c #D1E7FB", +"S+ c #B8D5FB", +"T+ c #A1C3FB", +"U+ c #8CB2FB", +"V+ c #78A3FB", +"W+ c #6695FB", +"X+ c #5688FB", +"Y+ c #4B81FD", +"Z+ c #477CFF", +"`+ c #2F63F5", +" @ c #134DFA", +".@ c #1046FF", +"+@ c #2E5DFE", +"@@ c #E4E9FB", +"#@ c #F6F6FB", +"$@ c #F7F7FC", +"%@ c #E8E8F7", +"&@ c #283ACB", +"*@ c #EDEDF5", +"=@ c #E3E3F0", +"-@ c #D5DCF1", +";@ c #4586FB", +">@ c #CEE2FC", +",@ c #B3D1FB", +"'@ c #9EC0FB", +")@ c #88B0FB", +"!@ c #75A1FB", +"~@ c #6392FB", +"{@ c #5386FB", +"]@ c #4C82FE", +"^@ c #3F75FB", +"/@ c #225BF7", +"(@ c #134DFC", +"_@ c #3163FE", +":@ c #E3E7FB", +"<@ c #F5F5FB", +"[@ c #F3F3FB", +"}@ c #394BD0", +"|@ c #C3C3DE", +"1@ c #C0C0DC", +"2@ c #D7D7E9", +"3@ c #7DA9F7", +"4@ c #82ACFA", +"5@ c #B5D1FA", +"6@ c #99BDFA", +"7@ c #84ACFA", +"8@ c #729EFA", +"9@ c #6090FA", +"0@ c #5286FB", +"a@ c #4C82FF", +"b@ c #366AF6", +"c@ c #1954F9", +"d@ c #1D57FE", +"e@ c #E1E6FA", +"f@ c #F2F2F9", +"g@ c #F2F2FA", +"h@ c #F3F3FA", +"i@ c #3F52D3", +"j@ c #3572E7", +"k@ c #B3BFE6", +"l@ c #C3C5E2", +"m@ c #D2D2E7", +"n@ c #417CF5", +"o@ c #B9D2FB", +"p@ c #98BDFB", +"q@ c #81AAFA", +"r@ c #6D9BFA", +"s@ c #5D8EFA", +"t@ c #5387FD", +"u@ c #457AFB", +"v@ c #2862F7", +"w@ c #225DFB", +"x@ c #BFCFF9", +"y@ c #F0F0F9", +"z@ c #F1F1F9", +"A@ c #7884E0", +"B@ c #2470FA", +"C@ c #CADBF8", +"D@ c #D0DBF3", +"E@ c #BCCBED", +"F@ c #B5C3E9", +"G@ c #B5BEE3", +"H@ c #C8CAE3", +"I@ c #A0B3E9", +"J@ c #4A7FF3", +"K@ c #B1CFFF", +"L@ c #86B0FF", +"M@ c #709FFD", +"N@ c #5F90FD", +"O@ c #5388FF", +"P@ c #3C72F7", +"Q@ c #2864F9", +"R@ c #BFCEF8", +"S@ c #EDEDF7", +"T@ c #EDEDF8", +"U@ c #EEEEF8", +"V@ c #818DE3", +"W@ c #2776FF", +"X@ c #A2C6FE", +"Y@ c #F0F7FF", +"Z@ c #E2EEFF", +"`@ c #D5E7FF", +" # c #C0D7F9", +".# c #AEC8F4", +"+# c #9CBBF0", +"@# c #9AB5E9", +"## c #4A7BEB", +"$# c #80A4F5", +"%# c #81A9F9", +"&# c #6B9AFB", +"*# c #6092FF", +"=# c #4E83FC", +"-# c #2E68F7", +";# c #A2BBF7", +"># c #E9E9F7", +",# c #EBEBF7", +"'# c #ECECF7", +")# c #959FE7", +"!# c #327FFE", +"~# c #86B3FD", +"{# c #E1EDFE", +"]# c #C9E0FF", +"^# c #BCD8FF", +"/# c #AFD1FF", +"(# c #9FC5FB", +"_# c #85B0F6", +":# c #275EEB", +"<# c #90B0F7", +"[# c #5387F8", +"}# c #497DF6", +"|# c #4377F6", +"1# c #99B5F6", +"2# c #E7E7F5", +"3# c #E8E8F6", +"4# c #B9BFEF", +"5# c #081CC3", +"6# c #2D70F7", +"7# c #7AA6F9", +"8# c #CADEFE", +"9# c #A2CAFF", +"0# c #96C2FF", +"a# c #72A4FA", +"b# c #2F5EE7", +"c# c #76A2FB", +"d# c #3875FB", +"e# c #8DACF7", +"f# c #E3E3F4", +"g# c #E4E4F4", +"h# c #E4E4F5", +"i# c #E6E6F5", +"j# c #BEC4F1", +"k# c #081CC4", +"l# c #2763EF", +"m# c #6D99F5", +"n# c #B3D1FD", +"o# c #89BBFF", +"p# c #5286F3", +"q# c #345FE5", +"r# c #8CB0FB", +"s# c #E1E1F3", +"t# c #E2E2F3", +"u# c #E2E4F7", +"v# c #081DC4", +"w# c #2156E8", +"x# c #618CF1", +"y# c #9CC3FD", +"z# c #7FB3FF", +"A# c #3567EB", +"B# c #5675E5", +"C# c #DEDEF2", +"D# c #E0E0F2", +"E# c #E3E6F8", +"F# c #1E34CC", +"G# c #1B49E1", +"H# c #5580EE", +"I# c #87B5FC", +"J# c #73ACFF", +"K# c #2958E5", +"L# c #7D93E9", +"M# c #DEDEF1", +"N# c #E4E7F9", +"O# c #1F35CD", +"P# c #163CDA", +"Q# c #4973E9", +"R# c #73A8FC", +"S# c #6CA7FF", +"T# c #143AD9", +"U# c #8C9CE9", +"V# c #3C52D6", +"W# c #0012C0", +"X# c #1130D2", +"Y# c #4067E5", +"Z# c #6095F8", +"`# c #1032D4", +" $ c #2F48D5", +".$ c #0014C2", +"+$ c #0C25CA", +"@$ c #0D2CD0", +"#$ c #0117C5", +" . + ", +" @ # $ ", +" % & * = - ", +" ; > , * ' ) ", +" ! ~ { ] ^ / ( _ : < [ } ", +" | 1 1 2 3 4 5 6 7 8 9 _ 0 < a b ", +" c 2 1 1 1 1 d e f g h i j k l m n o ", +" p 1 1 1 1 d q r s t u v w x y z A B C ", +" D 2 1 1 1 1 E F G H I J K L M N O P Q R ", +" S T 1 1 1 1 1 U V W X Y Z ` ...+.@.#.$.%.&. ", +" *.1 =.=.=.=.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<. ", +" c [.=.}.}.}.}.}.|.1.2.3.4.5.6.7.8.9.0.a.b._._.c.d. ", +" e.f.g.g.g.g.g.h.i.j.k.l.m.n.o.p.8.q.r.s.t._._.u.v.d. ", +" w.g.g.x.x.x.x.y.i.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.f.P. ", +" p =.Q.Q.Q.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+&+*+f.f.=+ ", +" -+=.;+>+>+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+=.3+3+3+4+5+", +" T g.6+6+6+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+2+m+m+=.=.=.n+o+", +" p+f.q+r+r+r+r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+I+J+J+m+K+L+ ", +"-+6+M+N+O+O+O+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@M+$@$@%@&@ ", +"{ ;+1 1 g.*@O+=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@<@<@#@[@}@d. ", +" |@1@2@6+=.1 2 ;+3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@g@h@g@i@d. ", +" j@k@l@m@T g.1 n@o@p@q@r@s@t@u@v@w@x@y@y@z@z@z@A@d. ", +" B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@T@U@f@V@d. ", +" W@X@Y@Z@`@ #.#+#@###$#%#&#*#=#-#;#>#,#,#'#U@)#d. ", +" !#~#{#Z@`@]#^#/#(#_#:#<#[#}#|#1#2#2#3#3#'#4#5# ", +" 6#7#8#]#^#/#9#0#a#b#c#d#e#f#g#h#i#>#j#k# ", +" l#m#n#/#9#0#o#p#q#r#s#s#t#t#g#u#v# ", +" w#x#y#0#o#z#A#B#t#C#D#t#E#F# ", +" G#H#I#z#J#K#L#M#C#N#O# ", +" P#Q#R#S#T#U#z@V#W# ", +" X#Y#Z#`# $.$ ", +" +$@$#$ "}; + +static const char * xpm_images[] = { +"32 32 557 2", +" c None", +". c #C4D0E5", +"+ c #9DAAC1", +"@ c #FBFFFF", +"# c #FFFFFF", +"$ c #FEFFFF", +"% c #F5FAFF", +"& c #EDF3FE", +"* c #E4EBF9", +"= c #D8E1F2", +"- c #C2D0E9", +"; c #ACB7CA", +"> c #FCFFFF", +", c #F8FDFF", +"' c #F2F7FF", +") c #EAF1FD", +"! c #E1E9F7", +"~ c #D5DFF0", +"{ c #BFCCE3", +"] c #EBF4FF", +"^ c #A6B2C6", +"/ c #EDF4FE", +"( c #E6EDFA", +"_ c #D9E2F2", +": c #C2CEE5", +"< c #F0F6FF", +"[ c #DCE7F9", +"} c #A6B2C8", +"| c #F8FCFF", +"1 c #F1F7FF", +"2 c #E9EFFC", +"3 c #DCE5F4", +"4 c #C4D0E6", +"5 c #E8EEFB", +"6 c #DBE5F9", +"7 c #A7B3C9", +"8 c #FAFEFF", +"9 c #F3F9FF", +"0 c #EBF1FD", +"a c #DFE7F6", +"b c #C6D1E5", +"c c #FDFFFF", +"d c #ECF2FD", +"e c #DEE9FB", +"f c #A9B5CA", +"g c #C3C4CD", +"h c #F3EADD", +"i c #EFD9C2", +"j c #E4C09A", +"k c #E4C29E", +"l c #E5C6A4", +"m c #F0DECC", +"n c #F5EADF", +"o c #F7EFE7", +"p c #FBF7F3", +"q c #F5F9FF", +"r c #E3EBF9", +"s c #BECBE1", +"t c #F3F5FB", +"u c #ECF2F9", +"v c #E4EBF7", +"w c #D8E1F0", +"x c #D0DCF1", +"y c #A1AEC5", +"z c #BF6300", +"A c #C1721B", +"B c #C26F14", +"C c #BD6F19", +"D c #B76B1A", +"E c #BD701D", +"F c #C0731F", +"G c #BB6E18", +"H c #B6660F", +"I c #BC7529", +"J c #D1A273", +"K c #EDDBC9", +"L c #F6F3ED", +"M c #F7FBFF", +"N c #E8EFFC", +"O c #C8D4E7", +"P c #98A9C5", +"Q c #C16601", +"R c #C6751D", +"S c #CF8C41", +"T c #D9AB7A", +"U c #CAB8A7", +"V c #B6B8C3", +"W c #B2B7CB", +"X c #C4C2CD", +"Y c #EEE6DE", +"Z c #F2E0C8", +"` c #E1C19B", +" . c #CB9355", +".. c #BC772E", +"+. c #AE600C", +"@. c #C38D57", +"#. c #E4D4C3", +"$. c #EFF3FA", +"%. c #EBF1FE", +"&. c #E5EDFA", +"*. c #D7E0F1", +"=. c #C1CEE4", +"-. c #B6C4DD", +";. c #B4C3DC", +">. c #AEBEDB", +",. c #8495B1", +"'. c #C16400", +"). c #C77416", +"!. c #D69C59", +"~. c #EFD9BB", +"{. c #E2F2FF", +"]. c #81AFEB", +"^. c #97BFF1", +"/. c #BDD8FA", +"(. c #8CABE2", +"_. c #A3B2DE", +":. c #F3F6FD", +"<. c #ECEBDB", +"[. c #D2AC7A", +"}. c #B8732C", +"|. c #A25200", +"1. c #CFB191", +"2. c #E9EDF4", +"3. c #CCD6EA", +"4. c #BECAE2", +"5. c #BBC9E0", +"6. c #B9C6DF", +"7. c #B5C5E0", +"8. c #C26400", +"9. c #CF8A37", +"0. c #ECD1A7", +"a. c #FFFFFC", +"b. c #FCFAEB", +"c. c #AFC8E2", +"d. c #57A0EE", +"e. c #8DCDFF", +"f. c #80C4FF", +"g. c #70C4FF", +"h. c #4877C8", +"i. c #C0BBD1", +"j. c #EFF3E2", +"k. c #CCDDC3", +"l. c #B7D3B6", +"m. c #C5E6D6", +"n. c #D5CDAE", +"o. c #C28A4B", +"p. c #9E5103", +"q. c #C5A280", +"r. c #E6ECF8", +"s. c #D5DFEF", +"t. c #C7D3E8", +"u. c #C5D1E6", +"v. c #C2CFE5", +"w. c #C1CDE4", +"x. c #BDCBE5", +"y. c #D18C3A", +"z. c #EED3A5", +"A. c #F3E2C1", +"B. c #F1DBB3", +"C. c #FBF1D0", +"D. c #F9F7DF", +"E. c #8EB2D8", +"F. c #137DF3", +"G. c #2296FF", +"H. c #178EFF", +"I. c #0089FF", +"J. c #0A5BCC", +"K. c #BCB5C4", +"L. c #A5C889", +"M. c #80BE7F", +"N. c #ABD9AD", +"O. c #9ACE9C", +"P. c #8CC38E", +"Q. c #EAEBD3", +"R. c #C38D51", +"S. c #9A4F01", +"T. c #C1A996", +"U. c #D0DAED", +"V. c #CCD7EA", +"W. c #C9D4E9", +"X. c #C7D2E7", +"Y. c #C6D2E6", +"Z. c #C3D0E8", +"`. c #CB7F25", +" + c #E0B373", +".+ c #D08E40", +"++ c #BE6807", +"@+ c #C17117", +"#+ c #D49C55", +"$+ c #F6E3AC", +"%+ c #C2C9CD", +"&+ c #0F58CD", +"*+ c #007AFC", +"=+ c #0C8DFF", +"-+ c #0061E8", +";+ c #4C67B4", +">+ c #C7B6A1", +",+ c #75C765", +"'+ c #6CDC70", +")+ c #7DE47D", +"!+ c #75E574", +"~+ c #34B638", +"{+ c #B6CC94", +"]+ c #FFEAC5", +"^+ c #B57329", +"/+ c #954E07", +"(+ c #CBCCD2", +"_+ c #D0DBED", +":+ c #CED9EC", +"<+ c #CBD7EA", +"[+ c #C8D5EC", +"}+ c #C06500", +"|+ c #C16907", +"1+ c #EBCA8C", +"2+ c #BE6809", +"3+ c #D49648", +"4+ c #F4EFCA", +"5+ c #9A9EAE", +"6+ c #4F7CC4", +"7+ c #467DCC", +"8+ c #4D61A6", +"9+ c #C7B0A7", +"0+ c #F5D9A6", +"a+ c #4DBC3D", +"b+ c #15CB18", +"c+ c #17CD17", +"d+ c #06CC05", +"e+ c #009F00", +"f+ c #9DB66A", +"g+ c #FEE3B4", +"h+ c #EABE7D", +"i+ c #974E03", +"j+ c #AD8763", +"k+ c #D2DCEF", +"l+ c #CEDAF0", +"m+ c #BF6401", +"n+ c #CF8C34", +"o+ c #FFF6BF", +"p+ c #C77C22", +"q+ c #B15C04", +"r+ c #DBA75B", +"s+ c #FFF7B9", +"t+ c #FFE7A6", +"u+ c #D9BB94", +"v+ c #BA9987", +"w+ c #E4C294", +"x+ c #FFE7A3", +"y+ c #FEDEA1", +"z+ c #609B38", +"A+ c #00A502", +"B+ c #07CC10", +"C+ c #00C009", +"D+ c #118A0C", +"E+ c #CBBF75", +"F+ c #FDD493", +"G+ c #FFDF9B", +"H+ c #B06714", +"I+ c #93500E", +"J+ c #D8E0F0", +"K+ c #D7E1F2", +"L+ c #D4DEF0", +"M+ c #D4DDEF", +"N+ c #D2DEF2", +"O+ c #BD6402", +"P+ c #E6BC6F", +"Q+ c #FFF4B0", +"R+ c #F2D48A", +"S+ c #D9A14C", +"T+ c #CD8A33", +"U+ c #CF903A", +"V+ c #E1B160", +"W+ c #FBDA8F", +"X+ c #FFE197", +"Y+ c #FFDF92", +"Z+ c #FFE391", +"`+ c #FFE58F", +" @ c #FFDE8B", +".@ c #FFD687", +"+@ c #FFD98B", +"@@ c #D7BC6E", +"#@ c #87A946", +"$@ c #5AAC38", +"%@ c #64A938", +"&@ c #A9AD4E", +"*@ c #FED078", +"=@ c #FFCE78", +"-@ c #FFCD7C", +";@ c #D28B30", +">@ c #8B4500", +",@ c #CFCBCC", +"'@ c #DBE4F3", +")@ c #D8E1F1", +"!@ c #D5E0F4", +"~@ c #BA6202", +"{@ c #E4B763", +"]@ c #FFF4A4", +"^@ c #FFED9C", +"/@ c #FFEC9C", +"(@ c #FAD983", +"_@ c #FEDC86", +":@ c #FFE791", +"<@ c #FFDB83", +"[@ c #FFD67C", +"}@ c #FFD47A", +"|@ c #FFD277", +"1@ c #FFD074", +"2@ c #FFCE70", +"3@ c #FFCB6D", +"4@ c #FFC869", +"5@ c #FFCC6D", +"6@ c #FFC367", +"7@ c #DDB654", +"8@ c #E89F49", +"9@ c #F99056", +"0@ c #EA8752", +"a@ c #F29E4A", +"b@ c #FFBF58", +"c@ c #E49832", +"d@ c #894300", +"e@ c #C7BBB4", +"f@ c #DDE6F4", +"g@ c #DAE4F3", +"h@ c #D9E3F6", +"i@ c #B76001", +"j@ c #C37A1D", +"k@ c #F3D27A", +"l@ c #FFF197", +"m@ c #FFE68A", +"n@ c #FFDF82", +"o@ c #FFDA7B", +"p@ c #FFD473", +"q@ c #FFD16E", +"r@ c #FFCF69", +"s@ c #FFCB64", +"t@ c #FFC860", +"u@ c #FFC55B", +"v@ c #FFC356", +"w@ c #FFC052", +"x@ c #FFBD4E", +"y@ c #FFBA4A", +"z@ c #FFBD49", +"A@ c #FE9D39", +"B@ c #F6916A", +"C@ c #F3A19A", +"D@ c #EFA6A2", +"E@ c #EB9C88", +"F@ c #F59B3D", +"G@ c #E58F1E", +"H@ c #864300", +"I@ c #CBC0BA", +"J@ c #DFE7F7", +"K@ c #DEE6F5", +"L@ c #DBE5F7", +"M@ c #B15B00", +"N@ c #C0771B", +"O@ c #D1953A", +"P@ c #E7B559", +"Q@ c #FFD979", +"R@ c #FFDC79", +"S@ c #FFCF6A", +"T@ c #FFCC64", +"U@ c #FFC95F", +"V@ c #FFC559", +"W@ c #FFC253", +"X@ c #FFBF4E", +"Y@ c #FFBD48", +"Z@ c #FFB942", +"`@ c #FFB53E", +" # c #FFB238", +".# c #FFB832", +"+# c #EE6924", +"@# c #F77471", +"## c #FF9498", +"$# c #FF9698", +"%# c #F96971", +"&# c #D7471C", +"*# c #E1820A", +"=# c #844100", +"-# c #C9BDB6", +";# c #E2EAF8", +"># c #E0E7F6", +",# c #DCE6F8", +"'# c #AB5600", +")# c #B4670F", +"!# c #C47E25", +"~# c #E5AC4C", +"{# c #FFD76D", +"]# c #FFCA60", +"^# c #FFBF4D", +"/# c #FFBC48", +"(# c #FFB842", +"_# c #FFB43C", +":# c #FFB036", +"<# c #FFAD30", +"[# c #FFB72B", +"}# c #E9541C", +"|# c #FB2725", +"1# c #FE2526", +"2# c #F91B1B", +"3# c #FF0D0D", +"4# c #C41803", +"5# c #C86C01", +"6# c #823F00", +"7# c #D7D6D9", +"8# c #E2E9F7", +"9# c #E0E8F7", +"0# c #E0E8F6", +"a# c #DEE8FA", +"b# c #A35100", +"c# c #AC5F0A", +"d# c #CF8C2D", +"e# c #FFC959", +"f# c #FFC252", +"g# c #FFBD4B", +"h# c #FFBA45", +"i# c #FFB740", +"j# c #FFB43A", +"k# c #FFB034", +"l# c #FFAC2F", +"m# c #FFA929", +"n# c #FFB125", +"o# c #E05F11", +"p# c #E50C0B", +"q# c #FF0E14", +"r# c #FF1014", +"s# c #E4000A", +"t# c #D14301", +"u# c #A45600", +"v# c #8C531C", +"w# c #E3EBF7", +"x# c #DFE9FA", +"y# c #A25403", +"z# c #D58F2C", +"A# c #FFC650", +"B# c #FFB844", +"C# c #FFB63E", +"D# c #FFB339", +"E# c #FFB033", +"F# c #FFAB2D", +"G# c #FFA828", +"H# c #FFA522", +"I# c #FFA31C", +"J# c #F89A15", +"K# c #D84A08", +"L# c #D22814", +"M# c #D02518", +"N# c #C02D06", +"O# c #E77A01", +"P# c #874400", +"Q# c #A47B55", +"R# c #E3EBF8", +"S# c #E1E9F8", +"T# c #AA5F0A", +"U# c #E69F32", +"V# c #FFBC41", +"W# c #FFB237", +"X# c #FFAE32", +"Y# c #FFAA2C", +"Z# c #FFA726", +"`# c #FFA421", +" $ c #FFA11B", +".$ c #FF9D15", +"+$ c #FF9D0F", +"@$ c #F88E07", +"#$ c #F48105", +"$$ c #F38005", +"%$ c #F68A02", +"&$ c #B96400", +"*$ c #D2C9C6", +"=$ c #E4ECF9", +"-$ c #E0E9FB", +";$ c #954A00", +">$ c #BA6E13", +",$ c #FEB036", +"'$ c #FFAF31", +")$ c #FFAA2B", +"!$ c #FFA625", +"~$ c #FFA31F", +"{$ c #FFA01A", +"]$ c #FF9D14", +"^$ c #FF990E", +"/$ c #FF9607", +"($ c #FF9404", +"_$ c #FF9402", +":$ c #FF9802", +"<$ c #EA8501", +"[$ c #8C4600", +"}$ c #A0744C", +"|$ c #E6ECF7", +"1$ c #E3EAF9", +"2$ c #9A5309", +"3$ c #D1821A", +"4$ c #FFB22C", +"5$ c #FFA723", +"6$ c #FFA21D", +"7$ c #FF9F17", +"8$ c #FF9C12", +"9$ c #FF980C", +"0$ c #FF9506", +"a$ c #FF9202", +"b$ c #FF9602", +"c$ c #ED8701", +"d$ c #934B00", +"e$ c #884C12", +"f$ c #DCD9DA", +"g$ c #E7EEFA", +"h$ c #E3EAF8", +"i$ c #AD9480", +"j$ c #974F03", +"k$ c #C67610", +"l$ c #FDA01A", +"m$ c #FFA316", +"n$ c #FF9D10", +"o$ c #FF990A", +"p$ c #FF9505", +"q$ c #FF9302", +"r$ c #FF9502", +"s$ c #FF9601", +"t$ c #D77901", +"u$ c #904900", +"v$ c #803F00", +"w$ c #C9B9AD", +"x$ c #E8EFFA", +"y$ c #C2CADB", +"z$ c #C6A583", +"A$ c #8D4803", +"B$ c #924B02", +"C$ c #B06005", +"D$ c #CA7205", +"E$ c #DE7E02", +"F$ c #E78301", +"G$ c #E38001", +"H$ c #CB7000", +"I$ c #994F00", +"J$ c #854100", +"K$ c #8E551E", +"L$ c #D9D2CF", +"M$ c #E9EFFA", +"N$ c #E9F0FC", +"O$ c #E1E8F7", +"P$ c #E0EAFC", +"Q$ c #FBFDFC", +"R$ c #F0E6DD", +"S$ c #C3A07E", +"T$ c #A2703E", +"U$ c #8A490B", +"V$ c #834000", +"W$ c #834100", +"X$ c #945F2C", +"Y$ c #C9B5A3", +"Z$ c #EBEDF3", +"`$ c #EDF2FD", +" % c #F4FDFF", +".% c #F9FEFF", +"+% c #F7FCFF", +"@% c #F4F9FF", +"#% c #F2F8FF", +" ", +" . . . . . . . . . . . . . . . + ", +" . @ # # # # # # # # $ % & * = - ; ", +" . > # # # # # # # # , ' ) ! ~ { ] ^ ", +" . > # # # # # # # # @ % / ( _ : < [ } ", +" . > # # # # # # # # $ | 1 2 3 4 # 5 6 7 ", +" . > # # # # # # # # # 8 9 0 a b # c d e f ", +" g h i j k l m n o p # > q & r s t u v w x y ", +" z A B C D E F G H I J K L M < N O P P P P P P P ", +" Q R S T U V W X Y Z ` ...+.@.#.$.%.&.! *.=.-.;.>.,.", +" '.).!.~.# {.].^./.(._.:.# # <.[.}.|.1.2.&.a 3.4.5.6.7.,.", +" 8.9.0.# a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.,.", +" '.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.,.", +" Q `. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+V.<+[+,.", +"}+|+1+2+ 3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+~ k+_+_+l+,.", +"m+n+o+p+ q+r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+,.", +"O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@= )@!@,.", +"~@{@]@^@/@(@_@:@<@[@}@|@1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@3 g@h@,.", +"i@j@k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@z@A@B@C@D@E@F@G@H@I@J@K@f@L@,.", +" M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@###$#%#&#*#=#-#;#>#a ,#,.", +" '#)#!#~#{#]#V@W@^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#8#9#0#a#,.", +" b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#r 9#J@x#,.", +" y#z#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#( R#;#S#x#,.", +" T#U#V#W#X#Y#Z#`# $.$+$@$#$$$%$&$6#*$( =$! ;#-$,.", +" ;$>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$( 1$! ;#-$,.", +" 2$3$4$5$6$7$8$9$0$a$a$b$c$d$e$f$g$( h$;#;#x#,.", +" i$j$k$l$m$n$o$p$q$r$s$t$u$v$w$x$g$( R#;#! -$,.", +" y$z$A$B$C$D$E$F$G$H$I$J$K$L$M$N$( =$;#;#O$P$,.", +" . Q$R$S$T$U$V$W$V$V$X$Y$Z$`$) N$( =$;#;#O$P$,.", +" . %# # .%.%, +%@%@%#%1 < & ) N$( =$;#;#O$P$,.", +" . ,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.", +" "}; + +#endif diff --git a/src/ksquirrelpart/sq_imagebcg.ui b/src/ksquirrelpart/sq_imagebcg.ui new file mode 100644 index 0000000..c3466d5 --- /dev/null +++ b/src/ksquirrelpart/sq_imagebcg.ui @@ -0,0 +1,989 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>SQ_ImageBCG</class> +<widget class="TQDialog"> + <property name="name"> + <cstring>SQ_ImageBCG</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>564</width> + <height>391</height> + </rect> + </property> + <property name="caption"> + <string>Color balance</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQWidgetStack" row="1" column="0" rowspan="3" colspan="1"> + <property name="name"> + <cstring>widgetStackParams</cstring> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>4</number> + </property> + <widget class="TQSpinBox" row="2" column="0"> + <property name="name"> + <cstring>spinB</cstring> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="minValue"> + <number>-255</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="2"> + <property name="name"> + <cstring>pushResetG</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton" row="0" column="1"> + <property name="name"> + <cstring>pushResetC</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="KDoubleSpinBox" row="2" column="2"> + <property name="name"> + <cstring>spinG</cstring> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="1"> + <property name="name"> + <cstring>spinC</cstring> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="minValue"> + <number>-255</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="0"> + <property name="name"> + <cstring>pushResetB</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_Label"> + <property name="name"> + <cstring>sQ_LabelB</cstring> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderB</cstring> + </property> + <property name="minValue"> + <number>-255</number> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="tickmarks"> + <enum>Above</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Brightness</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_Label"> + <property name="name"> + <cstring>sQ_LabelC</cstring> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderC</cstring> + </property> + <property name="minValue"> + <number>-255</number> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="tickmarks"> + <enum>Above</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Contrast</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="2"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_Label"> + <property name="name"> + <cstring>sQ_LabelG</cstring> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderG</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="maxValue"> + <number>600</number> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="tickmarks"> + <enum>Above</enum> + </property> + <property name="tickInterval"> + <number>22</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Gamma</string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>4</number> + </property> + <widget class="TQPushButton" row="0" column="0"> + <property name="name"> + <cstring>pushResetRed</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="0"> + <property name="name"> + <cstring>spinRed</cstring> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="minValue"> + <number>-255</number> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="1"> + <property name="name"> + <cstring>spinGreen</cstring> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="minValue"> + <number>-255</number> + </property> + </widget> + <widget class="TQPushButton" row="0" column="1"> + <property name="name"> + <cstring>pushResetGreen</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton" row="0" column="2"> + <property name="name"> + <cstring>pushResetBlue</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="2"> + <property name="name"> + <cstring>spinBlue</cstring> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="minValue"> + <number>-255</number> + </property> + </widget> + <widget class="TQLayoutWidget" row="1" column="2"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_Label"> + <property name="name"> + <cstring>sQ_LabelBlue</cstring> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderBlue</cstring> + </property> + <property name="minValue"> + <number>-255</number> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="tickmarks"> + <enum>Above</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Blue</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_Label"> + <property name="name"> + <cstring>sQ_LabelGreen</cstring> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderGreen</cstring> + </property> + <property name="minValue"> + <number>-255</number> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="tickmarks"> + <enum>Above</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Green</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_Label"> + <property name="name"> + <cstring>sQ_LabelRed</cstring> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderRed</cstring> + </property> + <property name="minValue"> + <number>-255</number> + </property> + <property name="maxValue"> + <number>255</number> + </property> + <property name="tickmarks"> + <enum>Above</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Red</string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + </widget> + <widget class="TQGroupBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>6</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQPushButton" row="0" column="4"> + <property name="name"> + <cstring>push2</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton" row="0" column="0"> + <property name="name"> + <cstring>push1</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer26</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <spacer row="0" column="3"> + <property name="name"> + <cstring>spacer27</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="2"> + <property name="name"> + <cstring>text</cstring> + </property> + <property name="alignment"> + <set>WordBreak|AlignCenter</set> + </property> + </widget> + </grid> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer12_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="5" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>249</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushGO</cstring> + </property> + <property name="text"> + <string>Colorize</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushCancel</cstring> + </property> + <property name="text"> + <string>Close</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="Line" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="2" column="1"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Original image:</string> + </property> + </widget> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer35</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="SQ_BCGLabel" row="1" column="3"> + <property name="name"> + <cstring>pixmap1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>160</height> + </size> + </property> + </widget> + <widget class="TQLabel" row="0" column="3" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Image after colorizing:</string> + </property> + </widget> + <spacer row="1" column="4"> + <property name="name"> + <cstring>spacer34</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="SQ_BCGLabel" row="1" column="1"> + <property name="name"> + <cstring>pixmap</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>160</height> + </size> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>SQ_BCGLabel</class> + <header location="local">sq_bcglabel.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>SQ_Label</class> + <header location="local">sq_label.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<connections> + <connection> + <sender>spinRed</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotRedChanged(int)</slot> + </connection> + <connection> + <sender>spinGreen</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotGreenChanged(int)</slot> + </connection> + <connection> + <sender>spinG</sender> + <signal>valueChanged(double)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotGSpinChanged(double)</slot> + </connection> + <connection> + <sender>spinC</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotCChanged(int)</slot> + </connection> + <connection> + <sender>spinBlue</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotBlueChanged(int)</slot> + </connection> + <connection> + <sender>spinB</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotBChanged(int)</slot> + </connection> + <connection> + <sender>sliderRed</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotRedChanged(int)</slot> + </connection> + <connection> + <sender>sliderGreen</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotGreenChanged(int)</slot> + </connection> + <connection> + <sender>sliderG</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotGChanged(int)</slot> + </connection> + <connection> + <sender>sliderC</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotCChanged(int)</slot> + </connection> + <connection> + <sender>sliderBlue</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotBlueChanged(int)</slot> + </connection> + <connection> + <sender>sliderB</sender> + <signal>valueChanged(int)</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotBChanged(int)</slot> + </connection> + <connection> + <sender>pushResetRed</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotResetRed()</slot> + </connection> + <connection> + <sender>pushResetGreen</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotResetGreen()</slot> + </connection> + <connection> + <sender>pushResetG</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotResetG()</slot> + </connection> + <connection> + <sender>pushResetC</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotResetC()</slot> + </connection> + <connection> + <sender>pushResetBlue</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotResetBlue()</slot> + </connection> + <connection> + <sender>pushResetB</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotResetB()</slot> + </connection> + <connection> + <sender>pushGO</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotStartBCG()</slot> + </connection> + <connection> + <sender>push2</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotPush()</slot> + </connection> + <connection> + <sender>push1</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>slotPush()</slot> + </connection> + <connection> + <sender>pushCancel</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageBCG</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>push1</tabstop> + <tabstop>push2</tabstop> + <tabstop>pushResetRed</tabstop> + <tabstop>pushResetGreen</tabstop> + <tabstop>pushResetBlue</tabstop> + <tabstop>sliderRed</tabstop> + <tabstop>sliderGreen</tabstop> + <tabstop>sliderBlue</tabstop> + <tabstop>spinRed</tabstop> + <tabstop>spinGreen</tabstop> + <tabstop>spinBlue</tabstop> + <tabstop>pushGO</tabstop> + <tabstop>pushCancel</tabstop> + <tabstop>pushResetB</tabstop> + <tabstop>pushResetC</tabstop> + <tabstop>pushResetG</tabstop> + <tabstop>sliderB</tabstop> + <tabstop>sliderC</tabstop> + <tabstop>sliderG</tabstop> + <tabstop>spinB</tabstop> + <tabstop>spinC</tabstop> + <tabstop>spinG</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in declaration">sq_imageedit.h</include> + <include location="global" impldecl="in declaration">tqimage.h</include> + <include location="global" impldecl="in declaration">tqstringlist.h</include> + <include location="local" impldecl="in implementation">fmt_filters.h</include> + <include location="global" impldecl="in implementation">knuminput.h</include> + <include location="global" impldecl="in implementation">ksquirrel-libs/fmt_defs.h</include> + <include location="global" impldecl="in implementation">ksquirrel-libs/fmt_types.h</include> + <include location="global" impldecl="in implementation">kstandarddirs.h</include> + <include location="global" impldecl="in implementation">sq_bcglabel.h</include> + <include location="local" impldecl="in implementation">sq_config.h</include> + <include location="local" impldecl="in implementation">sq_iconloader.h</include> + <include location="local" impldecl="in implementation">sq_imagebcg.ui.h</include> + <include location="global" impldecl="in implementation">sq_label.h</include> +</includes> +<variables> + <variable access="private">int id;</variable> + <variable access="private">TQImage sample, sample_saved;</variable> + <variable access="private">TQStringList strings;</variable> + <variable access="private">static SQ_ImageBCG *m_inst;</variable> +</variables> +<signals> + <signal>bcg(SQ_ImageBCGOptions*)</signal> +</signals> +<slots> + <slot access="private" specifier="non virtual">slotResetG()</slot> + <slot access="private" specifier="non virtual">slotResetC()</slot> + <slot access="private" specifier="non virtual">slotResetB()</slot> + <slot access="private" specifier="non virtual">slotResetRed()</slot> + <slot access="private" specifier="non virtual">slotResetGreen()</slot> + <slot access="private" specifier="non virtual">slotResetBlue()</slot> + <slot access="private" specifier="non virtual">slotStartBCG()</slot> + <slot access="private" specifier="non virtual">slotBChanged( int v )</slot> + <slot access="private" specifier="non virtual">slotCChanged( int v )</slot> + <slot access="private" specifier="non virtual">slotRedChanged( int v )</slot> + <slot access="private" specifier="non virtual">slotGreenChanged( int v )</slot> + <slot access="private" specifier="non virtual">slotBlueChanged( int v )</slot> + <slot access="private" specifier="non virtual">slotGChanged( int v )</slot> + <slot access="private" specifier="non virtual">slotGSpinChanged( double v )</slot> + <slot access="private" specifier="non virtual">slotPush()</slot> +</slots> +<functions> + <function access="private" specifier="non virtual">init()</function> + <function access="private" specifier="non virtual" returnType="int">RGB2Y( int r, int g, int b )</function> + <function access="private" specifier="non virtual">assignNewImage( const TQImage & im )</function> + <function access="private" specifier="non virtual">changeImage( int b, int c, int g1, int red, int green, int blue )</function> + <function specifier="non virtual">setPreviewImage( const TQImage & im )</function> + <function specifier="static" returnType="SQ_ImageBCG *">instance()</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/ksquirrelpart/sq_imagebcg.ui.h b/src/ksquirrelpart/sq_imagebcg.ui.h new file mode 100644 index 0000000..31c3516 --- /dev/null +++ b/src/ksquirrelpart/sq_imagebcg.ui.h @@ -0,0 +1,241 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** TQt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +SQ_ImageBCG * SQ_ImageBCG::m_inst = 0; + +void SQ_ImageBCG::init() +{ + m_inst = this; + + TQPixmap p = TQPixmap::fromMimeSource(locate("data", "images/imageedit/reset_value.png")); + + sQ_LabelB->setSingle(true); + sQ_LabelC->setSingle(true); + sQ_LabelG->setSingle(true); + sQ_LabelB->setText(tr2i18n("Brightness")); + sQ_LabelC->setText(tr2i18n("Contrast")); + sQ_LabelG->setText(tr2i18n("Gamma")); + sQ_LabelRed->setText(tr2i18n("Red"), tr2i18n("Cyan")); + sQ_LabelGreen->setText(tr2i18n("Green"), tr2i18n("Magenta")); + sQ_LabelBlue->setText(tr2i18n("Blue"), tr2i18n("Yellow")); + + pushResetB->setPixmap(p); + pushResetC->setPixmap(p); + pushResetG->setPixmap(p); + pushResetRed->setPixmap(p); + pushResetGreen->setPixmap(p); + pushResetBlue->setPixmap(p); + + strings.append(TQString("<b>") + tr2i18n("Brightness") + ", " + tr2i18n("Contrast") + ", " + tr2i18n("Gamma") + "</b>"); + strings.append(TQString("<b>") + tr2i18n("Red") + ", " + tr2i18n("Green") + ", " + tr2i18n("Blue") + "</b>"); + + id = 0; + widgetStackParams->raiseWidget(id); + text->setText(strings[id]); + + TQPixmap tool1 = TQPixmap::fromMimeSource(locate("data", "images/imageedit/resize_toolbutton.png")); + TQPixmap tool2 = TQPixmap::fromMimeSource(locate("data", "images/imageedit/resize_toolbutton2.png")); + push1->setPixmap(tool1); + push2->setPixmap(tool2); + + spinG->setRange(0, 6.0, 0.01, 2); + spinG->setValue(1.0); + connect(spinG, TQ_SIGNAL(valueChanged(int)), spinG, TQ_SLOT(slotValueChanged(int))); +} + +void SQ_ImageBCG::slotResetG() +{ + sliderG->setValue(100); +} + +void SQ_ImageBCG::slotResetC() +{ + sliderC->setValue(0); +} + +void SQ_ImageBCG::slotResetB() +{ + sliderB->setValue(0); +} + +void SQ_ImageBCG::slotResetRed() +{ + sliderRed->setValue(0); +} + +void SQ_ImageBCG::slotResetGreen() +{ + sliderGreen->setValue(0); +} + +void SQ_ImageBCG::slotResetBlue() +{ + sliderBlue->setValue(0); +} + +void SQ_ImageBCG::slotStartBCG() +{ + SQ_ImageBCGOptions opt; + opt.b = sliderB->value(); + opt.c = sliderC->value(); + opt.g = sliderG->value(); + opt.red = sliderRed->value(); + opt.green = sliderGreen->value(); + opt.blue = sliderBlue->value(); + + emit bcg(&opt); +} + +int SQ_ImageBCG::RGB2Y(int r, int g, int b) +{ + return (int)((double)r * 0.299 + (double)g * 0.587 + (double)b * 0.114); +} + +void SQ_ImageBCG::slotBChanged(int v) +{ + spinB->blockSignals(true); + sliderB->blockSignals(true); + spinB->setValue(v); + sliderB->setValue(v); + spinB->blockSignals(false); + sliderB->blockSignals(false); + + changeImage(v, sliderC->value(), sliderG->value(), sliderRed->value(), sliderGreen->value(), sliderBlue->value()); +} + +void SQ_ImageBCG::slotCChanged(int v) +{ + spinC->blockSignals(true); + sliderC->blockSignals(true); + spinC->setValue(v); + sliderC->setValue(v); + spinC->blockSignals(false); + sliderC->blockSignals(false); + + changeImage(sliderB->value(), v, sliderG->value(), sliderRed->value(), sliderGreen->value(), sliderBlue->value()); +} + +void SQ_ImageBCG::slotRedChanged(int v) +{ + spinRed->blockSignals(true); + sliderRed->blockSignals(true); + spinRed->setValue(v); + sliderRed->setValue(v); + spinRed->blockSignals(false); + sliderRed->blockSignals(false); + + changeImage(sliderB->value(), sliderC->value(), sliderG->value(), v, sliderGreen->value(), sliderBlue->value()); +} + +void SQ_ImageBCG::slotGreenChanged(int v) +{ + spinGreen->blockSignals(true); + sliderGreen->blockSignals(true); + spinGreen->setValue(v); + sliderGreen->setValue(v); + spinGreen->blockSignals(false); + sliderGreen->blockSignals(false); + + changeImage(sliderB->value(), sliderC->value(), sliderG->value(), sliderRed->value(), v, sliderBlue->value()); +} + +void SQ_ImageBCG::slotBlueChanged(int v) +{ + spinBlue->blockSignals(true); + sliderBlue->blockSignals(true); + spinBlue->setValue(v); + sliderBlue->setValue(v); + spinBlue->blockSignals(false); + sliderBlue->blockSignals(false); + + changeImage(sliderB->value(), sliderC->value(), sliderG->value(), sliderRed->value(), sliderGreen->value(), v); +} + +void SQ_ImageBCG::slotGChanged(int v) +{ + double g = (double)v / 100.0; + spinG->blockSignals(true); + spinG->setValue(g); + spinG->blockSignals(false); + + changeImage(sliderB->value(), sliderC->value(), v, sliderRed->value(), sliderGreen->value(), sliderBlue->value()); +} + +void SQ_ImageBCG::slotGSpinChanged(double v) +{ + int val = (int)(v * 100.0); + sliderG->blockSignals(true); + sliderG->setValue(val); + sliderG->blockSignals(false); + + changeImage(sliderB->value(), sliderC->value(), val, sliderRed->value(), sliderGreen->value(), sliderBlue->value()); +} + +void SQ_ImageBCG::assignNewImage(const TQImage &im) +{ + TQPixmap p; + p.convertFromImage(im); + pixmap1->setPixmap(p); +} + +void SQ_ImageBCG::changeImage(int b, int c, int g1, int red, int green, int blue) +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + double g = (double)g1 / 100.0; + + sample = sample_saved.copy(); + + // change brightness + fmt_filters::brightness(fmt_filters::image(sample.bits(), sample.width(), sample.height()), b); + + //change contrast + if(c) + fmt_filters::contrast(fmt_filters::image(sample.bits(), sample.width(), sample.height()), c); + + // change gamma + if(g1 != 100) + fmt_filters::gamma(fmt_filters::image(sample.bits(), sample.width(), sample.height()), g); + + if(red || green || blue) + fmt_filters::colorize(fmt_filters::image(sample.bits(), sample.width(), sample.height()), blue, green, red); + + assignNewImage(sample); +} + +void SQ_ImageBCG::slotPush() +{ + if(!id) id = 1; + else id = 0; + + widgetStackParams->raiseWidget(id); + text->setText(strings[id]); +} + +void SQ_ImageBCG::setPreviewImage(const TQImage &im) +{ + if(im.isNull()) return; + + sample = im.copy(); + sample_saved = sample.copy(); + + TQPixmap p; + + p.convertFromImage(sample_saved); + pixmap->setPixmap(p); + pixmap1->setPixmap(p); + + changeImage(sliderB->value(), sliderC->value(), sliderG->value(), sliderRed->value(), sliderGreen->value(), sliderBlue->value()); +} + +SQ_ImageBCG* SQ_ImageBCG::instance() +{ + return m_inst; +} diff --git a/src/ksquirrelpart/sq_imageedit.h b/src/ksquirrelpart/sq_imageedit.h new file mode 100644 index 0000000..a93e26b --- /dev/null +++ b/src/ksquirrelpart/sq_imageedit.h @@ -0,0 +1,84 @@ +/*************************************************************************** + sq_imageedit.h - description + ------------------- + begin : 29 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_IMAGEEDIT_H +#define SQ_IMAGEEDIT_H + +#include <tqfont.h> +#include <tqcolor.h> + +#include "fmt_filters.h" + +struct SQ_ImageOptions +{ + TQString putto; + int where_to_put; + bool close; +}; + +struct SQ_ImageBCGOptions +{ + int b, c, g; + int red, green, blue; +}; + +struct SQ_ImageConvertOptions +{ + TQString libname; +}; + +struct SQ_ImageFilterOptions +{ + int type; + + bool _bool; + fmt_filters::rgb rgb1, rgb2; + float _float; + unsigned int _uint; + double _double1, _double2; +}; + +namespace F +{ + enum ftype + { + fblend = 0, + fblur, + fdesaturate, + fdespeckle, + fedge, + femboss, + fequalize, + ffade, + fflatten, + fimplode, + fnegative, + fnoise, + foil, + fshade, + fsharpen, + fsolarize, + fspread, + fswapRGB, + fswirl, + fthreshold, + fgray, + fredeye + }; +} + +#endif diff --git a/src/ksquirrelpart/sq_imagefilter.ui b/src/ksquirrelpart/sq_imagefilter.ui new file mode 100644 index 0000000..0e50f97 --- /dev/null +++ b/src/ksquirrelpart/sq_imagefilter.ui @@ -0,0 +1,1559 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>SQ_ImageFilter</class> +<widget class="TQDialog"> + <property name="name"> + <cstring>SQ_ImageFilter</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>537</width> + <height>421</height> + </rect> + </property> + <property name="caption"> + <string>Filter</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQWidgetStack" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>widgetStackFilters</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <widget class="TQWidget"> + <property name="name"> + <cstring>blendWidget</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Color:</string> + </property> + </widget> + <widget class="KColorButton" row="0" column="1"> + <property name="name"> + <cstring>pushBlendColor</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer17</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>blendOpacity</cstring> + </property> + <property name="label"> + <string>Opacity</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer9_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="1" column="0"> + <property name="name"> + <cstring>blurSigma</cstring> + </property> + <property name="label"> + <string>Sigma</string> + </property> + </widget> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>blurRadius</cstring> + </property> + <property name="label"> + <string>Radius</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>2</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer10_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>45</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>desaturateValue</cstring> + </property> + <property name="label"> + <string>Factor</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>3</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="text"> + <string>There are no special options available for this filter. Just click "Filter".</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>11</width> + <height>26</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>4</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>30</height> + </size> + </property> + </spacer> + <widget class="KIntNumInput" row="0" column="0"> + <property name="name"> + <cstring>edgeRadius</cstring> + </property> + <property name="label"> + <string>Radius</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>5</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>30</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="1" column="0"> + <property name="name"> + <cstring>embossSigma</cstring> + </property> + <property name="label"> + <string>Sigma</string> + </property> + </widget> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>embossRadius</cstring> + </property> + <property name="label"> + <string>Radius</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>6</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="text"> + <string>There are no special options available for this filter. Just click "Filter".</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer11_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>11</width> + <height>14</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>7</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KColorButton" row="0" column="1"> + <property name="name"> + <cstring>fadeColor</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer15</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Color:</string> + </property> + </widget> + <widget class="KDoubleNumInput" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>fadeValue</cstring> + </property> + <property name="label"> + <string>Value</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>8</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KColorButton" row="0" column="1"> + <property name="name"> + <cstring>flattenColor1</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer16</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>11</height> + </size> + </property> + </spacer> + <widget class="KColorButton" row="1" column="1"> + <property name="name"> + <cstring>flattenColor2</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_4_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Color 1:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_4_3</cstring> + </property> + <property name="text"> + <string>Color 2:</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>9</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer15_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>25</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>implodeFactor</cstring> + </property> + <property name="label"> + <string>Factor</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>10</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer11_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>11</width> + <height>14</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2_2_2</cstring> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="text"> + <string>There are no special options available for this filter. Just click "Filter".</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>11</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>buttonGroupNoise</cstring> + </property> + <property name="title"> + <string>Noise type</string> + </property> + <property name="exclusive"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>9</number> + </property> + <property name="spacing"> + <number>2</number> + </property> + <widget class="TQRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioButton1</cstring> + </property> + <property name="text"> + <string>Uniform</string> + </property> + </widget> + <widget class="TQRadioButton" row="0" column="1"> + <property name="name"> + <cstring>radioButton1_4</cstring> + </property> + <property name="text"> + <string>Impulse</string> + </property> + <property name="buttonGroupId"> + <number>3</number> + </property> + </widget> + <widget class="TQRadioButton" row="2" column="0"> + <property name="name"> + <cstring>radioButton1_3</cstring> + </property> + <property name="text"> + <string>Multiplicative Gaussian</string> + </property> + </widget> + <widget class="TQRadioButton" row="2" column="1"> + <property name="name"> + <cstring>radioButton1_6</cstring> + </property> + <property name="text"> + <string>Poisson</string> + </property> + <property name="buttonGroupId"> + <number>5</number> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioButton1_2</cstring> + </property> + <property name="text"> + <string>Gaussian</string> + </property> + <property name="buttonGroupId"> + <number>1</number> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="1"> + <property name="name"> + <cstring>radioButton1_5</cstring> + </property> + <property name="text"> + <string>Laplacian</string> + </property> + <property name="buttonGroupId"> + <number>4</number> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>12</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer15_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>35</height> + </size> + </property> + </spacer> + <widget class="KIntNumInput" row="0" column="0"> + <property name="name"> + <cstring>oilRadius</cstring> + </property> + <property name="label"> + <string>Radius</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>13</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox" row="0" column="0"> + <property name="name"> + <cstring>shadeColor</cstring> + </property> + <property name="text"> + <string>Color</string> + </property> + </widget> + <spacer row="3" column="0"> + <property name="name"> + <cstring>spacer21</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="2" column="0"> + <property name="name"> + <cstring>shadeElev</cstring> + </property> + <property name="label"> + <string>Elevation</string> + </property> + </widget> + <widget class="KDoubleNumInput" row="1" column="0"> + <property name="name"> + <cstring>shadeAzim</cstring> + </property> + <property name="label"> + <string>Azimuth</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>14</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer13_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="1" column="0"> + <property name="name"> + <cstring>sharpenSigma</cstring> + </property> + <property name="label"> + <string>Sigma</string> + </property> + </widget> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>sharpenRadius</cstring> + </property> + <property name="label"> + <string>Radius</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>15</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer13_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>60</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>solarizeValue</cstring> + </property> + <property name="label"> + <string>Factor</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>16</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer24</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>35</height> + </size> + </property> + </spacer> + <widget class="KIntNumInput" row="0" column="0"> + <property name="name"> + <cstring>spreadValue</cstring> + </property> + <property name="label"> + <string>Amount</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>17</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>buttonGroupSwapRGB</cstring> + </property> + <property name="title"> + <string>Type</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>9</number> + </property> + <property name="spacing"> + <number>2</number> + </property> + <widget class="TQRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioButton7</cstring> + </property> + <property name="text"> + <string>GBR</string> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioButton8</cstring> + </property> + <property name="text"> + <string>BRG</string> + </property> + </widget> + </grid> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer25</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>11</width> + <height>41</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>18</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer13_2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>25</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput" row="0" column="0"> + <property name="name"> + <cstring>swirlAngle</cstring> + </property> + <property name="label"> + <string>Degrees</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>19</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer24_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>75</height> + </size> + </property> + </spacer> + <widget class="KIntNumInput" row="0" column="0"> + <property name="name"> + <cstring>thresholdValue</cstring> + </property> + <property name="label"> + <string>Threshold</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>20</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2_2_2_2</cstring> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="text"> + <string>There are no special options available for this filter. Just click "Filter".</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer11_2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>11</width> + <height>113</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>21</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KIntNumInput" row="0" column="0"> + <property name="name"> + <cstring>thresholdRE</cstring> + </property> + <property name="label"> + <string>Threshold</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer26_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>71</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer27</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="5" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer14</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>285</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushFilter</cstring> + </property> + <property name="text"> + <string>Filter</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>pushCancel</cstring> + </property> + <property name="text"> + <string>Close</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="Line" row="4" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>line7</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQListBox" row="0" column="0" rowspan="4" colspan="1"> + <item> + <property name="text"> + <string>Blend</string> + </property> + </item> + <item> + <property name="text"> + <string>Blur</string> + </property> + </item> + <item> + <property name="text"> + <string>Desaturate</string> + </property> + </item> + <item> + <property name="text"> + <string>Despeckle</string> + </property> + </item> + <item> + <property name="text"> + <string>Edge</string> + </property> + </item> + <item> + <property name="text"> + <string>Emboss</string> + </property> + </item> + <item> + <property name="text"> + <string>Equalize</string> + </property> + </item> + <item> + <property name="text"> + <string>Fade</string> + </property> + </item> + <item> + <property name="text"> + <string>Flatten</string> + </property> + </item> + <item> + <property name="text"> + <string>Implode</string> + </property> + </item> + <item> + <property name="text"> + <string>Negative</string> + </property> + </item> + <item> + <property name="text"> + <string>Noise</string> + </property> + </item> + <item> + <property name="text"> + <string>Oil</string> + </property> + </item> + <item> + <property name="text"> + <string>Shade</string> + </property> + </item> + <item> + <property name="text"> + <string>Sharpen</string> + </property> + </item> + <item> + <property name="text"> + <string>Solarize</string> + </property> + </item> + <item> + <property name="text"> + <string>Spread</string> + </property> + </item> + <item> + <property name="text"> + <string>Swap colors</string> + </property> + </item> + <item> + <property name="text"> + <string>Swirl</string> + </property> + </item> + <item> + <property name="text"> + <string>Threshold</string> + </property> + </item> + <item> + <property name="text"> + <string>Grayscale</string> + </property> + </item> + <item> + <property name="text"> + <string>Redeye</string> + </property> + </item> + <property name="name"> + <cstring>listMain</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + </widget> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer26</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLayoutWidget" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="SQ_BCGLabel" row="1" column="3"> + <property name="name"> + <cstring>pixmap1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>160</height> + </size> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Original image:</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer27_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer28</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="SQ_BCGLabel" row="1" column="1"> + <property name="name"> + <cstring>pixmap</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>160</height> + </size> + </property> + </widget> + <spacer row="1" column="4"> + <property name="name"> + <cstring>spacer27_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>1</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="3" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Image after filtering:</string> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>SQ_BCGLabel</class> + <header location="local">sq_bcglabel.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<connections> + <connection> + <sender>pushCancel</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageFilter</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>pushFilter</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageFilter</receiver> + <slot>slotStartFiltering()</slot> + </connection> + <connection> + <sender>listMain</sender> + <signal>selectionChanged()</signal> + <receiver>SQ_ImageFilter</receiver> + <slot>slotShowPage()</slot> + </connection> +</connections> +<tabstops> + <tabstop>pushFilter</tabstop> + <tabstop>pushCancel</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in declaration">sq_imageedit.h</include> + <include location="global" impldecl="in declaration">tqimage.h</include> + <include location="local" impldecl="in implementation">fmt_filters.h</include> + <include location="global" impldecl="in implementation">kcolorbutton.h</include> + <include location="global" impldecl="in implementation">knuminput.h</include> + <include location="global" impldecl="in implementation">sq_bcglabel.h</include> + <include location="local" impldecl="in implementation">sq_config.h</include> + <include location="local" impldecl="in implementation">sq_iconloader.h</include> + <include location="local" impldecl="in implementation">sq_imagefilter.ui.h</include> +</includes> +<variables> + <variable access="private">TQImage sample, sample_saved;</variable> + <variable access="private">static SQ_ImageFilter *m_inst;</variable> +</variables> +<signals> + <signal>filter(SQ_ImageFilterOptions*)</signal> +</signals> +<slots> + <slot access="private" specifier="non virtual">slotStartFiltering()</slot> + <slot access="private" specifier="non virtual">slotShowPage()</slot> + <slot access="private" specifier="non virtual">swapRGB()</slot> + <slot access="private" specifier="non virtual">blend()</slot> + <slot access="private" specifier="non virtual">fade()</slot> + <slot access="private" specifier="non virtual">desaturate()</slot> + <slot access="private" specifier="non virtual">threshold()</slot> + <slot access="private" specifier="non virtual">solarize()</slot> + <slot access="private" specifier="non virtual">spread()</slot> + <slot access="private" specifier="non virtual">swirl()</slot> + <slot access="private" specifier="non virtual">noise()</slot> + <slot access="private" specifier="non virtual">redeye()</slot> + <slot access="private" specifier="non virtual">flatten()</slot> + <slot access="private" specifier="non virtual">shade()</slot> + <slot access="private" specifier="non virtual">blur()</slot> + <slot access="private" specifier="non virtual">implode()</slot> + <slot access="private" specifier="non virtual">edge()</slot> + <slot access="private" specifier="non virtual">emboss()</slot> + <slot access="private" specifier="non virtual">sharpen()</slot> + <slot access="private" specifier="non virtual">oil()</slot> +</slots> +<functions> + <function access="private" specifier="non virtual">init()</function> + <function specifier="non virtual">setPreviewImage( const TQImage & im )</function> + <function access="private" specifier="non virtual">assignNewImage( const TQImage & im )</function> + <function access="private" specifier="non virtual">negative()</function> + <function access="private" specifier="non virtual">togray()</function> + <function access="private" specifier="non virtual">equalize()</function> + <function access="private" specifier="non virtual">despeckle()</function> + <function access="private" specifier="non virtual">hackConnect()</function> + <function specifier="static" returnType="SQ_ImageFilter *">instance()</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/ksquirrelpart/sq_imagefilter.ui.h b/src/ksquirrelpart/sq_imagefilter.ui.h new file mode 100644 index 0000000..18eb263 --- /dev/null +++ b/src/ksquirrelpart/sq_imagefilter.ui.h @@ -0,0 +1,610 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** TQt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +SQ_ImageFilter * SQ_ImageFilter::m_inst = 0; + +void SQ_ImageFilter::init() +{ + m_inst = this; + + // restore NumInputs... + const double sigmaMax = 99.9, sigmaMin = 0.01; + const double radiusMax = 99.9, radiusMin = 0.01; + + blendOpacity->setRange(0.0f, 1.0f, 0.01, true); + fadeValue->setRange(0.0f, 1.0f, 0.01f, true); + desaturateValue->setRange(0.0f, 1.0f, 0.01, true); + thresholdValue->setRange(0, 255, 1, true); + thresholdRE->setRange(0, 255, 1, true); + solarizeValue->setRange(0.0f, 50.0f, 0.01f, true); + spreadValue->setRange(1, 10, 1, true); + swirlAngle->setRange(-720.0f, 720.0f, 0.1f, true); + shadeAzim->setRange(0.0f, 90.0f, 0.01f, true); + shadeElev->setRange(0.0f, 90.0f, 0.01f, true); + blurRadius->setRange(radiusMin, radiusMax, 0.01f, true); + blurSigma->setRange(sigmaMin, 50.0, 0.01f, true); + implodeFactor->setRange(0, 100, 1, true); + edgeRadius->setRange((int)radiusMin, 30, 1, true); + embossRadius->setRange(radiusMin, radiusMax, 0.01f, true); + embossSigma->setRange(sigmaMin, sigmaMax, 0.01f, true); + sharpenRadius->setRange(radiusMin, radiusMax, 0.01f, true); + sharpenSigma->setRange(sigmaMin, 30.0, 0.01f, true); + oilRadius->setRange(1, 5, 1, true); + + SQ_Config::instance()->setGroup("Image edit options"); + + buttonGroupSwapRGB->setButton(SQ_Config::instance()->readNumEntry("filter_swapRGB", 0)); + // blend + TQColor c; + c.setNamedColor(SQ_Config::instance()->readEntry("filter_blend_color", "#00ff00")); + pushBlendColor->setColor(c); + blendOpacity->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_blend_opacity", 0.5)); + + // fade + c.setNamedColor(SQ_Config::instance()->readEntry("filter_flend_color", "#00ff00")); + fadeColor->setColor(c); + fadeValue->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_fade_value", 0.5)); + + // desaturate + desaturateValue->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_desaturate_value", 0.5)); + + // threshold + thresholdValue->setValue(SQ_Config::instance()->readNumEntry("filter_threshold_value", 1)); + + // threshold for redeye + thresholdRE->setValue(SQ_Config::instance()->readNumEntry("filter_threshold_redeye", 10)); + + // solarize + solarizeValue->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_solarize_value", 0.5)); + + // spread + spreadValue->setValue(SQ_Config::instance()->readNumEntry("filter_spread_value", 1)); + + // swirl + swirlAngle->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_swirl_value", 0.0)); + + // noise + buttonGroupNoise->setButton(SQ_Config::instance()->readNumEntry("filter_noise", 0)); + + // flatten + c.setNamedColor(SQ_Config::instance()->readEntry("filter_flatten_color1", "#00ff00")); + flattenColor1->setColor(c); + c.setNamedColor(SQ_Config::instance()->readEntry("filter_flatten_color2", "#00ff00")); + flattenColor2->setColor(c); + + // shade + shadeAzim->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_shade_azim", 0.1)); + shadeElev->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_shade_elev", 0.1)); + + if(SQ_Config::instance()->readBoolEntry("filter_shade_color", false)) + shadeColor->toggle(); + + // blur + blurRadius->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_blur_radius", 0.1)); + blurSigma->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_blur_sigma", 0.1)); + + // implode + implodeFactor->setValue(SQ_Config::instance()->readNumEntry("filter_implode_factor", 1)); + + // edge + edgeRadius->setValue(SQ_Config::instance()->readNumEntry("filter_egde_radius", 1)); + + // emboss + embossRadius->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_emboss_radius", 0.1)); + embossSigma->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_emboss_sigma", 0.1)); + + // sharpen + sharpenRadius->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_sharpen_radius", 0.1)); + sharpenSigma->setValue(SQ_Config::instance()->readDoubleNumEntry("filter_sharpen_sigma", 0.1)); + + // oil + oilRadius->setValue(SQ_Config::instance()->readNumEntry("filter_oil_radius", 1)); + + listMain->setCurrentItem(SQ_Config::instance()->readNumEntry("filter_filter", 0)); + + hackConnect(); +} + +void SQ_ImageFilter::slotStartFiltering() +{ + SQ_Config *tdeconf = SQ_Config::instance(); + + tdeconf->setGroup("Image edit options"); + tdeconf->writeEntry("filter_swapRGB", buttonGroupSwapRGB->selectedId()); + tdeconf->writeEntry("filter_blend_color", pushBlendColor->color().name()); + tdeconf->writeEntry("filter_blend_opacity", blendOpacity->value()); + tdeconf->writeEntry("filter_fade_color", fadeColor->color().name()); + tdeconf->writeEntry("filter_fade_value", fadeValue->value()); + tdeconf->writeEntry("filter_desaturate_value", desaturateValue->value()); + tdeconf->writeEntry("filter_threshold_value", thresholdValue->value()); + tdeconf->writeEntry("filter_threshold_redeye", thresholdRE->value()); + tdeconf->writeEntry("filter_solarize_value", solarizeValue->value()); + tdeconf->writeEntry("filter_spread_value", spreadValue->value()); + tdeconf->writeEntry("filter_swirl_value", swirlAngle->value()); + tdeconf->writeEntry("filter_noise", buttonGroupNoise->selectedId()); + tdeconf->writeEntry("filter_flatten_color1", flattenColor1->color().name()); + tdeconf->writeEntry("filter_flatten_color2", flattenColor2->color().name()); + tdeconf->writeEntry("filter_shade_azim", shadeAzim->value()); + tdeconf->writeEntry("filter_shade_elev", shadeElev->value()); + tdeconf->writeEntry("filter_shade_color", shadeColor->isChecked()); + tdeconf->writeEntry("filter_blur_radius", blurRadius->value()); + tdeconf->writeEntry("filter_blur_sigma", blurSigma->value()); + tdeconf->writeEntry("filter_implode_factor", implodeFactor->value()); + tdeconf->writeEntry("filter_egde_radius", edgeRadius->value()); + tdeconf->writeEntry("filter_emboss_radius", embossRadius->value()); + tdeconf->writeEntry("filter_emboss_sigma", embossSigma->value()); + tdeconf->writeEntry("filter_sharpen_radius", sharpenRadius->value()); + tdeconf->writeEntry("filter_sharpen_sigma", sharpenSigma->value()); + tdeconf->writeEntry("filter_oil_radius", oilRadius->value()); + tdeconf->writeEntry("filter_filter", listMain->currentItem()); + + SQ_ImageFilterOptions opt; + + opt.type = listMain->currentItem(); + + switch(opt.type) + { + case F::fblend: + { + TQColor c = pushBlendColor->color(); + opt.rgb1 = fmt_filters::rgb(c.red(), c.green(), c.blue()); + opt._float = blendOpacity->value(); + } + break; + case F::fblur: opt._double1 = blurRadius->value(); opt._double2 = blurSigma->value(); break; + case F::fdesaturate: opt._float = (float)desaturateValue->value(); break; + case F::fdespeckle: break; + case F::fedge: opt._double1 = (double)edgeRadius->value(); break; + case F::femboss: opt._double1 = embossRadius->value(); opt._double2 = embossSigma->value(); break; + case F::fequalize: break; + case F::ffade: + { + TQColor c = fadeColor->color(); + opt.rgb1 = fmt_filters::rgb(c.red(), c.green(), c.blue()); + opt._float = (float)fadeValue->value(); + } + break; + case F::fflatten: + { + TQColor c = flattenColor1->color(); + opt.rgb1 = fmt_filters::rgb(c.red(), c.green(), c.blue()); + c = flattenColor2->color(); + opt.rgb2 = fmt_filters::rgb(c.red(), c.green(), c.blue()); + } + break; + case F::fimplode: opt._double1 = implodeFactor->value(); break; + case F::fnegative: break; + case F::fnoise: opt._uint = buttonGroupNoise->selectedId(); break; + case F::foil: opt._double1 = (double)oilRadius->value(); break; + case F::fshade: opt._bool = shadeColor->isChecked(); opt._double1 = shadeAzim->value(); opt._double2 = shadeElev->value(); break; + case F::fsharpen: opt._double1 = sharpenRadius->value(); opt._double2 = sharpenSigma->value();break; + case F::fsolarize: opt._double1 = solarizeValue->value(); break; + case F::fspread: opt._uint = spreadValue->value(); break; + case F::fswapRGB: opt._uint = buttonGroupSwapRGB->selectedId(); break; + case F::fswirl: opt._double1 = swirlAngle->value(); break; + case F::fthreshold: opt._uint = thresholdValue->value(); break; + case F::fgray: break; + case F::fredeye: opt._uint = thresholdRE->value(); break; + } + + emit filter(&opt); +} + +void SQ_ImageFilter::slotShowPage() +{ + int id = listMain->currentItem(); + + widgetStackFilters->raiseWidget(id); + + switch(id) + { + case F::fblend: blend(); break; + case F::fblur: blur(); break; + case F::fdesaturate: desaturate(); break; + case F::fdespeckle: despeckle(); break; + case F::fedge: edge(); break; + case F::femboss: emboss(); break; + case F::fequalize: equalize(); break; + case F::ffade: fade(); break; + case F::fflatten: flatten(); break; + case F::fimplode: implode(); break; + case F::fnegative: negative(); break; + case F::fnoise: noise(); break; + case F::foil: oil(); break; + case F::fshade: shade(); break; + case F::fsharpen: sharpen(); break; + case F::fsolarize: solarize(); break; + case F::fspread: spread(); break; + case F::fswapRGB: swapRGB(); break; + case F::fswirl: swirl(); break; + case F::fthreshold: threshold(); break; + case F::fgray: togray(); break; + case F::fredeye: redeye(); break; + } +} + +void SQ_ImageFilter::setPreviewImage(const TQImage &im) +{ + if(im.isNull()) return; + + sample = im.copy(); + sample_saved = sample.copy(); + + TQPixmap p; + + p.convertFromImage(sample_saved); + pixmap->setPixmap(p); + pixmap1->setPixmap(p); + + slotShowPage(); +} + +void SQ_ImageFilter::assignNewImage(const TQImage &im) +{ + TQPixmap p; + p.convertFromImage(im); + pixmap1->setPixmap(p); +} + +void SQ_ImageFilter::swapRGB() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + int id = buttonGroupSwapRGB->selectedId(); + + if(id == -1) + return; + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::swapRGB(im, (id ? fmt_filters::GBR : fmt_filters::BRG)); + + assignNewImage(sample); +} + +void SQ_ImageFilter::negative() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::negative(im); + + assignNewImage(sample); +} + +void SQ_ImageFilter::blend() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + TQColor c = pushBlendColor->color(); + + fmt_filters::rgb rgb(c.red(), c.green(), c.blue()); + + fmt_filters::blend(im, rgb, blendOpacity->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::fade() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + TQColor c = fadeColor->color(); + + fmt_filters::fade(im, fmt_filters::rgb(c.red(), c.green(), c.blue()), fadeValue->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::togray() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::gray(im); + + assignNewImage(sample); +} + +void SQ_ImageFilter::desaturate() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::desaturate(im, desaturateValue->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::threshold() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::threshold(im, thresholdValue->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::solarize() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::solarize(im, solarizeValue->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::spread() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::spread(im, spreadValue->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::swirl() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::swirl(im, swirlAngle->value(), fmt_filters::rgba(255,255,255,255)); + + assignNewImage(sample); +} + +void SQ_ImageFilter::noise() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::noise(im, (fmt_filters::NoiseType)buttonGroupNoise->selectedId()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::redeye() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::redeye(im, im.w, im.h, 0, 0, thresholdRE->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::flatten() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + TQColor c1 = flattenColor1->color(); + TQColor c2 = flattenColor2->color(); + + fmt_filters::flatten(im, fmt_filters::rgb(c1.red(), c1.green(), c1.blue()), fmt_filters::rgb(c2.red(), c2.green(), c2.blue())); + + assignNewImage(sample); +} + +void SQ_ImageFilter::shade() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::shade(im, shadeColor->isChecked(), shadeAzim->value(), shadeElev->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::equalize() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::equalize(im); + + assignNewImage(sample); +} + +void SQ_ImageFilter::blur() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::blur(im, blurRadius->value(), blurSigma->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::despeckle() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::despeckle(im); + + assignNewImage(sample); +} + +void SQ_ImageFilter::implode() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::implode(im, implodeFactor->value(), fmt_filters::white); + + assignNewImage(sample); +} + +void SQ_ImageFilter::edge() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::edge(im, (double)edgeRadius->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::emboss() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::emboss(im, embossRadius->value(), embossSigma->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::sharpen() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::sharpen(im, sharpenRadius->value(), sharpenSigma->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::oil() +{ + if(sample.isNull() || sample_saved.isNull()) + return; + + sample = sample_saved.copy(); + + fmt_filters::image im(sample.bits(), sample.width(), sample.height()); + + fmt_filters::oil(im, oilRadius->value()); + + assignNewImage(sample); +} + +void SQ_ImageFilter::hackConnect() +{ + connect( blendOpacity, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( blend() ) ); + connect( pushBlendColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT( blend() ) ); + connect( blurRadius, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( blur() ) ); + connect( blurSigma, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( blur() ) ); + connect( desaturateValue, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( desaturate() ) ); + connect( edgeRadius, TQ_SIGNAL( valueChanged(int) ), this, TQ_SLOT( edge() ) ); + connect( embossRadius, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( emboss() ) ); + connect( embossSigma, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( emboss() ) ); + connect( fadeColor, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT( fade() ) ); + connect( fadeValue, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( fade() ) ); + connect( flattenColor1, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT( flatten() ) ); + connect( flattenColor2, TQ_SIGNAL( changed(const TQColor&) ), this, TQ_SLOT( flatten() ) ); + connect( implodeFactor, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( implode() ) ); + connect( buttonGroupNoise, TQ_SIGNAL( clicked(int) ), this, TQ_SLOT( noise() ) ); + connect( oilRadius, TQ_SIGNAL( valueChanged(int) ), this, TQ_SLOT( oil() ) ); + connect( shadeAzim, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( shade() ) ); + connect( shadeColor, TQ_SIGNAL( toggled(bool) ), this, TQ_SLOT( shade() ) ); + connect( shadeElev, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( shade() ) ); + connect( sharpenRadius, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( sharpen() ) ); + connect( sharpenSigma, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( sharpen() ) ); + connect( solarizeValue, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( solarize() ) ); + connect( spreadValue, TQ_SIGNAL( valueChanged(int) ), this, TQ_SLOT( spread() ) ); + connect( buttonGroupSwapRGB, TQ_SIGNAL( clicked(int) ), this, TQ_SLOT( swapRGB() ) ); + connect( swirlAngle, TQ_SIGNAL( valueChanged(double) ), this, TQ_SLOT( swirl() ) ); + connect( thresholdValue, TQ_SIGNAL( valueChanged(int) ), this, TQ_SLOT( threshold() ) ); + connect( thresholdRE, TQ_SIGNAL( valueChanged(int) ), this, TQ_SLOT( redeye() ) ); +} + +SQ_ImageFilter* SQ_ImageFilter::instance() +{ + return m_inst; +} diff --git a/src/ksquirrelpart/sq_imageproperties.ui b/src/ksquirrelpart/sq_imageproperties.ui new file mode 100644 index 0000000..a85d9c2 --- /dev/null +++ b/src/ksquirrelpart/sq_imageproperties.ui @@ -0,0 +1,969 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>SQ_ImageProperties</class> +<widget class="TQDialog"> + <property name="name"> + <cstring>SQ_ImageProperties</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>495</width> + <height>384</height> + </rect> + </property> + <property name="caption"> + <string>Image properties</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton" row="1" column="1"> + <property name="name"> + <cstring>pushButton1</cstring> + </property> + <property name="text"> + <string>Close</string> + </property> + <property name="toggleButton"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>470</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQTabWidget" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <widget class="TQWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>File</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="TQGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Attributes</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel4_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Owner:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel5_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Group:</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>textOwner</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel27_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Permissions:</string> + </property> + <property name="alignment"> + <set>AlignVCenter</set> + </property> + </widget> + <widget class="TQLabel" row="2" column="1"> + <property name="name"> + <cstring>textPermissions</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="1" column="1"> + <property name="name"> + <cstring>textGroup</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox" row="1" column="1"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Time</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Created:</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Last read:</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Last modified:</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>textCreated</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="1" column="1"> + <property name="name"> + <cstring>textLastRead</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="2" column="1"> + <property name="name"> + <cstring>textLastMod</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>General</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>File:</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="1"> + <property name="name"> + <cstring>textSize</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Directory:</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Size:</string> + </property> + </widget> + <widget class="TQLineEdit" row="0" column="1"> + <property name="name"> + <cstring>lineDirectory</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLineEdit" row="1" column="1"> + <property name="name"> + <cstring>lineFile</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Image</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel6_2_2_2</cstring> + </property> + <property name="text"> + <string>Type:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel11_2_2_2</cstring> + </property> + <property name="text"> + <string>Number of frames:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel23_2_2_2_2_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Current frame</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel23_2_2_2_2_4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Delay:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel7_2_2_2</cstring> + </property> + <property name="text"> + <string>Dimensions:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel8_2_2_2</cstring> + </property> + <property name="text"> + <string>Bits per pixel:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel9_2_2_2</cstring> + </property> + <property name="text"> + <string>Color space:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel10_2_2_2</cstring> + </property> + <property name="text"> + <string>Compression:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel21_2_2_2</cstring> + </property> + <property name="text"> + <string>Uncompressed size:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel23_2_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Compression ratio:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel23_2_2_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Interlaced:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel23_2_2_2_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Status:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer10</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>210</width> + <height>16</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textType</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textFrames</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textFrame</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textDelay</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textDimensions</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textBpp</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textColorModel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textCompression</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textUncompressed</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textRatio</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textInterlaced</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textStatusIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textStatus</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>205</width> + <height>16</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>Metadata</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQListView" row="0" column="0"> + <column> + <property name="text"> + <string>Group</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listMeta</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>pushButton1</sender> + <signal>clicked()</signal> + <receiver>SQ_ImageProperties</receiver> + <slot>close()</slot> + </connection> + <connection> + <sender>listMeta</sender> + <signal>contextMenuRequested(TQListViewItem*,const TQPoint&,int)</signal> + <receiver>SQ_ImageProperties</receiver> + <slot>slotContextMenu(TQListViewItem*,const TQPoint&,int)</slot> + </connection> +</connections> +<tabstops> + <tabstop>tabWidget</tabstop> + <tabstop>lineDirectory</tabstop> + <tabstop>lineFile</tabstop> + <tabstop>listMeta</tabstop> + <tabstop>pushButton1</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in declaration">tqvaluevector.h</include> + <include location="global" impldecl="in declaration">tqvariant.h</include> + <include location="global" impldecl="in declaration">tqpair.h</include> + <include location="global" impldecl="in declaration">tqpixmap.h</include> + <include location="global" impldecl="in declaration">kurl.h</include> + <include location="global" impldecl="in declaration">tdeio/job.h</include> + <include location="global" impldecl="in declaration">tdefileitem.h</include> + <include location="global" impldecl="in implementation">tqstringlist.h</include> + <include location="global" impldecl="in implementation">tqfileinfo.h</include> + <include location="global" impldecl="in implementation">tdeio/global.h</include> + <include location="global" impldecl="in implementation">tdepopupmenu.h</include> + <include location="global" impldecl="in implementation">kstdaction.h</include> + <include location="global" impldecl="in implementation">tdeaction.h</include> + <include location="global" impldecl="in implementation">tqapplication.h</include> + <include location="global" impldecl="in implementation">tqclipboard.h</include> + <include location="global" impldecl="in implementation">tqdir.h</include> + <include location="local" impldecl="in implementation">sq_iconloader.h</include> + <include location="global" impldecl="in implementation">tqbuttongroup.h</include> + <include location="global" impldecl="in implementation">tdelocale.h</include> + <include location="local" impldecl="in implementation">sq_imageproperties.ui.h</include> +</includes> +<forwards> + <forward>class TDEPopupMenu;</forward> + <forward>class TDEAction;</forward> + <forward>namespace TDEIO { class Job; }</forward> +</forwards> +<variables> + <variable access="private">KURL url;</variable> + <variable access="private">TQWidget *kew;</variable> + <variable access="private">TQPixmap ok, error;</variable> + <variable access="private">TDEPopupMenu *menu;</variable> + <variable access="private">TQListViewItem *data;</variable> + <variable access="private">int z, exifMode;</variable> + <variable access="private">TDEAction *copy, *copyentry, *copyall;</variable> + <variable access="private">TQString file;</variable> +</variables> +<slots> + <slot access="private">slotContextMenu( TQListViewItem * item, const TQPoint & p, int z1 )</slot> + <slot access="private">slotCopyString()</slot> + <slot access="private">slotCopyAll()</slot> + <slot access="private">slotCopyEntry()</slot> + <slot access="private" specifier="non virtual">slotModeClicked( int id )</slot> + <slot access="private">slotStatResult( TDEIO::Job * job )</slot> +</slots> +<functions> + <function access="private" specifier="non virtual">init()</function> + <function access="private" specifier="non virtual">destroy()</function> + <function>setParams( TQStringList & l )</function> + <function specifier="non virtual">setURL( const KURL & _url )</function> + <function access="private">setFileParams()</function> + <function>setMetaInfo( TQValueVector<TQPair<TQString, TQString> > meta )</function> + <function specifier="non virtual">setFile( const TQString & _file )</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/ksquirrelpart/sq_imageproperties.ui.h b/src/ksquirrelpart/sq_imageproperties.ui.h new file mode 100644 index 0000000..5265d46 --- /dev/null +++ b/src/ksquirrelpart/sq_imageproperties.ui.h @@ -0,0 +1,264 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** TQt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +/* + * SQ_ImageProperties shows image properties. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SQ_HAVE_KEXIF +#include <libkexif/kexifwidget.h> +#include <libkexif/kexifdata.h> +#include <tqobjectlist.h> +#include "sq_config.h" +#endif + +void SQ_ImageProperties::init() +{ + menu = new TDEPopupMenu; + copy = KStdAction::copy(this, TQ_SLOT(slotCopyString()), 0); + copyentry = new TDEAction(i18n("Copy entry"), 0, this, TQ_SLOT(slotCopyEntry()), 0); + copyall = new TDEAction(i18n("Copy all entries"), 0, this, TQ_SLOT(slotCopyAll()), 0); + + copyentry->setIcon(copy->icon()); + copyall->setIcon(copy->icon()); + + copy->plug(menu); + copyentry->plug(menu); + copyall->plug(menu); + + ok = SQ_IconLoader::instance()->loadIcon("ok", TDEIcon::Desktop, 16); + error = SQ_IconLoader::instance()->loadIcon("error", TDEIcon::Desktop, 16); +} + +void SQ_ImageProperties::destroy() +{ +#ifdef SQ_HAVE_KEXIF + SQ_Config::instance()->setGroup("GL view"); + SQ_Config::instance()->writeEntry("exifmode", exifMode); +#endif + + delete copyall; + delete copyentry; + delete copy; + delete menu; +} + +void SQ_ImageProperties::setParams(TQStringList &l) +{ + setFileParams(); + + TQStringList::Iterator it = l.begin(); + textType->setText(*it); ++it; + textDimensions->setText(*it); ++it; + textBpp->setText(*it); ++it; + textColorModel->setText(*it); ++it; + textCompression->setText(*it); ++it; + textUncompressed->setText(*it); ++it; + textRatio->setText(*it); ++it; + textInterlaced->setText(*it); ++it; + int errors = (*it).toInt(); ++it; + textFrames->setText(*it); ++it; + textFrame->setText(*it); ++it; + TQString s = TQString::fromLatin1("%1").arg(i18n("1 error", "%n errors", errors)); + textStatus->setText((errors)?s:TQString()); + textStatusIcon->setPixmap((errors)?error:ok); + + s = TQString::fromLatin1("%1%2").arg(*it).arg(i18n(" ms.")); + textDelay->setText(s); +} + +void SQ_ImageProperties::setURL(const KURL &_url) +{ + url = _url; +} + +void SQ_ImageProperties::setFileParams() +{ + TDEIO::Job *stjob = TDEIO::stat(url, false); + connect(stjob, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotStatResult(TDEIO::Job *))); + +#ifdef SQ_HAVE_KEXIF + SQ_Config::instance()->setGroup("GL view"); + exifMode = SQ_Config::instance()->readNumEntry("exifmode", 0); + + TQWidget *tabWidgetEXIF = new TQWidget(tabWidget, "tabWidgetEXIF"); + tabWidget->addTab(tabWidgetEXIF, i18n("EXIF")); + TQGridLayout *pageLayout6 = new TQGridLayout(tabWidgetEXIF, 2, 1, 11, 6, "tabWidgetEXIFLayout"); + + TQButtonGroup *gr = new TQButtonGroup(tabWidgetEXIF, "EXIF mode"); + gr->setFrameShape(TQFrame::NoFrame); + gr->setExclusive(true); + connect(gr, TQ_SIGNAL(clicked(int)), this, TQ_SLOT(slotModeClicked(int))); + + TQGridLayout *pageLayoutGR = new TQGridLayout(gr, 1, 3, 0, -1, "tabWidgetEXIFGRLayout"); + + TQPushButton *mode1 = new TQPushButton(i18n("Simple"), gr, "mode1"); + mode1->setToggleButton(true); + + TQPushButton *mode2 = new TQPushButton(i18n("Full"), gr, "mode2"); + mode2->setToggleButton(true); + + TQSpacerItem *spacer = new TQSpacerItem(15, 1, TQSizePolicy::Expanding, TQSizePolicy::Minimum); + + // create KEXIF widget and load metadata from file + KExifWidget *kew1 = new KExifWidget(tabWidgetEXIF); + kew1->loadFile(file); + + // hack to workaround poor libkexif API + TQObjectList *ch = const_cast<TQObjectList *>(kew1->children()); + for(TQObjectList::iterator it = ch->begin();it != ch->end();++it) + { + if((*it)->inherits("TQListView")) + { + TQListView *l = dynamic_cast<TQListView *>(*it); + TQWidget *w = tabWidget->page(3); + + if(l && w && !l->childCount()) + tabWidget->changeTab(w, i18n("EXIF (no)")); + + break; + } + } + + // set proper button on + if(exifMode) + { + mode2->setOn(true); + kew1->setMode(KExifWidget::FULL); + } + else + { + mode1->setOn(true); + kew1->setMode(KExifWidget::SIMPLE); + } + + // finally, add all widgets to layouts + pageLayoutGR->addWidget(mode1, 0, 0); + pageLayoutGR->addWidget(mode2, 0, 1); + pageLayoutGR->addItem(spacer, 0, 2); + + pageLayout6->addWidget(gr, 0, 0); + pageLayout6->addWidget(kew1, 1, 0); + kew = kew1; +#endif +} + +void SQ_ImageProperties::setMetaInfo(TQValueVector<TQPair<TQString,TQString> > meta ) +{ + TQListViewItem *after = 0, *item; + + TQValueVector<TQPair<TQString,TQString> >::iterator itEnd = meta.end(); + + for(TQValueVector<TQPair<TQString,TQString> >::iterator it = meta.begin();it != itEnd;++it) + { + if(after) + item = new TQListViewItem(listMeta, after, (*it).first+TQString::fromLatin1(" "), (*it).second.replace(TQChar('\n'), TQChar(' '))); + else + after = item = new TQListViewItem(listMeta, (*it).first+TQString::fromLatin1(" "), (*it).second.replace(TQChar('\n'), TQChar(' '))); + + listMeta->insertItem(item); + } + + if(!listMeta->childCount()) + { + listMeta->header()->hide(); + + TQWidget *w = tabWidget->page(2); + + if(w) + tabWidget->changeTab(w, i18n("Metadata (no)")); + } +} + +void SQ_ImageProperties::slotContextMenu( TQListViewItem *item, const TQPoint &p, int z1 ) +{ + if(item) + { + data = item; + z = z1; + menu->exec(p); + } +} + +void SQ_ImageProperties::slotCopyString() +{ + TQApplication::clipboard()->setText(data->text(z), TQClipboard::Clipboard); +} + +void SQ_ImageProperties::slotCopyAll() +{ + if(!data) + return; + + TQString app; + TQListViewItem *item = listMeta->firstChild(); + + for(;item;item = item->itemBelow()) + { + app.append(item->text(0) + "\n" + item->text(1) + "\n"); + } + + TQApplication::clipboard()->setText(app, TQClipboard::Clipboard); +} + +void SQ_ImageProperties::slotCopyEntry() +{ + if(!data) + return; + + TQString app = data->text(0) + "\n" + data->text(1) + "\n"; + + TQApplication::clipboard()->setText(app, TQClipboard::Clipboard); +} + +void SQ_ImageProperties::slotModeClicked(int id) +{ +// change mode: simple or full +#ifdef SQ_HAVE_KEXIF + exifMode = id; + static_cast<KExifWidget *>(kew)->setMode(id ? KExifWidget::FULL : KExifWidget::SIMPLE); +#endif +} + +void SQ_ImageProperties::slotStatResult(TDEIO::Job *job) +{ + if(!job->error()) + { + TDEIO::UDSEntry entry = static_cast<TDEIO::StatJob*>(job)->statResult(); + KFileItem fi(entry, url); + + KURL t = url; + t.cd(".."); + lineDirectory->setText(t.isLocalFile() ? t.path() : t.prettyURL()); + lineFile->setText(fi.name()); + + textSize->setText(TDEIO::convertSize(fi.size())); + textOwner->setText(TQString("%1").arg(fi.user())); + textGroup->setText(TQString("%1").arg(fi.group())); + textPermissions->setText(fi.permissionsString()); + + TQDateTime abs; + abs.setTime_t(fi.time(TDEIO::UDS_CREATION_TIME)); + textCreated->setText(abs.toString("dd/MM/yyyy hh:mm:ss")); + abs.setTime_t(fi.time(TDEIO::UDS_ACCESS_TIME)); + textLastRead->setText(abs.toString("dd/MM/yyyy hh:mm:ss")); + abs.setTime_t(fi.time(TDEIO::UDS_MODIFICATION_TIME)); + textLastMod->setText(abs.toString("dd/MM/yyyy hh:mm:ss")); + } +} + +// set local file for KEXIF +void SQ_ImageProperties::setFile(const TQString &_file) +{ + file = _file; +} diff --git a/src/ksquirrelpart/sq_label.cpp b/src/ksquirrelpart/sq_label.cpp new file mode 100644 index 0000000..a55a6eb --- /dev/null +++ b/src/ksquirrelpart/sq_label.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + sq_label.cpp - description + ------------------- + begin : June 10 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <tqpainter.h> + +#include "sq_label.h" + +#define MARGIN 15 + +SQ_Label::SQ_Label(TQWidget *parent, const char *name) : TQWidget(parent, name), single(false) +{} + +SQ_Label::~SQ_Label() +{} + +void SQ_Label::paintEvent(TQPaintEvent *) +{ + if((single && ltext.isEmpty() && rtext.isEmpty()) || (!single && ltext.isEmpty())) + return; + + TQPainter paint(this); + + TQFont font = paint.font(); + font.setBold(true); + font.setPointSize(10); + paint.setFont(font); + + if(!single) + { + paint.translate((width() + paint.fontMetrics().height()) / 2, height()); + paint.rotate(-90); + paint.drawText(MARGIN, 0, ltext); + + paint.translate(height() - paint.fontMetrics().width(rtext), 0); + paint.drawText(-MARGIN, 0, rtext); + } + else + { + paint.translate((width() + paint.fontMetrics().height()) / 2, + (height() + paint.fontMetrics().width(ltext)) / 2); + paint.rotate(-90); + paint.drawText(0, 0, ltext); + } +} + +void SQ_Label::setText(const TQString <, const TQString &rt) +{ + ltext = lt; + rtext = rt; + + update(); +} + +void SQ_Label::setText(const TQString <) +{ + ltext = lt; + + update(); +} + +void SQ_Label::setSingle(bool s) +{ + single = s; +} diff --git a/src/ksquirrelpart/sq_label.h b/src/ksquirrelpart/sq_label.h new file mode 100644 index 0000000..6d0edd5 --- /dev/null +++ b/src/ksquirrelpart/sq_label.h @@ -0,0 +1,41 @@ +/*************************************************************************** + sq_label.h - description + ------------------- + begin : June 10 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_LABEL_H +#define SQ_LABEL_H + +#include <tqwidget.h> + +class SQ_Label : public TQWidget +{ + public: + SQ_Label(TQWidget *parent = 0, const char *name = 0); + ~SQ_Label(); + + void setText(const TQString <, const TQString &rt); + void setText(const TQString <); + void setSingle(bool s); + + protected: + void paintEvent(TQPaintEvent *); + + private: + TQString ltext, rtext; + bool single; +}; + +#endif diff --git a/src/ksquirrelpart/sq_library.h b/src/ksquirrelpart/sq_library.h new file mode 100644 index 0000000..cf350d6 --- /dev/null +++ b/src/ksquirrelpart/sq_library.h @@ -0,0 +1,97 @@ +/*************************************************************************** + sq_library.h - description + ------------------- + begin : 27 2005 + copyright : (C) 2005 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_LIBRARY_H +#define SQ_LIBRARY_H + +#include <tqstring.h> +#include <tqregexp.h> +#include <tqpixmap.h> + +#include <ksquirrel-libs/fmt_defs.h> +#include <ksquirrel-libs/settings.h> + +class TQLibrary; + +class KTempFile; + +class fmt_codec_base; + +/* + * SQ_LIBRARY represents a library. It contains all information + * needed by other classes, e.g. pointer to codec, mime image, + * version string, filter string, etc. + * + * Used by SQ_LibraryHandler. + */ + +struct SQ_LIBRARY +{ + SQ_LIBRARY() : lib(0), codec(0), codec_il(0), tmp(0), tmp_il(0) + {} + + // pointer to library + TQLibrary *lib; + + // path to a library on disk + TQString libpath; + + // converted regular expression + TQRegExp regexp; + + // filter for a filemanager + TQString filter; + + // path to config file (.ui) + TQString config; + + fmt_settings settings; + + // regular expression as string + TQString regexp_str; + + TQString mimetype; + + bool mime_multi; + + // information on codec + TQString quickinfo; + + // codec's version + TQString version; + + // pointer to a codec + fmt_codec_base *codec, *codec_il; + + // 'create' and 'destroy' functions. + // should exist in library! + fmt_codec_base* (*codec_create)(); + void (*codec_destroy)(fmt_codec_base*); + + TQPixmap mime; + + // options for writers. + fmt_writeoptionsabs opt; + + bool writestatic, writeanimated; + bool readable; + bool canbemultiple, needtempfile; + + KTempFile *tmp, *tmp_il; +}; + +#endif diff --git a/src/ksquirrelpart/sq_libraryhandler.cpp b/src/ksquirrelpart/sq_libraryhandler.cpp new file mode 100644 index 0000000..3b6cf2c --- /dev/null +++ b/src/ksquirrelpart/sq_libraryhandler.cpp @@ -0,0 +1,582 @@ +/*************************************************************************** + sq_libraryhandler.cpp - description + ------------------- + begin : Mar 5 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqlibrary.h> +#include <tqfileinfo.h> +#include <tqstringlist.h> +#include <tqfile.h> +#include <tqdir.h> + +#include <kstringhandler.h> +#include <tdetempfile.h> +#include <tdeconfig.h> +#include <tdelocale.h> +#include <kdebug.h> +#include <kurl.h> +#include <kmimetype.h> + +#include "sq_libraryhandler.h" +#include "sq_config.h" + +#include <ksquirrel-libs/fmt_codec_base.h> + +#include <iostream> +#include <iomanip> + +#if !defined(QT_STRINGIFY) +# define QT_STRINGIFY2(x) #x +# define QT_STRINGIFY(x) QT_STRINGIFY2(x) +#endif + +static const int buffer_size = 10; + +SQ_LibraryHandler * SQ_LibraryHandler::m_instance = 0; + +// SQ_LibraryHandler +SQ_LibraryHandler::SQ_LibraryHandler(TQObject *parent) + : TQObject(parent), TQValueVector<SQ_LIBRARY>() +{ + m_instance = this; + + kdDebug() << "+SQ_LibraryHandler" << endl; + + tdeconf = new TDEConfig("ksquirrel-codec-settings"); + + load(); +} + +SQ_LibraryHandler::~SQ_LibraryHandler() +{ + clear(); + + delete tdeconf; + + kdDebug() << "-SQ_LibraryHandler" << endl; +} + +/* + * Find appropriate SQ_LIBRARY by filename. If + * not found, return NULL. + */ +SQ_LIBRARY* SQ_LibraryHandler::libraryForFile(const KURL &url) +{ + KMimeType::Ptr mime = KMimeType::findByURL(url); + + iterator itEnd = end(); + + SQ_LIBRARY *l = 0; + + // go through array and compare names + for(iterator it = begin();it != itEnd;++it) + { + if((*it).mime_multi) + { + if((*it).mimetype.find(mime->name()) != -1) + { + l = &(*it); + break; + } + } + else if((*it).mimetype == mime->name()) + { + l = &(*it); + break; + } + } + +#if 0 + if(l) + kdDebug() << KStringHandler::lsqueeze(url.prettyURL()) + << "\" => " + << l->quickinfo + << endl; +#endif + + return l; +} + +SQ_LIBRARY* SQ_LibraryHandler::libraryForFile(const TQString &path) +{ + KURL u; + u.setPath(path); + + return libraryForFile(u); +} + +/* + * Get all filters as one string. + */ +TQString SQ_LibraryHandler::allFiltersString() const +{ + TQString ret; + + const_iterator itEnd = end(); + + // construct string + for(const_iterator it = begin();it != itEnd;++it) + { + if(!(*it).filter.isEmpty()) + ret = ret + (*it).filter + ' '; + } + + return ret; +} + +TQString SQ_LibraryHandler::allFiltersFileDialogString(bool r, bool allfiles) const +{ + TQString ret; + + const_iterator itEnd = end(); + + // construct string + for(const_iterator it = begin();it != itEnd;++it) + { + if(!r) + if((*it).writestatic) + ret = ret + (*it).filter + '|' + (*it).quickinfo + '\n'; + else; + else if((*it).readable) + ret = ret + (*it).filter + '|' + (*it).quickinfo + '\n'; + } + + return allfiles ? (ret + "*.*|" + i18n("All files")) : ret.left(ret.length() - 1); +} + +/* + * Fill 'filters' with all found filters, and + * 'quick' with appropriate information. + */ +void SQ_LibraryHandler::allFilters(TQStringList &filters, TQStringList &quick) const +{ + // clear rubbish + filters.clear(); + quick.clear(); + + // no found libraries ? + if(empty()) + return; + + const_iterator itEnd = end(); + + // go through array and fill TQStringLists + for(const_iterator it = begin();it != itEnd;++it) + if(!(*it).filter.isEmpty()) + { + filters.append((*it).filter); + quick.append((*it).quickinfo); + } +} + +void SQ_LibraryHandler::allWritableFilters(TQStringList &filters, TQStringList &quick) const +{ + // clear rubbish + filters.clear(); + quick.clear(); + + // no libraries ? + if(empty()) + return; + + const_iterator itEnd = end(); + + // go through array and fill TQStringLists + for(const_iterator it = begin();it != itEnd;++it) + if((*it).writestatic && !(*it).filter.isEmpty()) + { + filters.append((*it).filter); + quick.append((*it).quickinfo); + } +} + +/* + * Remove and unload all libraries. + */ +void SQ_LibraryHandler::clear() +{ + kdDebug() << "SQ_LibraryHandler::clear()" << endl; + + iterator itEnd = end(); + + // unload libraries on clear() + for(iterator it = begin();it != itEnd;++it) + { + writeSettings(&(*it)); + + // delete temp file + if((*it).needtempfile) + { + delete (*it).tmp_il; + delete (*it).tmp; + } + + (*it).codec_destroy((*it).codec_il); + (*it).codec_destroy((*it).codec); + delete (*it).lib; + (*it).lib = 0; + } + + TQValueVector<SQ_LIBRARY>::clear(); +} + +/* + * Add new libraries. + */ +void SQ_LibraryHandler::add(TQStringList &foundLibraries) +{ + codec_options o; + + TQStringList::iterator itEnd = foundLibraries.end(); + + for(TQStringList::iterator it = foundLibraries.begin();it != itEnd;++it) + { + TQFileInfo ff(*it); + + SQ_LIBRARY libtmp; + + // create TQLibrary object + libtmp.lib = new TQLibrary(*it); + libtmp.libpath = *it; + libtmp.lib->load(); + + // resolve create() and destroy() functions + libtmp.codec_create = (fmt_codec_base*(*)())(libtmp.lib)->resolve(TQString::fromLatin1("codec_create")); + libtmp.codec_destroy = (void (*)(fmt_codec_base*))(libtmp.lib)->resolve(TQString::fromLatin1("codec_destroy")); + + // couldn't resolve - corrupted library ? + if(!libtmp.codec_create || !libtmp.codec_destroy) + { + libtmp.lib->unload(); + delete libtmp.lib; + } + else + { + // create codec ! + fmt_codec_base *codeK = libtmp.codec_create(); + + // read options + codeK->options(&o); + + TQString q = o.name; + + // Yet unknown library ? + if(!alreadyInMap(q)) + { + libtmp.mime = TQPixmap(reinterpret_cast<const char **>(o.pixmap)); + libtmp.mimetype = o.mimetype; + libtmp.mime_multi = libtmp.mimetype.find(';') != -1; + libtmp.quickinfo = q; + libtmp.filter = o.filter; + libtmp.version = o.version; + libtmp.regexp_str = o.mime; + libtmp.config = o.config; + libtmp.regexp.setPattern(libtmp.regexp_str); + libtmp.regexp.setCaseSensitive(true); + libtmp.writestatic = o.writestatic; + libtmp.writeanimated = o.writeanimated; + libtmp.readable = o.readable; + libtmp.canbemultiple = o.canbemultiple; + libtmp.needtempfile = o.needtempfile; + libtmp.tmp = 0; + + libtmp.codec_il = libtmp.codec_create(); + + if(libtmp.needtempfile) + { + libtmp.tmp = new KTempFile; + libtmp.tmp->setAutoDelete(true); + libtmp.tmp->close(); + codeK->settempfile(libtmp.tmp->name().ascii()); + + libtmp.tmp_il = new KTempFile; + libtmp.tmp_il->setAutoDelete(true); + libtmp.tmp_il->close(); + libtmp.codec_il->settempfile(libtmp.tmp_il->name().ascii()); + } + + if(libtmp.writestatic) + codeK->getwriteoptions(&libtmp.opt); + + libtmp.codec = codeK; + + readSettings(&libtmp); + + append(libtmp); + } + else // already known library + { + // destroy codec + libtmp.codec_destroy(codeK); + + // unload library + libtmp.lib->unload(); + + delete libtmp.lib; + } + } + } + + // print some information + dump(); +} + +/* + * Is library named 'quick' already been handled ? + */ +bool SQ_LibraryHandler::alreadyInMap(const TQString &quick) const +{ + const_iterator itEnd = end(); + + // go through array and find 'quick' + for(const_iterator it = begin();it != itEnd;++it) + if((*it).quickinfo == quick) + return true; + + return false; +} + +/* + * Print some information on found libraries. + */ +void SQ_LibraryHandler::dump() const +{ + std::cerr << "SQ_LibraryHandler: memory dump (total " << count() << ")" << endl; + + const_iterator itEnd = end(); + + std::cerr.setf(ios::left); + + for(const_iterator it = begin();it != itEnd;++it) + { + std::cerr << std::setw(30) + << KStringHandler::csqueeze(TQFileInfo((*it).libpath).fileName(), 30) + << std::setw(0) + << " [" + << KStringHandler::rsqueeze((*it).quickinfo, 45) + << "]" + << endl; + } +} + +/* + * Does any of found libraries handle given extension ? + */ +bool SQ_LibraryHandler::knownExtension(const TQString &ext) +{ + iterator itEnd = end(); + + // go through array and compare extensions + for(iterator it = begin();it != itEnd;++it) + { + if((*it).filter.contains(ext, false)) + return true; + } + + return false; +} + +/* + * Find appropriate SQ_LIBRARY by its name. If + * not found, return NULL. + * + * Name is a string, returned by fmt_quickinfo() + */ +SQ_LIBRARY* SQ_LibraryHandler::libraryByName(const TQString &name) +{ + SQ_LIBRARY *l; + + iterator itEnd = end(); + + // go through array and compare names + for(iterator it = begin();it != itEnd;++it) + { + l = &(*it); + + if(l->quickinfo == name) + return l; + } + + return 0; +} + +void SQ_LibraryHandler::writeSettings(SQ_LIBRARY *lib) +{ + // no config - no settings + if(lib->config.isEmpty()) + return; + + tdeconf->setGroup(lib->quickinfo); + + fmt_settings::iterator itEnd = lib->settings.end(); + + TQString k; + + for(fmt_settings::iterator it = lib->settings.begin();it != itEnd;++it) + { + k = (*it).first; + + if((*it).second.type == settings_value::v_bool) // boolean + { + k.prepend("b"); + tdeconf->writeEntry(k, (*it).second.bVal); + } + else if((*it).second.type == settings_value::v_int) // integer + { + k.prepend("i"); + tdeconf->writeEntry(k, (*it).second.iVal); + } + else if((*it).second.type == settings_value::v_double) // double + { + k.prepend("d"); + tdeconf->writeEntry(k, (*it).second.dVal); + } + else // string + { + k.prepend("s"); + tdeconf->writeEntry(k, (*it).second.sVal); + } + } +} + +void SQ_LibraryHandler::readSettings(SQ_LIBRARY *lib) +{ + // no config - no settings + if(lib->config.isEmpty()) + return; + + TQMap<TQString, TQString> map = tdeconf->entryMap(lib->quickinfo); + + if(!map.size()) + { + lib->codec->fill_default_settings(); + lib->settings = lib->codec->settings(); + return; + } + + TQMap<TQString, TQString>::iterator mapEnd = map.end(); + fmt_settings &sett = lib->settings; + TQString d, k; + settings_value val; + + for(TQMap<TQString, TQString>::iterator mapIt = map.begin();mapIt != mapEnd;++mapIt) + { + k = mapIt.key(); + d = mapIt.data(); + + if(k.startsWith(TQChar('i'))) + { + val.type = settings_value::v_int; + val.iVal = d.toInt(); + } + else if(k.startsWith(TQChar('d'))) + { + val.type = settings_value::v_double; + val.dVal = d.toDouble(); + } + else if(k.startsWith(TQChar('b'))) + { + val.type = settings_value::v_bool; + val.bVal = (d == "true"); + } + else // all other values are treated as strings + { + val.type = settings_value::v_string; + val.sVal = d.ascii(); + } + + k = k.right(k.length() - 1); + sett[k.ascii()] = val; + } + + lib->codec->set_settings(sett); +} + +void SQ_LibraryHandler::reload() +{ + clear(); + load(); +} + +void SQ_LibraryHandler::load() +{ + TQStringList libs; + + TQDir dir(QT_STRINGIFY(SQ_KLIBS), TQString(), TQDir::Unsorted, TQDir::Files); + + const TQFileInfoList *list = dir.entryInfoList(); + + if(list) + { + TQFileInfoListIterator it(*list); + TQFileInfo *fi; + + while((fi = it.current()) != 0) + { + libs.append(fi->absFilePath()); + ++it; + } + } + + // just show dump, if no libs were found + add(libs); +} + +SQ_LibraryHandler::Support SQ_LibraryHandler::maybeSupported(const KURL &u, const TQString &mime) const +{ + const_iterator itEnd = constEnd(); + + SQ_Config::instance()->setGroup("Main"); + bool treat = SQ_Config::instance()->readBoolEntry("treat", true); + + // we can determine mimetype by hand or use "mime" + TQString mimeDet = mime.isEmpty() ? KMimeType::findByURL(u)->name() : mime; + + // mimetype by magic is not determined automatically + // for non-local urls - we may support this file type or may not + // (we don't know exactly at this moment) + if(!u.isLocalFile() && mimeDet == KMimeType::defaultMimeType()) + return (treat ? SQ_LibraryHandler::No : SQ_LibraryHandler::Maybe); + + // go through array and compare mimetype names + for(const_iterator it = constBegin();it != itEnd;++it) + { + if((*it).mime_multi) + { + if((*it).mimetype.find(mimeDet, 0, false) != -1) + return SQ_LibraryHandler::Yes; + } + else if((*it).mimetype == mimeDet) // don't waste CPU time with find() + return SQ_LibraryHandler::Yes; + } + + // we don't know about given mimetype + return SQ_LibraryHandler::No; +} + +void SQ_LibraryHandler::sync() +{ + iterator itEnd = end(); + + // unload libraries on clear() + for(iterator it = begin();it != itEnd;++it) + writeSettings(&(*it)); + + tdeconf->sync(); +} diff --git a/src/ksquirrelpart/sq_libraryhandler.h b/src/ksquirrelpart/sq_libraryhandler.h new file mode 100644 index 0000000..8a3b25d --- /dev/null +++ b/src/ksquirrelpart/sq_libraryhandler.h @@ -0,0 +1,128 @@ +/*************************************************************************** + sq_libraryhandler.h - description + ------------------- + begin : Mar 5 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_LIBRARY_HANDLER_H +#define SQ_LIBRARY_HANDLER_H + +#include <tqvaluevector.h> +#include <tqdatetime.h> +#include <tqobject.h> + +#include "sq_library.h" + +class TQStringList; + +class TDEConfig; +class KURL; + +/* + * SQ_LibraryHandler is a library manager. It's the main class + * in library loading mechanizm. + */ + +class SQ_LibraryHandler : public TQObject, public TQValueVector<SQ_LIBRARY> +{ + public: + SQ_LibraryHandler(TQObject *parent = 0); + ~SQ_LibraryHandler(); + + enum Support { Maybe = 0, Yes, No }; + + /* + * Reload libraries from disk + */ + void reload(); + + void sync(); + + Support maybeSupported(const KURL &, const TQString& = TQString()) const; + + /* + * Find appropriate SQ_LIBRARY by filename. If + * not found, return NULL. + */ + SQ_LIBRARY* libraryForFile(const KURL &); + SQ_LIBRARY* libraryForFile(const TQString &); + + /* + * Find appropriate SQ_LIBRARY by its name. If + * not found, return NULL. + * + * Name is a string, returned by fmt_quickinfo() + */ + SQ_LIBRARY* libraryByName(const TQString &name); + + /* + * Does any of found libraries handle given extension ? + */ + bool knownExtension(const TQString &ext); + + /* + * Fill 'filters' with all found filters, and + * 'quick' with appropriate information. + */ + void allFilters(TQStringList &filters, TQStringList &quick) const; + + void allWritableFilters(TQStringList &filters, TQStringList &quick) const; + + /* + * Get all filters as one string. + */ + TQString allFiltersString() const; + + /* + * Filters as one string suitable for KFileDialogs. + * If r == true, return readable codecs + * If allfiles == true, append *.* to result + */ + TQString allFiltersFileDialogString(bool r, bool allfiles = true) const; + + /* + * Remove and unload all libraries. + */ + void clear(); + + /* + * Print some information on found libraries. + */ + void dump() const; + + static SQ_LibraryHandler* instance() { return m_instance; } + + private: + + void add(TQStringList &foundLibraries); + + /* + * Load libraries from disk. + */ + void load(); + /* + * Is library with name 'quick' already been handled ? + */ + bool alreadyInMap(const TQString &quick) const; + + void writeSettings(SQ_LIBRARY *lib); + void readSettings(SQ_LIBRARY *lib); + + private: + TDEConfig *tdeconf; + + static SQ_LibraryHandler *m_instance; +}; + +#endif diff --git a/src/ksquirrelpart/sq_popupmenu.cpp b/src/ksquirrelpart/sq_popupmenu.cpp new file mode 100644 index 0000000..553d9ef --- /dev/null +++ b/src/ksquirrelpart/sq_popupmenu.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + sq_popupmenu.cpp - description + ------------------- + begin : ??? June 3 2006 + copyright : (C) 2006 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sq_popupmenu.h" + +SQ_PopupMenu::SQ_PopupMenu(TQWidget *parent, const char *name) + : TDEPopupMenu(parent, name), title(0) +{} + +SQ_PopupMenu::~SQ_PopupMenu() +{} + +void SQ_PopupMenu::insertTitle(const TQString &t) +{ + title = TDEPopupMenu::insertTitle(t); +} + +void SQ_PopupMenu::changeTitle(const TQString &t) +{ + TDEPopupMenu::changeTitle(title, t); +} diff --git a/src/ksquirrelpart/sq_popupmenu.h b/src/ksquirrelpart/sq_popupmenu.h new file mode 100644 index 0000000..efc12f2 --- /dev/null +++ b/src/ksquirrelpart/sq_popupmenu.h @@ -0,0 +1,40 @@ +/*************************************************************************** + sq_popupmenu.h - description + ------------------- + begin : ??? June 3 2006 + copyright : (C) 2006 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_POPUPMENU_H +#define SQ_POPUPMENU_H + +#include <tdepopupmenu.h> + +/** + *@author Baryshev Dmitry + */ + +class SQ_PopupMenu : public TDEPopupMenu +{ + public: + SQ_PopupMenu(TQWidget *parent = 0, const char *name = 0); + ~SQ_PopupMenu(); + + void insertTitle(const TQString &t); + void changeTitle(const TQString &t); + + private: + int title; +}; + +#endif diff --git a/src/ksquirrelpart/sq_utils.cpp b/src/ksquirrelpart/sq_utils.cpp new file mode 100644 index 0000000..20eea42 --- /dev/null +++ b/src/ksquirrelpart/sq_utils.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** + sq_utils.cpp - description + ------------------- + begin : Thu Aug 2 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqstring.h> + +#include <ksquirrel-libs/fmt_defs.h> + +#include "sq_libraryhandler.h" +#include "sq_utils.h" + +#ifndef KSQUIRREL_PART +#include <kurl.h> +#include "sq_imageloader.h" +#include "sq_thumbnailinfo.h" +#include "sq_thumbnailsize.h" +#endif + +#ifdef SQ_HAVE_KEXIF +#include <libkexif/kexifdata.h> +#endif + +void SQ_Utils::exifRotate(const TQString &file, TQImage &im, int o) +{ +#ifdef SQ_HAVE_KEXIF + im = im.xForm(SQ_Utils::exifGetMatrix(file, o)); +#endif +} + +TQWMatrix SQ_Utils::exifGetMatrix(const TQString &file, int o) +{ + TQWMatrix matrix; + +#ifdef SQ_HAVE_KEXIF + int O; + + if(o == -1) + { + KExifData data; + data.readFromFile(file); + O = data.getImageQt::Orientation(); + } + else + O = o; + + switch(O) + { + case KExifData::HFLIP: matrix.scale(-1,1); break; + case KExifData::ROT_180: matrix.rotate(180); break; + case KExifData::VFLIP: matrix.scale(1,-1); break; + case KExifData::ROT_90_HFLIP: matrix.scale(-1,1); matrix.rotate(90); break; + case KExifData::ROT_90: matrix.rotate(90); break; + case KExifData::ROT_90_VFLIP: matrix.scale(1,-1); matrix.rotate(90); break; + case KExifData::ROT_270: matrix.rotate(270); break; + + // normal rotation or unspecified + default: ; + } + +#endif + + return matrix; +} + +TQImage SQ_Utils::scaleImage(unsigned char *im, int w, int h, int fitwithin) +{ + if(w <= fitwithin && h <= fitwithin) + { + TQImage scaled(im, w, h, 32, 0, 0, TQImage::LittleEndian); + scaled.setAlphaBuffer(true); + return scaled.copy(); + } + + TQImage orig(im, w, h, 32, 0, 0, TQImage::LittleEndian); + orig.setAlphaBuffer(true); + + // return scaled image + return SQ_Utils::scale(orig, fitwithin, fitwithin, SQ_Utils::SMOOTH_FAST, TQImage::ScaleMin); +} + +#ifndef KSQUIRREL_PART +bool SQ_Utils::loadThumbnail(const KURL &pixPath, SQ_Thumbnail &t) +{ + SQ_LIBRARY *lib = 0; + +#ifdef SQ_HAVE_KEXIF + lib = SQ_LibraryHandler::instance()->libraryForFile(pixPath.path()); + bool th = false; + + if(lib) + { + KExifData data; + data.readFromFile(pixPath.path()); + TQImage im = data.getThumbnail(); + + if(!im.isNull()) + { + SQ_Utils::exifRotate(TQString(), im, data.getImageQt::Orientation()); + + th = true; + t.w = 0; + t.h = 0; + t.mime = lib->mime; + + TQString w, h; + w = im.text("Thumb::Image::Width"); + h = im.text("Thumb::Image::Height"); + t.w = w.toInt(); + t.h = h.toInt(); + + if(!t.w || !t.h) + SQ_ImageLoader::instance()->tasteImage(pixPath.path(), &t.w, &t.h, lib); + + t.thumbnail = SQ_Utils::scaleImage((unsigned char *)im.bits(), im.width(), + im.height(), SQ_ThumbnailSize::biggest()); + t.thumbnail = t.thumbnail.swapRGB(); + } + } + else + return false; + + // thumbnail loaded - nothing to do, + // or load thumbnail by hands otherwise. + if(th) + return true; +#endif + + fmt_info *finfo; + + RGBA *all; + + bool b = SQ_ImageLoader::instance()->loadImage(pixPath.path(), SQ_CodecSettings::ThumbnailLoader); + + finfo = SQ_ImageLoader::instance()->info(); + all = SQ_ImageLoader::instance()->bits(); + + // memory allocation failed in SQ_ImageLoader::loadImage() + if(!all) + return false; + + // another error occured... + if(!b) + { + // if our image is partially corrupted - show it. The image + // is partially corrupted, if number of errors < number of scanlines + // and at least one page was loaded. + if(!finfo->image.size() + || (SQ_ImageLoader::instance()->errors() == finfo->image[0].h && finfo->image.size() == 1)) + { + SQ_ImageLoader::instance()->cleanup(); + return false; + } + } + + if(!lib) lib = SQ_LibraryHandler::instance()->libraryForFile(pixPath.path()); + + t.w = finfo->image[0].w; + t.h = finfo->image[0].h; + t.mime = lib->mime; + + t.thumbnail = SQ_Utils::scaleImage((unsigned char *)all, finfo->image[0].w, + finfo->image[0].h, SQ_ThumbnailSize::biggest()); + + SQ_ImageLoader::instance()->cleanup(); + + // finally, rotate thumbnail using EXIF + SQ_Utils::exifRotate(pixPath.path(), t.thumbnail); + + return true; +} +#endif diff --git a/src/ksquirrelpart/sq_utils.h b/src/ksquirrelpart/sq_utils.h new file mode 100644 index 0000000..6d92104 --- /dev/null +++ b/src/ksquirrelpart/sq_utils.h @@ -0,0 +1,63 @@ +/*************************************************************************** + sq_utils.h - description + ------------------- + begin : Thu Aug 2 2007 + copyright : (C) 2007 by Baryshev Dmitry + email : ksquirrel.iv@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SQ_UTILS_H +#define SQ_UTILS_H + +#include <tqimage.h> +#include <tqwmatrix.h> + +class KURL; + +class TQString; + +class SQ_Thumbnail; + +/* + * Helper class for SQ_GLWidget and SQ_ThumbnailLoadJob: + * + * thumbnail loader, rotater, mmx scaler + */ + +namespace SQ_Utils +{ + enum SmoothAlgorithm { SMOOTH_NONE, SMOOTH_FAST, SMOOTH_NORMAL, SMOOTH_BEST }; + + TQImage scale(const TQImage& image, int width, int height, + SmoothAlgorithm alg, TQImage::ScaleMode mode = TQImage::ScaleFree, double blur = 1.0); + + /* + * Scale given image to fit it within 'fitwithin' + */ + TQImage scaleImage(unsigned char *im, int w, int h, int fitwithin); + +#ifndef KSQUIRREL_PART + /* + * Create and save thumbnail for 'pixPath' + */ + bool loadThumbnail(const KURL &pixPath, SQ_Thumbnail&); +#endif + + /* + * determine EXIF rotation and rotate image if needed + */ + void exifRotate(const TQString &file, TQImage &i, int o = -1); + + TQWMatrix exifGetMatrix(const TQString &file, int o = -1); +}; + +#endif diff --git a/src/ksquirrelpart/sq_utils_asm_scale.S b/src/ksquirrelpart/sq_utils_asm_scale.S new file mode 100644 index 0000000..08b43da --- /dev/null +++ b/src/ksquirrelpart/sq_utils_asm_scale.S @@ -0,0 +1,810 @@ +#ifdef HAVE_X86_MMX + +#ifdef __EMX__ +/* Due to strange behaviour of as.exe we use this macros */ +/* For all OS/2 coders - please use PGCC to compile this code */ +#define PR_(foo) ___##foo +#define PT_(foo,func) ___##foo,func +#define SIZE(sym) \ + .___end_##sym:; \ + .size ___##sym,.___end_##sym-___##sym; \ + .align 8; +#else +#define PR_(foo) __##foo +#define PT_(foo,func) __##foo,func +#define SIZE(sym) \ + .__end_##sym:; \ + .size __##sym,.__end_##sym-__##sym; \ + .align 8; +#endif + +/*\ +|*| MMX assembly scaling routine for Imlib2 +|*| Written by Willem Monsuwe <willem@stack.nl> +\*/ + +.text + .align 8 +.globl PR_(mimageScale_mmx_AARGBA) +/* .type PT_(mimageScale_mmx_AARGBA,@function) */ + + +/*\ Prototype: __mimageScale_mmx_AARGBA(ImlibScaleInfo *isi, DATA32 *dest, +|*| int dxx, int dyy, int dx, int dy, int dw, int dh, int dow, int sow) +\*/ + +#define isi 8(%ebp) +#define dest 12(%ebp) +#define dxx 16(%ebp) +#define dyy 20(%ebp) +#define dx 24(%ebp) +#define dy 28(%ebp) +#define dw 32(%ebp) +#define dh 36(%ebp) +#define dow 40(%ebp) +#define sow 44(%ebp) + +/*\ Local variables that didn't fit in registers \*/ +#define y -4(%ebp) +#define yp -8(%ebp) +#define yap -12(%ebp) +#define xp -16(%ebp) +#define xap -20(%ebp) +#define Cx -24(%ebp) +#define Mx -28(%ebp) +#define Cy -32(%ebp) +#define My -36(%ebp) +#define sow_4 -40(%ebp) + +/*\ When %edx points to ImlibScaleInfo, these are the members \*/ +#define xpoints (%edx) +#define ypoints 4(%edx) +#define xapoints 8(%edx) +#define yapoints 12(%edx) +#define xup_yup 16(%edx) + +PR_(mimageScale_mmx_AARGBA): + pushl %ebp + movl %esp, %ebp + subl $40, %esp + pushl %ebx + pushl %ecx + pushl %edx + pushl %edi + pushl %esi + movl isi, %edx + + /*\ Check (dw > 0) && (dh > 0) \*/ + cmpl $0, dw + jle .scale_leave + cmpl $0, dh + jle .scale_leave + + /*\ X-based array pointers point to the end; we're looping up to 0 \*/ + /*\ %edi = dest + dow * dy + dx + dw \*/ + movl dow, %eax + imull dy, %eax + addl dx, %eax + addl dw, %eax + movl dest, %edi + leal (%edi, %eax, 4), %edi + /*\ xp = xpoints + dxx + dw \*/ + movl dxx, %ebx + addl dw, %ebx + movl xpoints, %eax + leal (%eax, %ebx, 4), %eax + movl %eax, xp + /*\ xap = xapoints + dxx + dw \*/ + movl xapoints, %eax + leal (%eax, %ebx, 4), %eax + movl %eax, xap + /*\ y = dh \*/ + movl dh, %eax + movl %eax, y + /*\ yp = ypoints + dyy \*/ + movl dyy, %ebx + movl ypoints, %eax + leal (%eax, %ebx, 4), %eax + movl %eax, yp + /*\ yap = yapoints + dyy \*/ + movl yapoints, %eax + leal (%eax, %ebx, 4), %eax + movl %eax, yap + + pxor %mm7, %mm7 + + /*\ Test xup bit \*/ + movl xup_yup, %eax + sarl $1, %eax + jnc .scale_x_down + +.scale_x_up: + /*\ Test yup bit \*/ + sarl $1, %eax + jnc .scale_x_up_y_down + + +/*\ Scaling up both ways \*/ + +.scale_x_up_y_up: + movl sow, %ebx + +.up_up_loop_y: + + /*\ x = -dw \*/ + movl dw, %ecx + negl %ecx + + /*\ %eax = *yap << 4 \*/ + movl yap, %eax + movl (%eax), %eax + sall $4, %eax + jz .up_up_yap_0 + movd %eax, %mm1 + punpcklwd %mm1, %mm1 + punpckldq %mm1, %mm1 + +.up_up_loop1_x: + /*\ %esi = *yp + xp[x] \*/ + movl yp, %eax + movl (%eax), %esi + movl xp, %eax + movl (%eax, %ecx, 4), %eax + leal (%esi, %eax, 4), %esi + + /*\ %eax = xap[x] << 4 \*/ + movl xap, %eax + movl (%eax, %ecx, 4), %eax + sall $4, %eax + jz .up_up_xap_0 + + /*\ %mm0 = xap[x] << 4 \*/ + movd %eax, %mm0 + punpcklwd %mm0, %mm0 + punpckldq %mm0, %mm0 + + /*\ Load and unpack four pixels in parralel + |*| %mm2 = ptr[0], %mm3 = ptr[1] + |*| %mm4 = ptr[sow], %mm5 = ptr[sow + 1] + \*/ + movq (%esi), %mm2 + movq (%esi, %ebx, 4), %mm4 + movq %mm2, %mm3 + movq %mm4, %mm5 + punpcklbw %mm7, %mm2 + punpcklbw %mm7, %mm4 + punpckhbw %mm7, %mm3 + punpckhbw %mm7, %mm5 + + /*\ X interpolation: r = l + (r - l) * xap \*/ + psubw %mm2, %mm3 + psubw %mm4, %mm5 + psllw $4, %mm3 + psllw $4, %mm5 + pmulhw %mm0, %mm3 + pmulhw %mm0, %mm5 + paddw %mm2, %mm3 + paddw %mm4, %mm5 + /*\ Now %mm3 = I(ptr[0], ptr[1]), %mm5 = I(ptr[sow], ptr[sow + 1]) \*/ + jmp .up_up_common +.up_up_xap_0: + /*\ Load and unpack two pixels + |*| %mm3 = ptr[0], %mm5 = ptr[sow] + \*/ + movd (%esi), %mm3 + movd (%esi, %ebx, 4), %mm5 + punpcklbw %mm7, %mm3 + punpcklbw %mm7, %mm5 +.up_up_common: + /*\ Y interpolation: d = u + (d - u) * yap \*/ + psubw %mm3, %mm5 + psllw $4, %mm5 + pmulhw %mm1, %mm5 + paddw %mm3, %mm5 + packuswb %mm5, %mm5 + movd %mm5, (%edi, %ecx, 4) + + /*\ while (++x) \*/ + incl %ecx + jnz .up_up_loop1_x + jmp .up_up_yap_end +.up_up_yap_0: + +.up_up_loop2_x: + /*\ %esi = *yp + xp[x] \*/ + movl yp, %eax + movl (%eax), %esi + movl xp, %eax + movl (%eax, %ecx, 4), %eax + leal (%esi, %eax, 4), %esi + + /*\ %eax = xap[x] << 4 \*/ + movl xap, %eax + movl (%eax, %ecx, 4), %eax + sall $4, %eax + jz .up_up_0 + + /*\ %mm0 = xap[x] << 4 \*/ + movd %eax, %mm0 + punpcklwd %mm0, %mm0 + punpckldq %mm0, %mm0 + + /*\ Load and unpack two pixels in parralel + |*| %mm2 = ptr[0], %mm3 = ptr[1] + \*/ + movq (%esi), %mm2 + movq %mm2, %mm3 + punpcklbw %mm7, %mm2 + punpckhbw %mm7, %mm3 + + /*\ X interpolation: r = l + (r - l) * xap \*/ + psubw %mm2, %mm3 + psllw $4, %mm3 + pmulhw %mm0, %mm3 + paddw %mm2, %mm3 + packuswb %mm3, %mm3 + movd %mm3, (%edi, %ecx, 4) + jmp .up_up_1 +.up_up_0: + /*\ dptr[x] = *sptr \*/ + movl (%esi), %eax + movl %eax, (%edi, %ecx, 4) +.up_up_1: + incl %ecx + jnz .up_up_loop2_x + +.up_up_yap_end: + /*\ dptr += dow \*/ + movl dow, %eax + leal (%edi, %eax, 4), %edi + /*\ yap++; yp++ \*/ + addl $4, yap + addl $4, yp + /*\ while (y--) \*/ + decl y + jnz .up_up_loop_y + + jmp .scale_leave + + +/*\ Scaling down vertically \*/ + +.scale_x_up_y_down: + /*\ sow_4 = sow * 4 \*/ + movl sow, %eax + sall $2, %eax + movl %eax, sow_4 + +.up_down_loop_y: + + /*\ Setup My and Cy \*/ + movl yap, %eax + movzwl (%eax), %ebx + movl %ebx, My + movzwl 2(%eax), %eax + movl %eax, Cy + + /*\ mm4 = Cy \*/ + movd %eax, %mm4 + punpcklwd %mm4, %mm4 + punpckldq %mm4, %mm4 + /*\ mm5 = My \*/ + movd %ebx, %mm5 + punpcklwd %mm5, %mm5 + punpckldq %mm5, %mm5 + + /*\ x = -dw \*/ + movl dw, %ecx + negl %ecx +.up_down_loop_x: + /*\ %esi = *yp + xp[x] \*/ + movl yp, %eax + movl (%eax), %esi + movl xp, %eax + movl (%eax, %ecx, 4), %eax + leal (%esi, %eax, 4), %esi + + movl %esi, %eax + /*\ v = (*p * My) >> 10 \*/ + movd (%eax), %mm0 + punpcklbw %mm7, %mm0 + psllw $6, %mm0 + pmulhw %mm5, %mm0 + + /*\ i = 0x4000 - My \*/ + movl $0x4000, %ebx + subl My, %ebx + jbe 5f + jmp 2f +1: + /*\ p += sow; v += (*p * Cy) >> 10 \*/ + addl sow_4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm4, %mm1 + paddw %mm1, %mm0 + + /*\ i -= Cy; while (i > Cy) \*/ + subl Cy, %ebx +2: + cmpl Cy, %ebx + jg 1b + + /*\ mm6 = i \*/ + movd %ebx, %mm6 + punpcklwd %mm6, %mm6 + punpckldq %mm6, %mm6 + + /*\ p += sow; v += (*p * i) >> 10 \*/ + addl sow_4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm6, %mm1 + paddw %mm1, %mm0 +5: + /*\ %eax = xap[x] << 5 \*/ + movl xap, %eax + movl (%eax, %ecx, 4), %eax + sall $5, %eax + jz 6f + /*\ mm3 = xap[x] << 5 \*/ + movd %eax, %mm3 + punpcklwd %mm3, %mm3 + punpckldq %mm3, %mm3 + + /*\ p + 1 \*/ + movl %esi, %eax + addl $4, %eax + /*\ vv = (*p * My) >> 10 \*/ + movd (%eax), %mm2 + punpcklbw %mm7, %mm2 + psllw $6, %mm2 + pmulhw %mm5, %mm2 + + /*\ i = 0x4000 - My \*/ + movl $0x4000, %ebx + subl My, %ebx + jbe 5f + jmp 2f +1: + /*\ p += sow; vv += (*p * Cy) >> 10 \*/ + addl sow_4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm4, %mm1 + paddw %mm1, %mm2 + + /*\ i -= Cy; while (i > Cy) \*/ + subl Cy, %ebx +2: + cmpl Cy, %ebx + jg 1b + + /*\ p += sow; v += (*p * i) >> 10 \*/ + addl sow_4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm6, %mm1 + paddw %mm1, %mm2 +5: + /*\ v = v + (vv - v) * xap \*/ + psubw %mm0, %mm2 + psllw $3, %mm2 + pmulhw %mm3, %mm2 + paddw %mm2, %mm0 +6: + /*\ dest[x] = v >> 4 \*/ + psrlw $4, %mm0 + packuswb %mm0, %mm0 + movd %mm0, (%edi, %ecx, 4) + + /*\ while (++x) \*/ + incl %ecx + jnz .up_down_loop_x + + /*\ dptr += dow \*/ + movl dow, %eax + leal (%edi, %eax, 4), %edi + /*\ yap++; yp++ \*/ + addl $4, yap + addl $4, yp + /*\ while (y--) \*/ + decl y + jnz .up_down_loop_y + + jmp .scale_leave + +.scale_x_down: + /*\ Test yup bit \*/ + sarl $1, %eax + jnc .scale_x_down_y_down + + +/*\ Scaling down horizontally \*/ + +.scale_x_down_y_up: + /*\ sow_4 = sow * 4 \*/ + movl sow, %eax + sall $2, %eax + movl %eax, sow_4 + +.down_up_loop_y: + + /*\ %eax = *yap << 5 \*/ + movl yap, %eax + movl (%eax), %eax + sall $5, %eax + /*\ mm3 = *yap << 5 \*/ + movd %eax, %mm3 + punpcklwd %mm3, %mm3 + punpckldq %mm3, %mm3 + + /*\ x = -dw \*/ + movl dw, %ecx + negl %ecx +.down_up_loop_x: + /*\ %esi = *yp + xp[x] \*/ + movl yp, %eax + movl (%eax), %esi + movl xp, %eax + movl (%eax, %ecx, 4), %eax + leal (%esi, %eax, 4), %esi + + /*\ Setup Mx and Cx \*/ + movl xap, %eax + movzwl (%eax, %ecx, 4), %ebx + movl %ebx, Mx + movzwl 2(%eax, %ecx, 4), %eax + movl %eax, Cx + + /*\ mm4 = Cx \*/ + movd %eax, %mm4 + punpcklwd %mm4, %mm4 + punpckldq %mm4, %mm4 + /*\ mm5 = Mx \*/ + movd %ebx, %mm5 + punpcklwd %mm5, %mm5 + punpckldq %mm5, %mm5 + + movl %esi, %eax + /*\ v = (*p * Mx) >> 10 \*/ + movd (%eax), %mm0 + punpcklbw %mm7, %mm0 + psllw $6, %mm0 + pmulhw %mm5, %mm0 + + /*\ i = 0x4000 - Mx \*/ + movl $0x4000, %ebx + subl Mx, %ebx + jbe 5f + jmp 2f +1: + /*\ p += sow; v += (*p * Cx) >> 10 \*/ + addl $4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm4, %mm1 + paddw %mm1, %mm0 + + /*\ i -= Cx; while (i > Cx) \*/ + subl Cx, %ebx +2: + cmpl Cx, %ebx + jg 1b + + /*\ mm6 = i \*/ + movd %ebx, %mm6 + punpcklwd %mm6, %mm6 + punpckldq %mm6, %mm6 + + /*\ p += sow; v += (*p * i) >> 10 \*/ + addl $4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm6, %mm1 + paddw %mm1, %mm0 +5: + movd %mm3, %eax + testl %eax, %eax + jz 6f + /*\ p + sow \*/ + movl %esi, %eax + addl sow_4, %eax + /*\ vv = (*p * Mx) >> 10 \*/ + movd (%eax), %mm2 + punpcklbw %mm7, %mm2 + psllw $6, %mm2 + pmulhw %mm5, %mm2 + + /*\ i = 0x4000 - Mx \*/ + movl $0x4000, %ebx + subl Mx, %ebx + jbe 5f + jmp 2f +1: + /*\ p += sow; vv += (*p * Cx) >> 10 \*/ + addl $4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm4, %mm1 + paddw %mm1, %mm2 + + /*\ i -= Cx; while (i > Cx) \*/ + subl Cx, %ebx +2: + cmpl Cx, %ebx + jg 1b + + /*\ p += sow; v += (*p * i) >> 10 \*/ + addl $4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $6, %mm1 + pmulhw %mm6, %mm1 + paddw %mm1, %mm2 +5: + /*\ v = v + (vv - v) * yap \*/ + psubw %mm0, %mm2 + psllw $3, %mm2 + pmulhw %mm3, %mm2 + paddw %mm2, %mm0 +6: + /*\ dest[x] = v >> 4 \*/ + psrlw $4, %mm0 + packuswb %mm0, %mm0 + movd %mm0, (%edi, %ecx, 4) + + /*\ while (++x) \*/ + incl %ecx + jnz .down_up_loop_x + + /*\ dptr += dow \*/ + movl dow, %eax + leal (%edi, %eax, 4), %edi + /*\ yap++; yp++ \*/ + addl $4, yap + addl $4, yp + /*\ while (y--) \*/ + decl y + jnz .down_up_loop_y + + jmp .scale_leave + + +/*\ Scaling down both ways \*/ + +.scale_x_down_y_down: + /*\ sow_4 = sow * 4 \*/ + movl sow, %eax + sall $2, %eax + movl %eax, sow_4 + +.down_down_loop_y: + + /*\ Setup My and Cy \*/ + movl yap, %eax + movzwl (%eax), %ebx + movl %ebx, My + movzwl 2(%eax), %eax + movl %eax, Cy + + /*\ x = -dw \*/ + movl dw, %ecx + negl %ecx +.down_down_loop_x: + /*\ %esi = *yp + xp[x] \*/ + movl yp, %eax + movl (%eax), %esi + movl xp, %eax + movl (%eax, %ecx, 4), %eax + leal (%esi, %eax, 4), %esi + + /*\ Setup Mx and Cx \*/ + movl xap, %eax + movzwl (%eax, %ecx, 4), %ebx + movl %ebx, Mx + movzwl 2(%eax, %ecx, 4), %eax + movl %eax, Cx + + /*\ mm3 = Cx \*/ + movd %eax, %mm3 + punpcklwd %mm3, %mm3 + punpckldq %mm3, %mm3 + /*\ mm5 = Mx \*/ + movd %ebx, %mm5 + punpcklwd %mm5, %mm5 + punpckldq %mm5, %mm5 + + /*\ p = sptr; v = (*p * Mx) >> 9 \*/ + movl %esi, %eax + movd (%eax), %mm0 + punpcklbw %mm7, %mm0 + psllw $7, %mm0 + pmulhw %mm5, %mm0 + + /*\ i = 0x4000 - Mx \*/ + movl $0x4000, %ebx + subl Mx, %ebx + jbe 5f + jmp 2f +1: + /*\ v += (*++p * Cx) >> 9 \*/ + addl $4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $7, %mm1 + pmulhw %mm3, %mm1 + paddw %mm1, %mm0 + + /*\ i -= Cx; while (i > Cx) \*/ + subl Cx, %ebx +2: + cmpl Cx, %ebx + jg 1b + + /*\ mm6 = i \*/ + movd %ebx, %mm6 + punpcklwd %mm6, %mm6 + punpckldq %mm6, %mm6 + + /*\ v += (*++p * i) >> 9 \*/ + addl $4, %eax + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $7, %mm1 + pmulhw %mm6, %mm1 + paddw %mm1, %mm0 +5: + /*\ v *= My \*/ + movd My, %mm4 + punpcklwd %mm4, %mm4 + punpckldq %mm4, %mm4 + psllw $2, %mm0 + pmulhw %mm4, %mm0 + + /*\ j = 0x4000 - My \*/ + movl $0x4000, %edx + subl My, %edx + jbe 6f + jmp 4f +3: + /*\ sptr += sow; p = sptr \*/ + addl sow_4, %esi + movl %esi, %eax + /*\ vx = (*p * Mx) >> 9 \*/ + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $7, %mm1 + pmulhw %mm5, %mm1 + + /*\ i = 0x4000 - Mx \*/ + movl $0x4000, %ebx + subl Mx, %ebx + jbe 5f + jmp 2f +1: + /*\ vx += (*++p * Cx) >> 9 \*/ + addl $4, %eax + movd (%eax), %mm2 + punpcklbw %mm7, %mm2 + psllw $7, %mm2 + pmulhw %mm3, %mm2 + paddw %mm2, %mm1 + + /*\ i -= Cx; while (i > Cx) \*/ + subl Cx, %ebx +2: + cmpl Cx, %ebx + jg 1b + + /*\ vx += (*++p * i) >> 9 \*/ + addl $4, %eax + movd (%eax), %mm2 + punpcklbw %mm7, %mm2 + psllw $7, %mm2 + pmulhw %mm6, %mm2 + paddw %mm2, %mm1 +5: + /*\ v += (vx * Cy) >> 14 \*/ + movd Cy, %mm4 + punpcklwd %mm4, %mm4 + punpckldq %mm4, %mm4 + psllw $2, %mm1 + pmulhw %mm4, %mm1 + paddw %mm1, %mm0 + + /*\ j -= Cy; while (j > Cy) \*/ + subl Cy, %edx +4: + cmpl Cy, %edx + jg 3b + + /*\ sptr += sow; p = sptr \*/ + addl sow_4, %esi + movl %esi, %eax + /*\ vx = (*p * Mx) >> 9 \*/ + movd (%eax), %mm1 + punpcklbw %mm7, %mm1 + psllw $7, %mm1 + pmulhw %mm5, %mm1 + + /*\ i = 0x4000 - Mx \*/ + movl $0x4000, %ebx + subl Mx, %ebx + jbe 5f + jmp 2f +1: + /*\ vx += (*++p * Cx) >> 9 \*/ + addl $4, %eax + movd (%eax), %mm2 + punpcklbw %mm7, %mm2 + psllw $7, %mm2 + pmulhw %mm3, %mm2 + paddw %mm2, %mm1 + + /*\ i -= Cx; while (i > Cx) \*/ + subl Cx, %ebx +2: + cmpl Cx, %ebx + jg 1b + + /*\ vx += (*++p * i) >> 9 \*/ + addl $4, %eax + movd (%eax), %mm2 + punpcklbw %mm7, %mm2 + psllw $7, %mm2 + pmulhw %mm6, %mm2 + paddw %mm2, %mm1 +5: + /*\ v += (vx * j) >> 14 \*/ + movd %edx, %mm4 + punpcklwd %mm4, %mm4 + punpckldq %mm4, %mm4 + psllw $2, %mm1 + pmulhw %mm4, %mm1 + paddw %mm1, %mm0 +6: + /*\ dptr[x] = mm0 >> 5 \*/ + psrlw $5, %mm0 + packuswb %mm0, %mm0 + movd %mm0, (%edi, %ecx, 4) + + /*\ while (++x) \*/ + incl %ecx + jnz .down_down_loop_x + + /*\ dptr += dow \*/ + movl dow, %eax + leal (%edi, %eax, 4), %edi + /*\ yap++; yp++ \*/ + addl $4, yap + addl $4, yp + /*\ while (y--) \*/ + decl y + jnz .down_down_loop_y + + jmp .scale_leave + +.scale_leave: + emms + popl %esi + popl %edi + popl %edx + popl %ecx + popl %ebx + movl %ebp, %esp + popl %ebp + ret + +SIZE(mimageScale_mmx_AARGBA) + +#endif + +.section .note.GNU-stack,"",%progbits diff --git a/src/ksquirrelpart/sq_utils_scale.cpp b/src/ksquirrelpart/sq_utils_scale.cpp new file mode 100644 index 0000000..b4d05f1 --- /dev/null +++ b/src/ksquirrelpart/sq_utils_scale.cpp @@ -0,0 +1,1933 @@ +// This file includes code for scaling images, in two versions. +// One ported from ImageMagick (slower, but can achieve better quality), +// and from Imlib2 ported by Mosfet (very fast). + + +// ImageMagick code begin +// ---------------------- + +// This code is ImageMagick's resize code, adapted for TQImage, with +// fastfloat class added as an optimization. +// The original license text follows. + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% RRRR EEEEE SSSSS IIIII ZZZZZ EEEEE % +% R R E SS I ZZ E % +% RRRR EEE SSS I ZZZ EEE % +% R R E SS I ZZ E % +% R R EEEEE SSSSS IIIII ZZZZZ EEEEE % +% % +% ImageMagick Image Resize Methods % +% % +% % +% Software Design % +% John Cristy % +% July 1992 % +% % +% % +% Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated % +% to making software imaging solutions freely available. % +% % +% Permission is hereby granted, free of charge, to any person obtaining a % +% copy of this software and associated documentation files ("ImageMagick"), % +% to deal in ImageMagick without restriction, including without limitation % +% the rights to use, copy, modify, merge, publish, distribute, sublicense, % +% and/or sell copies of ImageMagick, and to permit persons to whom the % +% ImageMagick is furnished 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 ImageMagick. % +% % +% The software is provided "as is", without warranty of any kind, express or % +% implied, including but not limited to the warranties of merchantability, % +% fitness for a particular purpose and noninfringement. In no event shall % +% ImageMagick Studio be liable for any claim, damages or other liability, % +% whether in an action of contract, tort or otherwise, arising from, out of % +% or in connection with ImageMagick or the use or other dealings in % +% ImageMagick. % +% % +% Except as contained in this notice, the name of the ImageMagick Studio % +% shall not be used in advertising or otherwise to promote the sale, use or % +% other dealings in ImageMagick without prior written authorization from the % +% ImageMagick Studio. % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// System +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#else +#ifdef HAVE_SYS_ENDIAN_H +#include <sys/endian.h> +#endif +#endif + +#include <tqimage.h> +#include <tqcolor.h> + +#include <tdeversion.h> +#include <kcpuinfo.h> + +#include <cstring> +#include <cstdlib> + +#include "sq_utils.h" + +// everything in namespace +namespace SQ_Utils { + +#define Max TQMAX +#define Min TQMIN + +// mustn't be less than used precision (i.e. 1/fastfloat::RATIO) +#define MagickEpsilon 0.0002 + +// fastfloat begin +// this class stores floating point numbers as integers, with BITS shift, +// i.e. value XYZ is stored as XYZ * RATIO +struct fastfloat + { + private: + enum { BITS = 12, RATIO = 4096 }; + public: + fastfloat() {} + fastfloat( long v ) : value( v << BITS ) {} + fastfloat( int v ) : value( v << BITS ) {} + fastfloat( double v ) : value( static_cast< long >( v * RATIO + 0.5 )) {} + double toDouble() const { return static_cast< double >( value ) / RATIO; } + long toLong() const { return value >> BITS; } + fastfloat& operator += ( fastfloat r ) { value += r.value; return *this; } + fastfloat& operator -= ( fastfloat r ) { value -= r.value; return *this; } + fastfloat& operator *= ( fastfloat r ) { value = static_cast< long long >( value ) * r.value >> BITS; return *this; } + fastfloat& operator /= ( fastfloat r ) { value = ( static_cast< long long >( value ) << BITS ) / r.value; return *this; } + bool operator< ( fastfloat r ) const { return value < r.value; } + bool operator<= ( fastfloat r ) const { return value <= r.value; } + bool operator> ( fastfloat r ) const { return value > r.value; } + bool operator>= ( fastfloat r ) const { return value >= r.value; } + bool operator== ( fastfloat r ) const { return value == r.value; } + bool operator!= ( fastfloat r ) const { return value != r.value; } + fastfloat operator-() const { return fastfloat( -value, false ); } + private: + fastfloat( long v, bool ) : value( v ) {} // for operator-() + long value; + }; + +inline fastfloat operator+ ( fastfloat l, fastfloat r ) { return fastfloat( l ) += r; } +inline fastfloat operator- ( fastfloat l, fastfloat r ) { return fastfloat( l ) -= r; } +inline fastfloat operator* ( fastfloat l, fastfloat r ) { return fastfloat( l ) *= r; } +inline fastfloat operator/ ( fastfloat l, fastfloat r ) { return fastfloat( l ) /= r; } + +inline bool operator< ( fastfloat l, double r ) { return l < fastfloat( r ); } +inline bool operator<= ( fastfloat l, double r ) { return l <= fastfloat( r ); } +inline bool operator> ( fastfloat l, double r ) { return l > fastfloat( r ); } +inline bool operator>= ( fastfloat l, double r ) { return l >= fastfloat( r ); } +inline bool operator== ( fastfloat l, double r ) { return l == fastfloat( r ); } +inline bool operator!= ( fastfloat l, double r ) { return l != fastfloat( r ); } + +inline bool operator< ( double l, fastfloat r ) { return fastfloat( l ) < r ; } +inline bool operator<= ( double l, fastfloat r ) { return fastfloat( l ) <= r ; } +inline bool operator> ( double l, fastfloat r ) { return fastfloat( l ) > r ; } +inline bool operator>= ( double l, fastfloat r ) { return fastfloat( l ) >= r ; } +inline bool operator== ( double l, fastfloat r ) { return fastfloat( l ) == r ; } +inline bool operator!= ( double l, fastfloat r ) { return fastfloat( l ) != r ; } + +inline double fasttodouble( fastfloat v ) { return v.toDouble(); } +inline long fasttolong( fastfloat v ) { return v.toLong(); } + +#if 1 // change to 0 to turn fastfloat usage off +#else +#define fastfloat double +#define fasttodouble( v ) double( v ) +#define fasttolong( v ) long( v ) +#endif + +//fastfloat end + + +typedef fastfloat (*Filter)(const fastfloat, const fastfloat); + +typedef struct _ContributionInfo +{ + fastfloat + weight; + + long + pixel; +} ContributionInfo; + + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% R e s i z e I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ResizeImage() scales an image to the desired dimensions with one of these +% filters: +% +% Bessel Blackman Box +% Catrom Cubic Gaussian +% Hanning Hermite Lanczos +% Mitchell Point Quandratic +% Sinc Triangle +% +% Most of the filters are FIR (finite impulse response), however, Bessel, +% Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc +% are windowed (brought down to zero) with the Blackman filter. +% +% ResizeImage() was inspired by Paul Heckbert's zoom program. +% +% The format of the ResizeImage method is: +% +% Image *ResizeImage(Image *image,const unsigned long columns, +% const unsigned long rows,const FilterTypes filter,const double blur, +% ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o image: The image. +% +% o columns: The number of columns in the scaled image. +% +% o rows: The number of rows in the scaled image. +% +% o filter: Image filter to use. +% +% o blur: The blur factor where > 1 is blurry, < 1 is sharp. +% +% o exception: Return any errors or warnings in this structure. +% +% +*/ + +#if 0 +static fastfloat Bessel(const fastfloat x,const fastfloat) +{ + if (x == 0.0) + return(MagickPI/4.0); + return(BesselOrderOne(MagickPI*x)/(2.0*x)); +} + +static fastfloat Sinc(const fastfloat x,const fastfloat) +{ + if (x == 0.0) + return(1.0); + return(sin(MagickPI*x)/(MagickPI*x)); +} + +static fastfloat Blackman(const fastfloat x,const fastfloat) +{ + return(0.42+0.5*cos(MagickPI*x)+0.08*cos(2*MagickPI*x)); +} + +static fastfloat BlackmanBessel(const fastfloat x,const fastfloat) +{ + return(Blackman(x/support,support)*Bessel(x,support)); +} + +static fastfloat BlackmanSinc(const fastfloat x,const fastfloat) +{ + return(Blackman(x/support,support)*Sinc(x,support)); +} +#endif + +static fastfloat Box(const fastfloat x,const fastfloat) +{ + if (x < -0.5) + return(0.0); + if (x < 0.5) + return(1.0); + return(0.0); +} + +#if 0 +static fastfloat Catrom(const fastfloat x,const fastfloat) +{ + if (x < -2.0) + return(0.0); + if (x < -1.0) + return(0.5*(4.0+x*(8.0+x*(5.0+x)))); + if (x < 0.0) + return(0.5*(2.0+x*x*(-5.0-3.0*x))); + if (x < 1.0) + return(0.5*(2.0+x*x*(-5.0+3.0*x))); + if (x < 2.0) + return(0.5*(4.0+x*(-8.0+x*(5.0-x)))); + return(0.0); +} + +static fastfloat Cubic(const fastfloat x,const fastfloat) +{ + if (x < -2.0) + return(0.0); + if (x < -1.0) + return((2.0+x)*(2.0+x)*(2.0+x)/6.0); + if (x < 0.0) + return((4.0+x*x*(-6.0-3.0*x))/6.0); + if (x < 1.0) + return((4.0+x*x*(-6.0+3.0*x))/6.0); + if (x < 2.0) + return((2.0-x)*(2.0-x)*(2.0-x)/6.0); + return(0.0); +} + +static fastfloat Gaussian(const fastfloat x,const fastfloat) +{ + return(exp(-2.0*x*x)*sqrt(2.0/MagickPI)); +} + +static fastfloat Hanning(const fastfloat x,const fastfloat) +{ + return(0.5+0.5*cos(MagickPI*x)); +} + +static fastfloat Hamming(const fastfloat x,const fastfloat) +{ + return(0.54+0.46*cos(MagickPI*x)); +} + +static fastfloat Hermite(const fastfloat x,const fastfloat) +{ + if (x < -1.0) + return(0.0); + if (x < 0.0) + return((2.0*(-x)-3.0)*(-x)*(-x)+1.0); + if (x < 1.0) + return((2.0*x-3.0)*x*x+1.0); + return(0.0); +} + +static fastfloat Lanczos(const fastfloat x,const fastfloat support) +{ + if (x < -3.0) + return(0.0); + if (x < 0.0) + return(Sinc(-x,support)*Sinc(-x/3.0,support)); + if (x < 3.0) + return(Sinc(x,support)*Sinc(x/3.0,support)); + return(0.0); +} + +static fastfloat Mitchell(const fastfloat x,const fastfloat) +{ +#define B (1.0/3.0) +#define C (1.0/3.0) +#define P0 (( 6.0- 2.0*B )/6.0) +#define P2 ((-18.0+12.0*B+ 6.0*C)/6.0) +#define P3 (( 12.0- 9.0*B- 6.0*C)/6.0) +#define Q0 (( 8.0*B+24.0*C)/6.0) +#define Q1 (( -12.0*B-48.0*C)/6.0) +#define Q2 (( 6.0*B+30.0*C)/6.0) +#define Q3 (( - 1.0*B- 6.0*C)/6.0) + + if (x < -2.0) + return(0.0); + if (x < -1.0) + return(Q0-x*(Q1-x*(Q2-x*Q3))); + if (x < 0.0) + return(P0+x*x*(P2-x*P3)); + if (x < 1.0) + return(P0+x*x*(P2+x*P3)); + if (x < 2.0) + return(Q0+x*(Q1+x*(Q2+x*Q3))); + return(0.0); + +#undef B +#undef C +#undef P0 +#undef P2 +#undef P3 +#undef Q0 +#undef Q1 +#undef Q2 +#undef Q3 +} +#endif + +// this is the same like Mitchell, but it has different values +// for B and C, resulting in sharper images +// http://sourceforge.net/mailarchive/forum.php?thread_id=7445822&forum_id=1210 +static fastfloat Bicubic(const fastfloat x,const fastfloat) +{ +#define B (0.0/3.0) +#define C (2.0/3.0) +#define P0 (( 6.0- 2.0*B )/6.0) +#define P2 ((-18.0+12.0*B+ 6.0*C)/6.0) +#define P3 (( 12.0- 9.0*B- 6.0*C)/6.0) +#define Q0 (( 8.0*B+24.0*C)/6.0) +#define Q1 (( -12.0*B-48.0*C)/6.0) +#define Q2 (( 6.0*B+30.0*C)/6.0) +#define Q3 (( - 1.0*B- 6.0*C)/6.0) + + if (x < -2.0) + return(0.0); + if (x < -1.0) + return(Q0-x*(Q1-x*(Q2-x*Q3))); + if (x < 0.0) + return(P0+x*x*(P2-x*P3)); + if (x < 1.0) + return(P0+x*x*(P2+x*P3)); + if (x < 2.0) + return(Q0+x*(Q1+x*(Q2+x*Q3))); + return(0.0); + +#undef B +#undef C +#undef P0 +#undef P2 +#undef P3 +#undef Q0 +#undef Q1 +#undef Q2 +#undef Q3 +} + +#if 0 +static fastfloat Quadratic(const fastfloat x,const fastfloat) +{ + if (x < -1.5) + return(0.0); + if (x < -0.5) + return(0.5*(x+1.5)*(x+1.5)); + if (x < 0.5) + return(0.75-x*x); + if (x < 1.5) + return(0.5*(x-1.5)*(x-1.5)); + return(0.0); +} +#endif + +static fastfloat Triangle(const fastfloat x,const fastfloat) +{ + if (x < -1.0) + return(0.0); + if (x < 0.0) + return(1.0+x); + if (x < 1.0) + return(1.0-x); + return(0.0); +} + +static void HorizontalFilter(const TQImage& source,TQImage& destination, + const fastfloat x_factor,const fastfloat blur, + ContributionInfo *contribution, Filter filter, fastfloat filtersupport) +{ + fastfloat + center, + density, + scale, + support; + + long + n, + start, + stop, + y; + + long + i, + x; + + /* + Apply filter to resize horizontally from source to destination. + */ + scale=blur*Max(1.0/x_factor,1.0); + support=scale* filtersupport; + if (support <= 0.5) + { + /* + Reduce to point sampling. + */ + support=0.5+MagickEpsilon; + scale=1.0; + } + scale=1.0/scale; + for (x=0; x < (long) destination.width(); x++) + { + center=(fastfloat) (x+0.5)/x_factor; + start= fasttolong(Max(center-support+0.5,0)); + stop= fasttolong(Min(center+support+0.5,source.width())); + density=0.0; + for (n=0; n < (stop-start); n++) + { + contribution[n].pixel=start+n; + contribution[n].weight= + filter (scale*(start+n-center+0.5), filtersupport ); + density+=contribution[n].weight; + } + if ((density != 0.0) && (density != 1.0)) + { + /* + Normalize. + */ + density=1.0/density; + for (i=0; i < n; i++) + contribution[i].weight*=density; + } +// p=AcquireImagePixels(source,contribution[0].pixel,0,contribution[n-1].pixel- +// contribution[0].pixel+1,source->rows,exception); +// q=SetImagePixels(destination,x,0,1,destination->rows); + for (y=0; y < (long) destination.height(); y++) + { + fastfloat red = 0; + fastfloat green = 0; + fastfloat blue = 0; + fastfloat alpha = 0; + for (i=0; i < n; i++) + { + int px = contribution[i].pixel; + int py = y; + TQRgb p = reinterpret_cast< TQRgb* >( const_cast<TQImage&>(source).jumpTable()[ py ])[ px ]; + red+=contribution[i].weight*tqRed(p); + green+=contribution[i].weight*tqGreen(p); + blue+=contribution[i].weight*tqBlue(p); + alpha+=contribution[i].weight*tqAlpha(p); + } + TQRgb pix = tqRgba( + fasttolong( red < 0 ? 0 : red > 255 ? 255 : red + 0.5 ), + fasttolong( green < 0 ? 0 : green > 255 ? 255 : green + 0.5 ), + fasttolong( blue < 0 ? 0 : blue > 255 ? 255 : blue + 0.5 ), + fasttolong( alpha < 0 ? 0 : alpha > 255 ? 255 : alpha + 0.5 )); + reinterpret_cast< TQRgb* >( destination.jumpTable()[ y ])[ x ] = pix; + } + } +} + +static void VerticalFilter(const TQImage& source,TQImage& destination, + const fastfloat y_factor,const fastfloat blur, + ContributionInfo *contribution, Filter filter, fastfloat filtersupport ) +{ + fastfloat + center, + density, + scale, + support; + + long + n, + start, + stop, + x; + + long + i, + y; + + /* + Apply filter to resize vertically from source to destination. + */ + scale=blur*Max(1.0/y_factor,1.0); + support=scale* filtersupport; + if (support <= 0.5) + { + /* + Reduce to point sampling. + */ + support=0.5+MagickEpsilon; + scale=1.0; + } + scale=1.0/scale; + for (y=0; y < (long) destination.height(); y++) + { + center=(fastfloat) (y+0.5)/y_factor; + start= fasttolong(Max(center-support+0.5,0)); + stop= fasttolong(Min(center+support+0.5,source.height())); + density=0.0; + for (n=0; n < (stop-start); n++) + { + contribution[n].pixel=start+n; + contribution[n].weight= + filter (scale*(start+n-center+0.5), filtersupport); + density+=contribution[n].weight; + } + if ((density != 0.0) && (density != 1.0)) + { + /* + Normalize. + */ + density=1.0/density; + for (i=0; i < n; i++) + contribution[i].weight*=density; + } +// p=AcquireImagePixels(source,0,contribution[0].pixel,source->columns, +// contribution[n-1].pixel-contribution[0].pixel+1,exception); +// q=SetImagePixels(destination,0,y,destination->columns,1); + for (x=0; x < (long) destination.width(); x++) + { + fastfloat red = 0; + fastfloat green = 0; + fastfloat blue = 0; + fastfloat alpha = 0; + for (i=0; i < n; i++) + { + int px = x; + int py = contribution[i].pixel; + TQRgb p = reinterpret_cast< TQRgb* >( const_cast<TQImage&>(source).jumpTable()[ py ])[ px ]; + red+=contribution[i].weight*tqRed(p); + green+=contribution[i].weight*tqGreen(p); + blue+=contribution[i].weight*tqBlue(p); + alpha+=contribution[i].weight*tqAlpha(p); + } + TQRgb pix = tqRgba( + fasttolong( red < 0 ? 0 : red > 255 ? 255 : red + 0.5 ), + fasttolong( green < 0 ? 0 : green > 255 ? 255 : green + 0.5 ), + fasttolong( blue < 0 ? 0 : blue > 255 ? 255 : blue + 0.5 ), + fasttolong( alpha < 0 ? 0 : alpha > 255 ? 255 : alpha + 0.5 )); + reinterpret_cast< TQRgb* >( destination.jumpTable()[ y ])[ x ] = pix; + } + } +} + +static TQImage ResizeImage(const TQImage& image,const int columns, + const int rows, Filter filter, fastfloat filtersupport, double blur) +{ + ContributionInfo + *contribution; + + fastfloat + support, + x_factor, + x_support, + y_factor, + y_support; + + /* + Initialize resize image attributes. + */ + if ((columns == image.width()) && (rows == image.height()) && (blur == 1.0)) + return image.copy(); + TQImage resize_image( columns, rows, 32 ); + resize_image.setAlphaBuffer( image.hasAlphaBuffer()); + /* + Allocate filter contribution info. + */ + x_factor=(fastfloat) resize_image.width()/image.width(); + y_factor=(fastfloat) resize_image.height()/image.height(); +// i=(long) LanczosFilter; +// if (image->filter != UndefinedFilter) +// i=(long) image->filter; +// else +// if ((image->storage_class == PseudoClass) || image->matte || +// ((x_factor*y_factor) > 1.0)) +// i=(long) MitchellFilter; + x_support=blur*Max(1.0/x_factor,1.0)*filtersupport; + y_support=blur*Max(1.0/y_factor,1.0)*filtersupport; + support=Max(x_support,y_support); + if (support < filtersupport) + support=filtersupport; + contribution=new ContributionInfo[ fasttolong( 2.0*Max(support,0.5)+3 ) ]; + TQ_CHECK_PTR( contribution ); + /* + Resize image. + */ + if (((fastfloat) columns*(image.height()+rows)) > + ((fastfloat) rows*(image.width()+columns))) + { + TQImage source_image( columns, image.height(), 32 ); + source_image.setAlphaBuffer( image.hasAlphaBuffer()); + HorizontalFilter(image,source_image,x_factor,blur, + contribution,filter,filtersupport); + VerticalFilter(source_image,resize_image,y_factor, + blur,contribution,filter,filtersupport); + } + else + { + TQImage source_image( image.width(), rows, 32 ); + source_image.setAlphaBuffer( image.hasAlphaBuffer()); + VerticalFilter(image,source_image,y_factor,blur, + contribution,filter,filtersupport); + HorizontalFilter(source_image,resize_image,x_factor, + blur,contribution,filter,filtersupport); + } + /* + Free allocated memory. + */ + delete[] contribution; + return(resize_image); +} + + +#undef Max +#undef Min +#undef MagickEpsilon + + +// filters and their matching support values +#if 0 + static const FilterInfo + filters[SincFilter+1] = + { + { Box, 0.0 }, + { Box, 0.0 }, + { Box, 0.5 }, + { Triangle, 1.0 }, + { Hermite, 1.0 }, + { Hanning, 1.0 }, + { Hamming, 1.0 }, + { Blackman, 1.0 }, + { Gaussian, 1.25 }, + { Quadratic, 1.5 }, + { Cubic, 2.0 }, + { Catrom, 2.0 }, + { Mitchell, 2.0 }, + { Lanczos, 3.0 }, + { BlackmanBessel, 3.2383 }, + { BlackmanSinc, 4.0 } + }; +#endif + + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% S a m p l e I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% SampleImage() scales an image to the desired dimensions with pixel +% sampling. Unlike other scaling methods, this method does not introduce +% any additional color into the scaled image. +% +% The format of the SampleImage method is: +% +% Image *SampleImage(const Image *image,const unsigned long columns, +% const unsigned long rows,ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o image: The image. +% +% o columns: The number of columns in the sampled image. +% +% o rows: The number of rows in the sampled image. +% +% o exception: Return any errors or warnings in this structure. +% +% +*/ +TQImage SampleImage(const TQImage& image,const int columns, + const int rows) +{ + int + *x_offset, + *y_offset; + + long + j, + y; + + uchar + *pixels; + + const uchar + *p; + + long + x; + + uchar + *q; + + /* + Initialize sampled image attributes. + */ + if ((columns == image.width()) && (rows == image.height())) + return image; + // This function is modified to handle any image depth, not only + // 32bit like the ImageMagick original. This avoids the relatively + // expensive conversion. + const int d = image.depth() / 8; + TQImage sample_image( columns, rows, image.depth()); + sample_image.setAlphaBuffer( image.hasAlphaBuffer()); + /* + Allocate scan line buffer and column offset buffers. + */ + pixels= new uchar[ image.width() * d ]; + x_offset= new int[ sample_image.width() ]; + y_offset= new int[ sample_image.height() ]; + /* + Initialize pixel offsets. + */ +// In the following several code 0.5 needs to be added, otherwise the image +// would be moved by half a pixel to bottom-right, just like +// with TQt's TQImage::scale() + for (x=0; x < (long) sample_image.width(); x++) + { + x_offset[x]=int((x+0.5)*image.width()/sample_image.width()); + } + for (y=0; y < (long) sample_image.height(); y++) + { + y_offset[y]=int((y+0.5)*image.height()/sample_image.height()); + } + /* + Sample each row. + */ + j=(-1); + for (y=0; y < (long) sample_image.height(); y++) + { + q= sample_image.scanLine( y ); + if (j != y_offset[y] ) + { + /* + Read a scan line. + */ + j= y_offset[y]; + p= image.scanLine( j ); + (void) memcpy(pixels,p,image.width()*d); + } + /* + Sample each column. + */ + switch( d ) + { + case 1: // 8bit + for (x=0; x < (long) sample_image.width(); x++) + { + *q++=pixels[ x_offset[x] ]; + } + break; + case 4: // 32bit + for (x=0; x < (long) sample_image.width(); x++) + { + *(TQRgb*)q=((TQRgb*)pixels)[ x_offset[x] ]; + q += d; + } + break; + default: + for (x=0; x < (long) sample_image.width(); x++) + { + memcpy( q, pixels + x_offset[x] * d, d ); + q += d; + } + break; + } + } + if( d != 4 ) // != 32bit + { + sample_image.setNumColors( image.numColors()); + for( int i = 0; i < image.numColors(); ++i ) + sample_image.setColor( i, image.color( i )); + } + delete[] y_offset; + delete[] x_offset; + delete[] pixels; + return sample_image; +} + + +// ImageMagick code end + + +// Imlib2/Mosfet code begin +// ------------------------ + +// This code is Imlib2 code, additionally modified by Mosfet, and with few small +// modifications for Gwenview. The MMX scaling code also belongs to it. + +// The original license texts follow. + +/** + * This is the normal smoothscale method, based on Imlib2's smoothscale. + * + * Originally I took the algorithm used in NetPBM and TQt and added MMX/3dnow + * optimizations. It ran in about 1/2 the time as TQt. Then I ported Imlib's + * C algorithm and it ran at about the same speed as my MMX optimized one... + * Finally I ported Imlib's MMX version and it ran in less than half the + * time as my MMX algorithm, (taking only a quarter of the time TQt does). + * + * Changes include formatting, namespaces and other C++'ings, removal of old + * #ifdef'ed code, and removal of unneeded border calculation code. + * + * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code + * is by Willem Monsuwe <willem@stack.nl>. All other modifications are + * (C) Daniel M. Duley. + */ + +/* + Copyright (C) 2004 Daniel M. Duley <dan.duley@verizon.net> + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* +Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software and its Copyright notices. In addition publicly +documented acknowledgment must be given that this software has been used if no +source code of this software is made available publicly. This includes +acknowledgments in either Copyright notices, Manuals, Publicity and Marketing +documents or any documentation provided with any product containing this +software. This License does not apply to any software that links to the +libraries provided by this software (statically or dynamically), but only to +the software provided. + +Please see the COPYING.PLAIN for a plain-english explanation of this notice +and it's intent. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +namespace MImageScale{ + typedef struct __mimage_scale_info + { + int *xpoints; + unsigned int **ypoints; + int *xapoints, *yapoints; + int xup_yup; + } MImageScaleInfo; + + unsigned int** mimageCalcYPoints(unsigned int *src, int sow, int sh, + int dh); + int* mimageCalcXPoints(int sw, int dw); + int* mimageCalcApoints(int s, int d, int up); + MImageScaleInfo* mimageFreeScaleInfo(MImageScaleInfo *isi); + MImageScaleInfo *mimageCalcScaleInfo(TQImage &img, int sw, int sh, + int dw, int dh, char aa, int sow); + void mimageSampleRGBA(MImageScaleInfo *isi, unsigned int *dest, int dxx, + int dyy, int dx, int dy, int dw, int dh, int dow); + void mimageScaleAARGBA(MImageScaleInfo *isi, unsigned int *dest, int dxx, + int dyy, int dx, int dy, int dw, int dh, int dow, + int sow); + void mimageScaleAARGB(MImageScaleInfo *isi, unsigned int *dest, int dxx, + int dyy, int dx, int dy, int dw, int dh, int dow, int + sow); + TQImage smoothScale(const TQImage& img, int dw, int dh); +} + +#ifdef HAVE_X86_MMX +extern "C" { + void __mimageScale_mmx_AARGBA(MImageScale::MImageScaleInfo *isi, + unsigned int *dest, int dxx, int dyy, + int dx, int dy, int dw, int dh, + int dow, int sow); +} +#endif + +using namespace MImageScale; + +TQImage MImageScale::smoothScale(const TQImage& image, int dw, int dh) +{ + TQImage img = image.depth() < 32 ? image.convertDepth( 32 ) : image; + int w = img.width(); + int h = img.height(); + + int sow = img.bytesPerLine(); + // handle CroppedTQImage + if( img.height() > 1 && sow != img.scanLine( 1 ) - img.scanLine( 0 )) + sow = img.scanLine( 1 ) - img.scanLine( 0 ); + sow = sow / ( img.depth() / 8 ); + + MImageScaleInfo *scaleinfo = + mimageCalcScaleInfo(img, w, h, dw, dh, true, sow); + if(!scaleinfo) + return TQImage(); + + TQImage buffer(dw, dh, 32); + buffer.setAlphaBuffer(img.hasAlphaBuffer()); + +#ifdef HAVE_X86_MMX +//#warning Using MMX Smoothscale + bool haveMMX = KCPUInfo::haveExtension( KCPUInfo::IntelMMX ); + if(haveMMX){ + __mimageScale_mmx_AARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, sow); + } + else +#endif + { + if(img.hasAlphaBuffer()) + mimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0, + 0, 0, dw, dh, dw, sow); + else + mimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0, + 0, 0, dw, dh, dw, sow); + } + mimageFreeScaleInfo(scaleinfo); + return(buffer); +} + +// +// Code ported from Imlib... +// + +// FIXME: replace with mRed, etc... These work on pointers to pixels, not +// pixel values +#if BYTE_ORDER == BIG_ENDIAN +#define A_VAL(p) ((unsigned char *)(p))[0] +#define R_VAL(p) ((unsigned char *)(p))[1] +#define G_VAL(p) ((unsigned char *)(p))[2] +#define B_VAL(p) ((unsigned char *)(p))[3] +#elif BYTE_ORDER == LITTLE_ENDIAN +#define A_VAL(p) ((unsigned char *)(p))[3] +#define R_VAL(p) ((unsigned char *)(p))[2] +#define G_VAL(p) ((unsigned char *)(p))[1] +#define B_VAL(p) ((unsigned char *)(p))[0] +#else +#error "BYTE_ORDER is not defined" +#endif + +#define INV_XAP (256 - xapoints[x]) +#define XAP (xapoints[x]) +#define INV_YAP (256 - yapoints[dyy + y]) +#define YAP (yapoints[dyy + y]) + +unsigned int** MImageScale::mimageCalcYPoints(unsigned int *src, + int sow, int sh, int dh) +{ + unsigned int **p; + int i, j = 0; + int val, inc, rv = 0; + + if(dh < 0){ + dh = -dh; + rv = 1; + } + p = new unsigned int* [dh+1]; + + val = 0; + inc = (sh << 16) / dh; + for(i = 0; i < dh; i++){ + p[j++] = src + ((val >> 16) * sow); + val += inc; + } + if(rv){ + for(i = dh / 2; --i >= 0; ){ + unsigned int *tmp = p[i]; + p[i] = p[dh - i - 1]; + p[dh - i - 1] = tmp; + } + } + return(p); +} + +int* MImageScale::mimageCalcXPoints(int sw, int dw) +{ + int *p, i, j = 0; + int val, inc, rv = 0; + + if(dw < 0){ + dw = -dw; + rv = 1; + } + p = new int[dw+1]; + + val = 0; + inc = (sw << 16) / dw; + for(i = 0; i < dw; i++){ + p[j++] = (val >> 16); + val += inc; + } + + if(rv){ + for(i = dw / 2; --i >= 0; ){ + int tmp = p[i]; + p[i] = p[dw - i - 1]; + p[dw - i - 1] = tmp; + } + } + return(p); +} + +int* MImageScale::mimageCalcApoints(int s, int d, int up) +{ + int *p, i, j = 0, rv = 0; + + if(d < 0){ + rv = 1; + d = -d; + } + p = new int[d]; + + /* scaling up */ + if(up){ + int val, inc; + + val = 0; + inc = (s << 16) / d; + for(i = 0; i < d; i++){ + p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00); + if((val >> 16) >= (s - 1)) + p[j - 1] = 0; + val += inc; + } + } + /* scaling down */ + else{ + int val, inc, ap, Cp; + val = 0; + inc = (s << 16) / d; + Cp = ((d << 14) / s) + 1; + for(i = 0; i < d; i++){ + ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; + p[j] = ap | (Cp << 16); + j++; + val += inc; + } + } + if(rv){ + int tmp; + for(i = d / 2; --i >= 0; ){ + tmp = p[i]; + p[i] = p[d - i - 1]; + p[d - i - 1] = tmp; + } + } + return(p); +} + +MImageScaleInfo* MImageScale::mimageFreeScaleInfo(MImageScaleInfo *isi) +{ + if(isi){ + delete[] isi->xpoints; + delete[] isi->ypoints; + delete[] isi->xapoints; + delete[] isi->yapoints; + delete isi; + } + return(NULL); +} + +MImageScaleInfo* MImageScale::mimageCalcScaleInfo(TQImage &img, int sw, int sh, + int dw, int dh, char aa, int sow) +{ + MImageScaleInfo *isi; + int scw, sch; + + scw = dw * img.width() / sw; + sch = dh * img.height() / sh; + + isi = new MImageScaleInfo; + if(!isi) + return(NULL); + memset(isi, 0, sizeof(MImageScaleInfo)); + + isi->xup_yup = (abs(dw) >= sw) + ((abs(dh) >= sh) << 1); + + isi->xpoints = mimageCalcXPoints(img.width(), scw); + if(!isi->xpoints) + return(mimageFreeScaleInfo(isi)); + isi->ypoints = mimageCalcYPoints((unsigned int *)img.scanLine(0), + sow, img.height(), sch ); + if (!isi->ypoints) + return(mimageFreeScaleInfo(isi)); + if(aa){ + isi->xapoints = mimageCalcApoints(img.width(), scw, isi->xup_yup & 1); + if(!isi->xapoints) + return(mimageFreeScaleInfo(isi)); + isi->yapoints = mimageCalcApoints(img.height(), sch, isi->xup_yup & 2); + if(!isi->yapoints) + return(mimageFreeScaleInfo(isi)); + } + return(isi); +} + +/* scale by pixel sampling only */ +void MImageScale::mimageSampleRGBA(MImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow) +{ + unsigned int *sptr, *dptr; + int x, y, end; + unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + + /* whats the last pixel ont he line so we stop there */ + end = dxx + dw; + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + /* get the pointer to the start of the destination scanline */ + dptr = dest + dx + ((y + dy) * dow); + /* calculate the source line we'll scan from */ + sptr = ypoints[dyy + y]; + /* go thru the scanline and copy across */ + for(x = dxx; x < end; x++) + *dptr++ = sptr[xpoints[x]]; + } +} + +/* FIXME: NEED to optimise ScaleAARGBA - currently its "ok" but needs work*/ + +/* scale by area sampling */ +void MImageScale::mimageScaleAARGBA(MImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) +{ + unsigned int *sptr, *dptr; + int x, y, end; + unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + end = dxx + dw; + /* scaling up both ways */ + if(isi->xup_yup == 3){ + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + /* calculate the source line we'll scan from */ + dptr = dest + dx + ((y + dy) * dow); + sptr = ypoints[dyy + y]; + if(YAP > 0){ + for(x = dxx; x < end; x++){ + int r, g, b, a; + int rr, gg, bb, aa; + unsigned int *pix; + + if(XAP > 0){ + pix = ypoints[dyy + y] + xpoints[x]; + r = R_VAL(pix) * INV_XAP; + g = G_VAL(pix) * INV_XAP; + b = B_VAL(pix) * INV_XAP; + a = A_VAL(pix) * INV_XAP; + pix++; + r += R_VAL(pix) * XAP; + g += G_VAL(pix) * XAP; + b += B_VAL(pix) * XAP; + a += A_VAL(pix) * XAP; + pix += sow; + rr = R_VAL(pix) * XAP; + gg = G_VAL(pix) * XAP; + bb = B_VAL(pix) * XAP; + aa = A_VAL(pix) * XAP; + pix--; + rr += R_VAL(pix) * INV_XAP; + gg += G_VAL(pix) * INV_XAP; + bb += B_VAL(pix) * INV_XAP; + aa += A_VAL(pix) * INV_XAP; + r = ((rr * YAP) + (r * INV_YAP)) >> 16; + g = ((gg * YAP) + (g * INV_YAP)) >> 16; + b = ((bb * YAP) + (b * INV_YAP)) >> 16; + a = ((aa * YAP) + (a * INV_YAP)) >> 16; + *dptr++ = tqRgba(r, g, b, a); + } + else{ + pix = ypoints[dyy + y] + xpoints[x]; + r = R_VAL(pix) * INV_YAP; + g = G_VAL(pix) * INV_YAP; + b = B_VAL(pix) * INV_YAP; + a = A_VAL(pix) * INV_YAP; + pix += sow; + r += R_VAL(pix) * YAP; + g += G_VAL(pix) * YAP; + b += B_VAL(pix) * YAP; + a += A_VAL(pix) * YAP; + r >>= 8; + g >>= 8; + b >>= 8; + a >>= 8; + *dptr++ = tqRgba(r, g, b, a); + } + } + } + else{ + for(x = dxx; x < end; x++){ + int r, g, b, a; + unsigned int *pix; + + if(XAP > 0){ + pix = ypoints[dyy + y] + xpoints[x]; + r = R_VAL(pix) * INV_XAP; + g = G_VAL(pix) * INV_XAP; + b = B_VAL(pix) * INV_XAP; + a = A_VAL(pix) * INV_XAP; + pix++; + r += R_VAL(pix) * XAP; + g += G_VAL(pix) * XAP; + b += B_VAL(pix) * XAP; + a += A_VAL(pix) * XAP; + r >>= 8; + g >>= 8; + b >>= 8; + a >>= 8; + *dptr++ = tqRgba(r, g, b, a); + } + else + *dptr++ = sptr[xpoints[x] ]; + } + } + } + } + /* if we're scaling down vertically */ + else if(isi->xup_yup == 1){ + /*\ 'Correct' version, with math units prepared for MMXification \*/ + int Cy, j; + unsigned int *pix; + int r, g, b, a, rr, gg, bb, aa; + int yap; + + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + Cy = YAP >> 16; + yap = YAP & 0xffff; + + dptr = dest + dx + ((y + dy) * dow); + for(x = dxx; x < end; x++){ + pix = ypoints[dyy + y] + xpoints[x]; + r = (R_VAL(pix) * yap) >> 10; + g = (G_VAL(pix) * yap) >> 10; + b = (B_VAL(pix) * yap) >> 10; + a = (A_VAL(pix) * yap) >> 10; + for(j = (1 << 14) - yap; j > Cy; j -= Cy){ + pix += sow; + r += (R_VAL(pix) * Cy) >> 10; + g += (G_VAL(pix) * Cy) >> 10; + b += (B_VAL(pix) * Cy) >> 10; + a += (A_VAL(pix) * Cy) >> 10; + } + if(j > 0){ + pix += sow; + r += (R_VAL(pix) * j) >> 10; + g += (G_VAL(pix) * j) >> 10; + b += (B_VAL(pix) * j) >> 10; + a += (A_VAL(pix) * j) >> 10; + } + if(XAP > 0){ + pix = ypoints[dyy + y] + xpoints[x] + 1; + rr = (R_VAL(pix) * yap) >> 10; + gg = (G_VAL(pix) * yap) >> 10; + bb = (B_VAL(pix) * yap) >> 10; + aa = (A_VAL(pix) * yap) >> 10; + for(j = (1 << 14) - yap; j > Cy; j -= Cy){ + pix += sow; + rr += (R_VAL(pix) * Cy) >> 10; + gg += (G_VAL(pix) * Cy) >> 10; + bb += (B_VAL(pix) * Cy) >> 10; + aa += (A_VAL(pix) * Cy) >> 10; + } + if(j > 0){ + pix += sow; + rr += (R_VAL(pix) * j) >> 10; + gg += (G_VAL(pix) * j) >> 10; + bb += (B_VAL(pix) * j) >> 10; + aa += (A_VAL(pix) * j) >> 10; + } + r = r * INV_XAP; + g = g * INV_XAP; + b = b * INV_XAP; + a = a * INV_XAP; + r = (r + ((rr * XAP))) >> 12; + g = (g + ((gg * XAP))) >> 12; + b = (b + ((bb * XAP))) >> 12; + a = (a + ((aa * XAP))) >> 12; + } + else{ + r >>= 4; + g >>= 4; + b >>= 4; + a >>= 4; + } + *dptr = tqRgba(r, g, b, a); + dptr++; + } + } + } + /* if we're scaling down horizontally */ + else if(isi->xup_yup == 2){ + /*\ 'Correct' version, with math units prepared for MMXification \*/ + int Cx, j; + unsigned int *pix; + int r, g, b, a, rr, gg, bb, aa; + int xap; + + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + dptr = dest + dx + ((y + dy) * dow); + for(x = dxx; x < end; x++){ + Cx = XAP >> 16; + xap = XAP & 0xffff; + + pix = ypoints[dyy + y] + xpoints[x]; + r = (R_VAL(pix) * xap) >> 10; + g = (G_VAL(pix) * xap) >> 10; + b = (B_VAL(pix) * xap) >> 10; + a = (A_VAL(pix) * xap) >> 10; + for(j = (1 << 14) - xap; j > Cx; j -= Cx){ + pix++; + r += (R_VAL(pix) * Cx) >> 10; + g += (G_VAL(pix) * Cx) >> 10; + b += (B_VAL(pix) * Cx) >> 10; + a += (A_VAL(pix) * Cx) >> 10; + } + if(j > 0){ + pix++; + r += (R_VAL(pix) * j) >> 10; + g += (G_VAL(pix) * j) >> 10; + b += (B_VAL(pix) * j) >> 10; + a += (A_VAL(pix) * j) >> 10; + } + if(YAP > 0){ + pix = ypoints[dyy + y] + xpoints[x] + sow; + rr = (R_VAL(pix) * xap) >> 10; + gg = (G_VAL(pix) * xap) >> 10; + bb = (B_VAL(pix) * xap) >> 10; + aa = (A_VAL(pix) * xap) >> 10; + for(j = (1 << 14) - xap; j > Cx; j -= Cx){ + pix++; + rr += (R_VAL(pix) * Cx) >> 10; + gg += (G_VAL(pix) * Cx) >> 10; + bb += (B_VAL(pix) * Cx) >> 10; + aa += (A_VAL(pix) * Cx) >> 10; + } + if(j > 0){ + pix++; + rr += (R_VAL(pix) * j) >> 10; + gg += (G_VAL(pix) * j) >> 10; + bb += (B_VAL(pix) * j) >> 10; + aa += (A_VAL(pix) * j) >> 10; + } + r = r * INV_YAP; + g = g * INV_YAP; + b = b * INV_YAP; + a = a * INV_YAP; + r = (r + ((rr * YAP))) >> 12; + g = (g + ((gg * YAP))) >> 12; + b = (b + ((bb * YAP))) >> 12; + a = (a + ((aa * YAP))) >> 12; + } + else{ + r >>= 4; + g >>= 4; + b >>= 4; + a >>= 4; + } + *dptr = tqRgba(r, g, b, a); + dptr++; + } + } + } + /* if we're scaling down horizontally & vertically */ + else{ + /*\ 'Correct' version, with math units prepared for MMXification: + |*| The operation 'b = (b * c) >> 16' translates to pmulhw, + |*| so the operation 'b = (b * c) >> d' would translate to + |*| psllw (16 - d), %mmb; pmulh %mmc, %mmb + \*/ + int Cx, Cy, i, j; + unsigned int *pix; + int a, r, g, b, ax, rx, gx, bx; + int xap, yap; + + for(y = 0; y < dh; y++){ + Cy = YAP >> 16; + yap = YAP & 0xffff; + + dptr = dest + dx + ((y + dy) * dow); + for(x = dxx; x < end; x++){ + Cx = XAP >> 16; + xap = XAP & 0xffff; + + sptr = ypoints[dyy + y] + xpoints[x]; + pix = sptr; + sptr += sow; + rx = (R_VAL(pix) * xap) >> 9; + gx = (G_VAL(pix) * xap) >> 9; + bx = (B_VAL(pix) * xap) >> 9; + ax = (A_VAL(pix) * xap) >> 9; + pix++; + for(i = (1 << 14) - xap; i > Cx; i -= Cx){ + rx += (R_VAL(pix) * Cx) >> 9; + gx += (G_VAL(pix) * Cx) >> 9; + bx += (B_VAL(pix) * Cx) >> 9; + ax += (A_VAL(pix) * Cx) >> 9; + pix++; + } + if(i > 0){ + rx += (R_VAL(pix) * i) >> 9; + gx += (G_VAL(pix) * i) >> 9; + bx += (B_VAL(pix) * i) >> 9; + ax += (A_VAL(pix) * i) >> 9; + } + + r = (rx * yap) >> 14; + g = (gx * yap) >> 14; + b = (bx * yap) >> 14; + a = (ax * yap) >> 14; + + for(j = (1 << 14) - yap; j > Cy; j -= Cy){ + pix = sptr; + sptr += sow; + rx = (R_VAL(pix) * xap) >> 9; + gx = (G_VAL(pix) * xap) >> 9; + bx = (B_VAL(pix) * xap) >> 9; + ax = (A_VAL(pix) * xap) >> 9; + pix++; + for(i = (1 << 14) - xap; i > Cx; i -= Cx){ + rx += (R_VAL(pix) * Cx) >> 9; + gx += (G_VAL(pix) * Cx) >> 9; + bx += (B_VAL(pix) * Cx) >> 9; + ax += (A_VAL(pix) * Cx) >> 9; + pix++; + } + if(i > 0){ + rx += (R_VAL(pix) * i) >> 9; + gx += (G_VAL(pix) * i) >> 9; + bx += (B_VAL(pix) * i) >> 9; + ax += (A_VAL(pix) * i) >> 9; + } + + r += (rx * Cy) >> 14; + g += (gx * Cy) >> 14; + b += (bx * Cy) >> 14; + a += (ax * Cy) >> 14; + } + if(j > 0){ + pix = sptr; + sptr += sow; + rx = (R_VAL(pix) * xap) >> 9; + gx = (G_VAL(pix) * xap) >> 9; + bx = (B_VAL(pix) * xap) >> 9; + ax = (A_VAL(pix) * xap) >> 9; + pix++; + for(i = (1 << 14) - xap; i > Cx; i -= Cx){ + rx += (R_VAL(pix) * Cx) >> 9; + gx += (G_VAL(pix) * Cx) >> 9; + bx += (B_VAL(pix) * Cx) >> 9; + ax += (A_VAL(pix) * Cx) >> 9; + pix++; + } + if(i > 0){ + rx += (R_VAL(pix) * i) >> 9; + gx += (G_VAL(pix) * i) >> 9; + bx += (B_VAL(pix) * i) >> 9; + ax += (A_VAL(pix) * i) >> 9; + } + + r += (rx * j) >> 14; + g += (gx * j) >> 14; + b += (bx * j) >> 14; + a += (ax * j) >> 14; + } + + R_VAL(dptr) = r >> 5; + G_VAL(dptr) = g >> 5; + B_VAL(dptr) = b >> 5; + A_VAL(dptr) = a >> 5; + dptr++; + } + } + } +} + +/* scale by area sampling - IGNORE the ALPHA byte*/ +void MImageScale::mimageScaleAARGB(MImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) +{ + unsigned int *sptr, *dptr; + int x, y, end; + unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + end = dxx + dw; + /* scaling up both ways */ + if(isi->xup_yup == 3){ + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + /* calculate the source line we'll scan from */ + dptr = dest + dx + ((y + dy) * dow); + sptr = ypoints[dyy + y]; + if(YAP > 0){ + for(x = dxx; x < end; x++){ + int r = 0, g = 0, b = 0; + int rr = 0, gg = 0, bb = 0; + unsigned int *pix; + + if(XAP > 0){ + pix = ypoints[dyy + y] + xpoints[x]; + r = R_VAL(pix) * INV_XAP; + g = G_VAL(pix) * INV_XAP; + b = B_VAL(pix) * INV_XAP; + pix++; + r += R_VAL(pix) * XAP; + g += G_VAL(pix) * XAP; + b += B_VAL(pix) * XAP; + pix += sow; + rr = R_VAL(pix) * XAP; + gg = G_VAL(pix) * XAP; + bb = B_VAL(pix) * XAP; + pix --; + rr += R_VAL(pix) * INV_XAP; + gg += G_VAL(pix) * INV_XAP; + bb += B_VAL(pix) * INV_XAP; + r = ((rr * YAP) + (r * INV_YAP)) >> 16; + g = ((gg * YAP) + (g * INV_YAP)) >> 16; + b = ((bb * YAP) + (b * INV_YAP)) >> 16; + *dptr++ = tqRgba(r, g, b, 0xff); + } + else{ + pix = ypoints[dyy + y] + xpoints[x]; + r = R_VAL(pix) * INV_YAP; + g = G_VAL(pix) * INV_YAP; + b = B_VAL(pix) * INV_YAP; + pix += sow; + r += R_VAL(pix) * YAP; + g += G_VAL(pix) * YAP; + b += B_VAL(pix) * YAP; + r >>= 8; + g >>= 8; + b >>= 8; + *dptr++ = tqRgba(r, g, b, 0xff); + } + } + } + else{ + for(x = dxx; x < end; x++){ + int r = 0, g = 0, b = 0; + unsigned int *pix; + + if(XAP > 0){ + pix = ypoints[dyy + y] + xpoints[x]; + r = R_VAL(pix) * INV_XAP; + g = G_VAL(pix) * INV_XAP; + b = B_VAL(pix) * INV_XAP; + pix++; + r += R_VAL(pix) * XAP; + g += G_VAL(pix) * XAP; + b += B_VAL(pix) * XAP; + r >>= 8; + g >>= 8; + b >>= 8; + *dptr++ = tqRgba(r, g, b, 0xff); + } + else + *dptr++ = sptr[xpoints[x] ]; + } + } + } + } + /* if we're scaling down vertically */ + else if(isi->xup_yup == 1){ + /*\ 'Correct' version, with math units prepared for MMXification \*/ + int Cy, j; + unsigned int *pix; + int r, g, b, rr, gg, bb; + int yap; + + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + Cy = YAP >> 16; + yap = YAP & 0xffff; + + dptr = dest + dx + ((y + dy) * dow); + for(x = dxx; x < end; x++){ + pix = ypoints[dyy + y] + xpoints[x]; + r = (R_VAL(pix) * yap) >> 10; + g = (G_VAL(pix) * yap) >> 10; + b = (B_VAL(pix) * yap) >> 10; + pix += sow; + for(j = (1 << 14) - yap; j > Cy; j -= Cy){ + r += (R_VAL(pix) * Cy) >> 10; + g += (G_VAL(pix) * Cy) >> 10; + b += (B_VAL(pix) * Cy) >> 10; + pix += sow; + } + if(j > 0){ + r += (R_VAL(pix) * j) >> 10; + g += (G_VAL(pix) * j) >> 10; + b += (B_VAL(pix) * j) >> 10; + } + if(XAP > 0){ + pix = ypoints[dyy + y] + xpoints[x] + 1; + rr = (R_VAL(pix) * yap) >> 10; + gg = (G_VAL(pix) * yap) >> 10; + bb = (B_VAL(pix) * yap) >> 10; + pix += sow; + for(j = (1 << 14) - yap; j > Cy; j -= Cy){ + rr += (R_VAL(pix) * Cy) >> 10; + gg += (G_VAL(pix) * Cy) >> 10; + bb += (B_VAL(pix) * Cy) >> 10; + pix += sow; + } + if(j > 0){ + rr += (R_VAL(pix) * j) >> 10; + gg += (G_VAL(pix) * j) >> 10; + bb += (B_VAL(pix) * j) >> 10; + } + r = r * INV_XAP; + g = g * INV_XAP; + b = b * INV_XAP; + r = (r + ((rr * XAP))) >> 12; + g = (g + ((gg * XAP))) >> 12; + b = (b + ((bb * XAP))) >> 12; + } + else{ + r >>= 4; + g >>= 4; + b >>= 4; + } + *dptr = tqRgba(r, g, b, 0xff); + dptr++; + } + } + } + /* if we're scaling down horizontally */ + else if(isi->xup_yup == 2){ + /*\ 'Correct' version, with math units prepared for MMXification \*/ + int Cx, j; + unsigned int *pix; + int r, g, b, rr, gg, bb; + int xap; + + /* go through every scanline in the output buffer */ + for(y = 0; y < dh; y++){ + dptr = dest + dx + ((y + dy) * dow); + for(x = dxx; x < end; x++){ + Cx = XAP >> 16; + xap = XAP & 0xffff; + + pix = ypoints[dyy + y] + xpoints[x]; + r = (R_VAL(pix) * xap) >> 10; + g = (G_VAL(pix) * xap) >> 10; + b = (B_VAL(pix) * xap) >> 10; + pix++; + for(j = (1 << 14) - xap; j > Cx; j -= Cx){ + r += (R_VAL(pix) * Cx) >> 10; + g += (G_VAL(pix) * Cx) >> 10; + b += (B_VAL(pix) * Cx) >> 10; + pix++; + } + if(j > 0){ + r += (R_VAL(pix) * j) >> 10; + g += (G_VAL(pix) * j) >> 10; + b += (B_VAL(pix) * j) >> 10; + } + if(YAP > 0){ + pix = ypoints[dyy + y] + xpoints[x] + sow; + rr = (R_VAL(pix) * xap) >> 10; + gg = (G_VAL(pix) * xap) >> 10; + bb = (B_VAL(pix) * xap) >> 10; + pix++; + for(j = (1 << 14) - xap; j > Cx; j -= Cx){ + rr += (R_VAL(pix) * Cx) >> 10; + gg += (G_VAL(pix) * Cx) >> 10; + bb += (B_VAL(pix) * Cx) >> 10; + pix++; + } + if(j > 0){ + rr += (R_VAL(pix) * j) >> 10; + gg += (G_VAL(pix) * j) >> 10; + bb += (B_VAL(pix) * j) >> 10; + } + r = r * INV_YAP; + g = g * INV_YAP; + b = b * INV_YAP; + r = (r + ((rr * YAP))) >> 12; + g = (g + ((gg * YAP))) >> 12; + b = (b + ((bb * YAP))) >> 12; + } + else{ + r >>= 4; + g >>= 4; + b >>= 4; + } + *dptr = tqRgba(r, g, b, 0xff); + dptr++; + } + } + } + /* fully optimized (i think) - onyl change of algorithm can help */ + /* if we're scaling down horizontally & vertically */ + else{ + /*\ 'Correct' version, with math units prepared for MMXification \*/ + int Cx, Cy, i, j; + unsigned int *pix; + int r, g, b, rx, gx, bx; + int xap, yap; + + for(y = 0; y < dh; y++){ + Cy = YAP >> 16; + yap = YAP & 0xffff; + + dptr = dest + dx + ((y + dy) * dow); + for(x = dxx; x < end; x++){ + Cx = XAP >> 16; + xap = XAP & 0xffff; + + sptr = ypoints[dyy + y] + xpoints[x]; + pix = sptr; + sptr += sow; + rx = (R_VAL(pix) * xap) >> 9; + gx = (G_VAL(pix) * xap) >> 9; + bx = (B_VAL(pix) * xap) >> 9; + pix++; + for(i = (1 << 14) - xap; i > Cx; i -= Cx){ + rx += (R_VAL(pix) * Cx) >> 9; + gx += (G_VAL(pix) * Cx) >> 9; + bx += (B_VAL(pix) * Cx) >> 9; + pix++; + } + if(i > 0){ + rx += (R_VAL(pix) * i) >> 9; + gx += (G_VAL(pix) * i) >> 9; + bx += (B_VAL(pix) * i) >> 9; + } + + r = (rx * yap) >> 14; + g = (gx * yap) >> 14; + b = (bx * yap) >> 14; + + for(j = (1 << 14) - yap; j > Cy; j -= Cy){ + pix = sptr; + sptr += sow; + rx = (R_VAL(pix) * xap) >> 9; + gx = (G_VAL(pix) * xap) >> 9; + bx = (B_VAL(pix) * xap) >> 9; + pix++; + for(i = (1 << 14) - xap; i > Cx; i -= Cx){ + rx += (R_VAL(pix) * Cx) >> 9; + gx += (G_VAL(pix) * Cx) >> 9; + bx += (B_VAL(pix) * Cx) >> 9; + pix++; + } + if(i > 0){ + rx += (R_VAL(pix) * i) >> 9; + gx += (G_VAL(pix) * i) >> 9; + bx += (B_VAL(pix) * i) >> 9; + } + + r += (rx * Cy) >> 14; + g += (gx * Cy) >> 14; + b += (bx * Cy) >> 14; + } + if(j > 0){ + pix = sptr; + sptr += sow; + rx = (R_VAL(pix) * xap) >> 9; + gx = (G_VAL(pix) * xap) >> 9; + bx = (B_VAL(pix) * xap) >> 9; + pix++; + for(i = (1 << 14) - xap; i > Cx; i -= Cx){ + rx += (R_VAL(pix) * Cx) >> 9; + gx += (G_VAL(pix) * Cx) >> 9; + bx += (B_VAL(pix) * Cx) >> 9; + pix++; + } + if(i > 0){ + rx += (R_VAL(pix) * i) >> 9; + gx += (G_VAL(pix) * i) >> 9; + bx += (B_VAL(pix) * i) >> 9; + } + + r += (rx * j) >> 14; + g += (gx * j) >> 14; + b += (bx * j) >> 14; + } + + R_VAL(dptr) = r >> 5; + G_VAL(dptr) = g >> 5; + B_VAL(dptr) = b >> 5; + dptr++; + } + } + } +} + +// Imlib2/Mosfet code end + +TQImage scale(const TQImage& image, int width, int height, + SmoothAlgorithm alg, TQImage::ScaleMode mode, double blur ) +{ + if( image.isNull()) return image.copy(); + + TQSize newSize( image.size() ); + newSize.scale( TQSize( width, height ), (TQSize::ScaleMode)mode ); // ### remove cast in TQt 4.0 + newSize = newSize.expandedTo( TQSize( 1, 1 )); // make sure it doesn't become null + + if ( newSize == image.size() ) return image.copy(); + + width = newSize.width(); + height = newSize.height(); + Filter filter = NULL; + fastfloat filtersupport; + + switch( alg ) { + case SMOOTH_NONE: + filter = NULL; + filtersupport = 0.0; + break; + case SMOOTH_FAST: + filter = Box; + filtersupport = 0.5; + break; + case SMOOTH_NORMAL: + default: + filter = Triangle; + filtersupport = 1.0; + break; + case SMOOTH_BEST: +// filter = Mitchell; + filter = Bicubic; + filtersupport = 2.0; + break; + } + + if( filter == Box && blur == 1.0 ) + return MImageScale::smoothScale( image, width, height ); + + if( filter == Box && width > image.width() && height > image.height() && blur == 1.0 ) { + filter = NULL; // Box doesn't really smooth when enlarging + } + + if( filter == NULL ) { + return SampleImage( image, width, height ); // doesn't need 32bit + } + + return ResizeImage( image.convertDepth( 32 ), width, height, filter, filtersupport, blur ); + // unlike TQt's smoothScale() this function introduces new colors to grayscale images ... oh well +} + + +} // namespace |
