From 9294494137f0917d6ba8fc1763e65e27a0075686 Mon Sep 17 00:00:00 2001 From: Stefan Doehla Date: Wed, 24 Aug 2005 12:00:00 +0200 Subject: [PATCH] xcalib-source-0.6.tar.gz --- AdobeGammaTest.icm | Bin 0 -> 2756 bytes Makefile | 34 +++++- README | 65 +++++++++-- README.profilers | 11 +- fglrx/fglrx_gamma.h | 83 ++++++++++++++ fglrx/libfglrx_gamma.a | Bin 0 -> 5050 bytes fglrx/libfglrx_gamma.so.1.0 | Bin 0 -> 10296 bytes gamma_2_2_bright.icc | Bin 0 -> 864 bytes gamma_2_2_lowContrast.icc | Bin 0 -> 864 bytes xcalib.c | 223 ++++++++++++++++++++++++++++++------ 10 files changed, 367 insertions(+), 49 deletions(-) create mode 100644 AdobeGammaTest.icm create mode 100644 fglrx/fglrx_gamma.h create mode 100644 fglrx/libfglrx_gamma.a create mode 100644 fglrx/libfglrx_gamma.so.1.0 create mode 100644 gamma_2_2_bright.icc create mode 100644 gamma_2_2_lowContrast.icc diff --git a/AdobeGammaTest.icm b/AdobeGammaTest.icm new file mode 100644 index 0000000000000000000000000000000000000000..e5f1246185d1498dca8e6c8f3872fd9381e3e973 GIT binary patch literal 2756 zcmb`I33L-x6o&sUvQ{WiDvQdXRX}N>fQ5n!ZCVOSSxQ+&Fr7@(&}K22G@vLdh$t#9 zxT3h>j*0?;`-VFTh@gl&Dk`7|f{K9t_r0b`dhp=kI3FkH=FQBT;odKQfo7`;iVBO9 z(*du~4wjV^8so-KFdA<_6QrXpa*^jWLxIv!gUZ2UNU_5R@gk{X$KH)dl5gv?Wv|%! zf2vxWfuIc}P2|LpPSf_Ab%&zrV5!U-zXVrwg9w60Vo#C~dA=Z6l-L_2bmpYDh zTClv#!J7A@g=910+8J~i4!<|x^i4BL{Vq?X$8s6rkjLjX3S9mQ%P4Vry-x06wR@zRZBpjy*jnrj@{r1AB~VK1n^^52WN=jF)r@^bU@^0Is7 z_>cK+-t?XNB1(T(h6EWK57hYl$ksHK9|S# z_XcONMDnIlpU*)+NL>DCNAWer24rHZ8`=c zxH7iWR{i^6&GYIr;Ujq-zb1z~ZbOzGW#xt$4%SM|BPqEzaJcXKH>7Vs3Ln9L?a>)s z(4BE~8v0=X&O`x>9!xJsJF)YU8ULY@$m+&%q1+S9V$m>`|-XL${E%G*b2k(;i$ZGOFJ|JtzTCxrwlJ(>x zvVm+QACph8iF`^nlh4TK$= zB)=+lVHb9j-^d=tUhKv1J24ap#Fkx7n0JJOzXKu2;cj>GY!6AaQBC*VYq zg_CeH>4L84hEvF?bTu0}=s|kY+Ft05K6E#a^rgZ1=ueAJ#~C#FEDWU0g>ca5Vme)d z!SwoUnmv?m52M{9=yw?nFQ?;UX!$th`9x*kTPC;pGM=O zzKiWM>uuMrYtOai;<)x(yDeU8r^RP+Sv(epmnwV3TX9xw6;H)baZ{`mAJ-}e#XYfZ zv+_**+M{jx)=2Lgrp-*|&7l$}nm37wqw_{5 zPBd?1Dmrg;+9YO;OlV16(n!uo%B)Z+BN-D-7@3%)OEg7lbj=BiUe5+j-xk`y{6q6s1Cpp!vTK_`NwfldOMy<|Yc-+y8n0RI5~GHOWx literal 0 HcmV?d00001 diff --git a/Makefile b/Makefile index 4d063e6..dacc95b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Makefile for xcalib # -# (c) 2004 Stefan Doehla +# (c) 2004-2005 Stefan Doehla # # This program is GPL-ed postcardware! please see README # @@ -20,12 +20,36 @@ # MA 02111-1307 USA. # -XCALIB_VERSION = 0.5 +# +# the following targets are defined: +# - lo_xcalib +# xcalib in its standard version (internal parser) +# - icclib_xcalib +# xcalib using Graeme Gill's icclib +# - lcms_xcalib +# xcalib using a patched version of Marti Maria's LCMS +# - win_xcalib +# version for MS-Windows systems with MinGW (internal parser) +# - fglrx_xcalib +# version for ATI's proprietary fglrx driver (internal parser) +# +# - clean +# delete all objects and binaries +# - dist +# create .tar.gz archive +# +# if it doesn't compile right-out-of-the-box, it may be sufficient +# to change the following variables + +XCALIB_VERSION = 0.6 CFLAGS = -Os XINCLUDEDIR = /usr/X11R6/include XLIBDIR = /usr/X11R6/lib LCMSINCLUDEDIR = /usr/local/include LCMSLIBDIR = /usr/local/lib +# for ATI's proprietary driver (must contain the header file fglrx_gamma.h) +FGLRXINCLUDEDIR = ./fglrx +FGLRXLIBDIR = ./fglrx # default make target all: lo_xcalib @@ -36,6 +60,10 @@ lo_xcalib: xcalib.c $(CC) $(CFLAGS) -c xcalib.c -I$(XINCLUDEDIR) -DXCALIB_VERSION=\"$(XCALIB_VERSION)\" $(CC) $(CFLAGS) -L$(XLIBDIR) -lm -o xcalib xcalib.o -lX11 -lXxf86vm -lXext +fglrx_xcalib: xcalib.c + $(CC) $(CFLAGS) -c xcalib.c -I$(XINCLUDEDIR) -DXCALIB_VERSION=\"$(XCALIB_VERSION)\" -I$(FGLRXINCLUDEDIR) -DFGLRX + $(CC) $(CFLAGS) -L$(XLIBDIR) -L$(FGLRXLIBDIR) -lm -o xcalib xcalib.o -lX11 -lXxf86vm -lXext -lfglrx_gamma + win_xcalib: xcalib.c $(CC) $(CFLAGS) -c xcalib.c -DXCALIB_VERSION=\"$(XCALIB_VERSION)\" -DWIN32GDI windres.exe resource.rc resource.o @@ -68,6 +96,6 @@ clean: dist: cd .. - tar czf xcalib-source-$(XCALIB_VERSION).tar.gz xcalib-$(XCALIB_VERSION) + tar czf xcalib-source-$(XCALIB_VERSION).tar.gz xcalib-$(XCALIB_VERSION)/ cd xcalib-$(XCALIB_VERSION)/ diff --git a/README b/README index 3f7de9f..b661fc0 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -xcalib 0.5 +Xcalib 0.6 ==================================================== (c) 2004-2005 Stefan Döhla This program is GPL-licensed postcardware! More infos at end of README. @@ -23,13 +23,14 @@ usage: -noaction or -n -verbose or -v -printramps or -p + -loss or -l -help or -h -version - last parameter MUST be an ICC profile containing vcgt-tag + last parameter MUST be an ICC profile containing a vcgt or mLUT tag. use profiles gamma_1_0.icc and gamma_2_2.icc for testing. Profiles - with vcg-tables can be created with some profile creation suites. + with vcg-tables can be created with most profile creation suites. An example profile with a vcg-table is inclued, named bluish.icc, which simulates a very high whitepoint (without further intentions). @@ -40,6 +41,12 @@ requirements: is available. Other X-servers like OpenWin do not contain XVidMode stuff - so please don't ask me for support if XVidMode isn't supported. + + Since version 0.5, Win32-support was added. The program will work + with most video cards, that have correctly implemented drivers. + + As of version 0.6, a special treatment for the close-source ATI FGLRX + X11 driver was added. XVidMode is still required. You need a profile which contains the 'vcgt' tag to achieve monitor calibration. You can create it with some commercial @@ -57,6 +64,9 @@ install: $ make lcms_xcalib $ make lo_xcalib + $ make win_xcalib + $ make fglrx_xcalib + The make targets correspond to the possible ICC reader implementations: - Graeme Gill's "icclib" @@ -83,13 +93,21 @@ install: The Win32 version was made with and tested for MinGW. Since most users do not have a running MinGW environment, a binary executable is - provided. To compile it on yout own, the following command creates a + provided. To compile it on your own, the following command creates a working Win32-build (tested with MSys): $ make win_xcalib Win32 was only tested with the internal parser - lcms and icclib support are not planned. + + For ATI's proprietary FGLRX driver for X11, a special version can be + built. Issue the command + + $ make fglrx_xcalib + + on the commandline. For now, only the internal parser can be used + in combination with this server backend. motivation: ----------- @@ -124,6 +142,7 @@ motivation: live with it since it's common. They use a tag called Video Card Gamma Tag (or vcgt) in ICC-profiles that contains calibration values. The calibration is applied before profile creation, where the vcgt + will be saved in your profile for convenience reasons: All color settings for the display device are stored in a common file. @@ -160,6 +179,7 @@ limitations: Known not-working drivers: - vesa (generic driver without any calibration knobs) + - fglrx (but you can build fglrx_xcalib) If you see both/only one/no display changing it's behaviour, test if it's a bug of xcalib by cross-checking with the 'xgamma' tool that @@ -169,10 +189,36 @@ limitations: vcgt. The vcgt contains 2.2 in all cases, whereas the real LUT-values that are downloaded to the X-server are located somewhere else in the system - but nobody know's where. Please tell me where they are - if - you find them. + you find them. A newer version of AdobeGamma (from 2003) writes a + vcgt tag with useful data. Nevertheless, the size field is wrong. As + of version 0.6, basic concealment for wrong AdobeGamma profiles + (created with the 2003 version) was added to the internal parser. + + On Win32-systems, some drivers are not correctly implemented. E.g. + the NVidia Riva driver for Windows2000 and WindowsXP wrote nonsense + values to the video cards RAMDAC (resulting in a gray display). I + used for these cards an old NT-driver from a video card vendor. + + The source code became messy in the last time because of numerous + workarounds and a bad mixture of Win32, X11, ATI code and code for + the different parsers used to get the gamma ramps from the profile. + This makes it hard to find the important code sections for others + than me and might have lead to bugs or leaks. A following version + will most likely be ported to C++ to ease modularisation of the code + and allow utilization by other software. history: -------- + 0.6: + - added 0-interpolated upscaling if LUT>vcgt + - added reading of mLUT instead of vcgt (not memory-safe for now) + this is used for profiles, created by ProfileMechanic Monitor + - added concealment for obviously wrong profiles made by AdobeGamma + - added fglrx version for ATI's proprietary driver + - added loss calculation (option "-loss" or "-l") which shows how + many steps are lost by calibrating the device + - added limits of VideoCardGammaFormula to internal parser + 0.5: 2005-03-03 - Win32 version added (compilable with MinGW) + support for command line options as usual @@ -218,11 +264,15 @@ history: todo: ----- - [ ] gamma limits of vcgt-spec need to be implemented + [ ] integrate the _ICC_PROFILE atom + [ ] interpolated upscaling + [X] use ATI's API when using the closed-source X11 ATI driver + [ ] gamma limits of vcgt-spec for icclib and LCMS version [ ] further code review for memory leaks [x] use platform independent types for better portability [X] use lcms instead of icclib: worse vcgt-parsing but functions for gamma ramp building and smoothing + [ ] add multi-monitor support to Win32 version bugs: ----- @@ -260,6 +310,7 @@ links: http://www.littlecms.com http://www.argyllcms.com http://www.coloraid.de + http://www.behrmann.name license: -------- @@ -273,6 +324,6 @@ license: GERMANY Please write on it your name and email-address and that you use - xcalib-0.5 . + xcalib-0.6 . EOF diff --git a/README.profilers b/README.profilers index 3665508..b0c14de 100644 --- a/README.profilers +++ b/README.profilers @@ -9,7 +9,7 @@ BasiCColor display: ------------------- vcgt, table with 256 * 16bit entries -Gretag ProfileMaker 4.1: +Gretag/Logo ProfileMaker 4.1: ------------------------ vcgt, table with 256 * 16bit entries @@ -17,5 +17,14 @@ lprof, Marti's little profiler (unmaintained): ---------------------------------------------- no calibration +Profile Mechanic Monitor (by Jonathan Sachs) +-------------------------------------------- +mLUT, table with 256 * 16bit entries + +AdobeGamma (came with Photoshop CS) +----------------------------------- +vcgt, table with 256 * 16bit entries, signalled as 8bit entries! + + (c) 2005 - Stefan Doehla EOF diff --git a/fglrx/fglrx_gamma.h b/fglrx/fglrx_gamma.h new file mode 100644 index 0000000..c139d5b --- /dev/null +++ b/fglrx/fglrx_gamma.h @@ -0,0 +1,83 @@ +/*****************************************************************************/ +/* */ +/* NAME: fglrx_gamma.h */ +/* */ +/* FGLRXGAMMA extension interface library */ +/* */ +/* Copyright (c) 2002,2003 ATI Research, Starnberg, Germany */ +/* */ +/*****************************************************************************/ + +#ifndef __FGLRX_GAMMA_H__ +#define __FGLRX_GAMMA_H__ + +////////////////////////////////////////////////////////////////////////////// +// includes + +#include + + +////////////////////////////////////////////////////////////////////////////// +// macro defines + +// boolean constants +#define FALSE (1==0) +#define TRUE (1==1) + +// ordinal constants +#define FGLRX_GAMMA_RAMP_SIZE 256 + + +////////////////////////////////////////////////////////////////////////////// +// type defines + +// basic types +typedef unsigned long DWORD; +typedef unsigned long ULONG; +typedef unsigned int UINT; +typedef unsigned int HANDLE; +#ifndef ULONG_PTR +typedef ULONG ULONG_PTR; +#endif // ULONG_PTR + +// structured types +typedef XF86VidModeGamma FGLRX_X11Gamma_float; + +typedef struct { + UINT red; /* red color value for gamma correction table */ + UINT green; /* green color value for gamma correction table */ + UINT blue; /* blue color value for gamma correction table */ +} FGLRX_X11Gamma_UINT, FGLRX_X11Gamma_uint_1024; + +typedef struct { + CARD16 red; /* red color value for gamma correction table */ + CARD16 green; /* green color value for gamma correction table */ + CARD16 blue; /* blue color value for gamma correction table */ +} FGLRX_X11Gamma_C16, FGLRX_X11Gamma_C16_1024; + +typedef struct { + CARD16 RGamma[FGLRX_GAMMA_RAMP_SIZE]; /* red color value for gamma correction table */ + CARD16 GGamma[FGLRX_GAMMA_RAMP_SIZE]; /* green color value for gamma correction table */ + CARD16 BGamma[FGLRX_GAMMA_RAMP_SIZE]; /* blue color value for gamma correction table */ +} FGLRX_X11Gamma_C16native, FGLRX_X11Gamma_C16native_1024; + + +////////////////////////////////////////////////////////////////////////////// +// exported functions from libfglrx_gamma.h + +extern Bool FGLRX_X11SetGammaRamp_float + (Display *dpy, int screen, int controller, int size, FGLRX_X11Gamma_float *Gamma); +extern Bool FGLRX_X11SetGammaRamp_uint_1024 + (Display *dpy, int screen, int controller, int size, FGLRX_X11Gamma_uint_1024 *Gamma); +extern Bool FGLRX_X11SetGammaRamp_C16_1024 + (Display *dpy, int screen, int controller, int size, FGLRX_X11Gamma_C16_1024 *Gamma); +extern Bool FGLRX_X11SetGammaRamp_C16native_1024 + (Display *dpy, int screen, int controller, int size, FGLRX_X11Gamma_C16native_1024 *Gamma); + +extern Bool FGLRX_X11GetGammaRampSize + (Display *dpy, int screen, int *size); + +#endif /* __FGLRX_GAMMA_H__ */ + +////////////////////////////////////////////////////////////////////////////// +// EOF diff --git a/fglrx/libfglrx_gamma.a b/fglrx/libfglrx_gamma.a new file mode 100644 index 0000000000000000000000000000000000000000..0f1258eb1e52d475ed747c7c86d8d4fe42c1ab39 GIT binary patch literal 5050 zcmd^DU2GKB6~1c^usG|iA%+?y6tk`toER~! z@qFfle*BbJdq_T+u}q_JZ__&RHlz6-;!Mm+o{XYT9ooR}9zuFw)uK^ZDSAa`TC5u}leZioQZ?lJDIjC<3zQ zzWVJyJU!4mbMu%p)$qZcQmHgOR|VO8GwN7 zTF^K{aMpx~jL8(w7y_EF90uQRUN1AgP$;?(8f#mMDEtq3ISNYTDsxb!Hux2Of* zy1JMyzB6=bF@4#ITuRvO1A)c%pthQQb|3)HK;oZyBd~@LJ87N%tOT1scnnDCT#<2|qP z!xiP4SK%J9^ioCtmePM0C?~=xIp0k!y{0tkmM)-YTrHdrVW9JKtXW`f^{;Lsi4*M$ z2b}Zh3oN`2E0$;M8e4h%`Ar zxvzgOatgoLMTe+(30~BKGDLzG5hDq^92F!O7LxV^!tWRc*ANEq>wSm8L&!#+=RX?; z@82^FKCXnp0>j|;YdrRHEa0r`EAddbG89&aK|cmRuiWwSj zSOUT5(%Er6lt$xGlCg{QMl3y9BTe?X_xcHY$aifR=R9A39=sV|S(Qgmeqwoj7_p5@h zZj7bxVPxT?TknwHGdB;|L!WpK*Uo=h{x)#(b@tSq*&?dkeB_q6`$J*t%2T#FSm8gC zUkGl7-}0TA!q6S~UfB31Zgj5J8T!P*98-7fn?rL(5uy(v!YRx94qL8ljFq)cZ3*{S zd5fM+af@nWH)aafE+O~RU=Q8FCFJQAK0(YCg4gmy=d_CFT-x{f~~^xWyR6*~^JCd)YP_9o*g-HM;GggzRx zVnRQj%L$!KlCqP^j>J;nWhDpW4Be=ZBRQ){=wq3@o=Rp;WHTdi-O|_jF4i+yE3RW* zkLRq|$O)m3WYg(*#=3iJ>vDENf`jAdx@?E=4s9;?`L0vlhk+ipI0nI|7+4EF$1`Z@ z(l0Bz8pt;69R!+sY+uDgeXpMP%h%Q8cQNgI^*TYjEu=b)K<`w2`0ddE9@n=4kGsBh z^l5J|9=4Y;$lW7p%J}pugc;c`LC;+i8SL{J#zTGAf5laLl(C(|!&G4{JgHTmA`ao-#Y_ouSZF5!0(@Oqr?X~q-e&5?=JmKVn6uQb@hAD58?S5 z9*)ldnd^*?Dsa55T1Mb9r+P&MaXmHS*<~?$jM(K?EgldBMH+DOR@i@WSuD0zZ5Blj zO+Q~>MgM6P{n;wI%ClsS=UwVH(mOyO!raV7&i@2yIK!m}Nh3I~EBO>Kgl+r=W2t`u zwA*NJ#gE+)FJ&e(iL5X^KZYg8lvU2lMeU1ca>;DQ%*4|16(*KNvPqeGZyfk9Z>P25KmxM}VBC7sz>r zlsrK>=1D1fnl$D)jWnnI-xFb9Lp;*ng9>*l+yj*Mfzm!u+E?-f<+QKpY0|V0Thcy} z_7UIGzQUaf_W-4RptKK^_LV$IIqYW@Jxv<+lPJ`*KTm}H4}rA*7lj*;Kcs7cwEq<# z?Kc8x{|P1Uq8#@76+K28_U9G7pzv*lf217t{syGIY7}MKs|9ktZ9t8OjOL>+h|oPi Hgzx_j3{WzO literal 0 HcmV?d00001 diff --git a/fglrx/libfglrx_gamma.so.1.0 b/fglrx/libfglrx_gamma.so.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..ddab3875fc6b584828951785e1299f0673b755ca GIT binary patch literal 10296 zcmeHNeQ;FO6~FrdE*MNe)F2es8Ub6fVG)r*O7k6I!e_#Vh4`|`ZnCSJ-MIS}!6B7& z$=K~SPAs&Y{-e$~{lXb*M@O*GF%l+-&Lo+RfUqRk&p;dMUGP4w6;yJ)KAOQMyTI2? z`}6&`fmXo!Ems7v+f1s6w9qQ=SXs7WS%uJQYFCw))oQD%tLv)jwfeI1+A2+GT5DT0 zqQ!MzOxHk$A|YL9EkIy3Z}lim)#p55z@vP3_u^+D5Op zE}+-=+S+_;eQoVpOE~J&#m2x^y&@Ly>4B=PdLR-HMI*ATIu!9&hT`pE-!`FbTpMT) z6IX{5@u1|F`LpcN)h9v`UGvVHzhI2lS9lkG20P-@Lt6qlLN%5q)Um;Az}i4tbW1>0 zHymne_Qa!}g+dGXeYy`OYKq4Vt+a;6D{5+&l~-unaq90rl&I2S|`1ILE|kFiBTvImYxn&VKAg#*2k=C~5%-@ucS z=1doKlYUgv%mz_2G0-DvR7eEpk=`L`vVx09w}S@G0_t3sJn77^U{hz`Y0SgvBo_)@ zy}EtqNV;M0a9@uFl>E~W>Fn!;_>TQlED{yzU7TdQjwZgAPVW21&``Rd>!?2K#3akp zJw3@@XG(I1jt)yD2Ktj!V%xZ>p)Z|$8V{$OMVTVh^~6)%PtT(M?gO)l3>&8!1~c

SRM-Pj`|$YC8+9Co<_7MY-+SupSoJobD*hyaUnB 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 C)PlMI literal 0 HcmV?d00001 diff --git a/gamma_2_2_bright.icc b/gamma_2_2_bright.icc new file mode 100644 index 0000000000000000000000000000000000000000..4d46b98f8be4bc7fbab98de5858f30ea6baa8038 GIT binary patch literal 864 zcmcJOy-EW?5Xb+?fw2f7!8D@9f{lVEF?K=3e5fE1!fBy`kYsPYoZJ_8n?yTbz_-xC zPG3dAO2LPaR2I(Wf=Lmui35B0+nfLH%(wmM*O9?J!EZOad4tn0d1K$Wk$TNxE=Af;=c50PfgXBjq)J^ z=Jshuu(GE~{Iv(Y8I$$+5C+GhInT zri)MnJz?b7c1KFTl+XA3{ajluw0{?H&)LC59VtWfEG~{N&D!v=XIjrhob)J;X9)Wr zA_39e57VcPlNZ1(wTPNeXVuHfOS*et&!H;lgj-VJ(@ T4zc(a@Yj62$KYf1Ka_p|TOW2Q literal 0 HcmV?d00001 diff --git a/gamma_2_2_lowContrast.icc b/gamma_2_2_lowContrast.icc new file mode 100644 index 0000000000000000000000000000000000000000..cf3e9b819df2570884f095456d7f84ba109fd2f9 GIT binary patch literal 864 zcmcJO&q~8U5XQeIU_F$g*o)|4!Ha^nRc|6<|EM4pBzjOmu-&X_Bx%BC+v?31@Ettp z!JEE{f+qzZLOgkJwp+A^f)^b~_P3dDcV>1cfPGSrmN!j_WGR+$|f9 z7}?DGoRa%fQ{r6Lhe{M*NZ)HJHp}POQn9$i%CgM`+ioYyZ?T%+avMPug?UyA0_JFG z!W@wZ*%5A@tu~d4R|5NE6(Cvrvb z50LEfcQ=dP&nOk6d9e5b$ZP_t8 Sq^xD&xB1T=AFuuYVdV>mvUY|5 literal 0 HcmV?d00001 diff --git a/xcalib.c b/xcalib.c index e5809d9..12dd9c9 100644 --- a/xcalib.c +++ b/xcalib.c @@ -53,6 +53,9 @@ #include #include #include +#ifdef FGLRX +# include +#endif #else #include #include @@ -78,6 +81,7 @@ /* the 4-byte marker for the vcgt-Tag */ #define VCGT_TAG 0x76636774L +#define MLUT_TAG 0x6d4c5554L #ifndef XCALIB_VERSION # define XCALIB_VERSION "version unknown (>0.5)" @@ -117,10 +121,11 @@ struct xcalib_state_t { void usage (void) { - fprintf (stdout, "usage: xcalib [-options] ICCPROFILE\n"); fprintf (stdout, "Copyright (C) 2004-2005 Stefan Doehla \n"); fprintf (stdout, "THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY!\n"); fprintf (stdout, "\n"); + fprintf (stdout, "usage: xcalib [-options] ICCPROFILE\n"); + fprintf (stdout, "\n"); fprintf (stdout, "where the available options are:\n"); #ifndef WIN32GDI fprintf (stdout, " -display or -d\n"); @@ -130,6 +135,7 @@ usage (void) fprintf (stdout, " -noaction or -n\n"); fprintf (stdout, " -verbose or -v\n"); fprintf (stdout, " -printramps or -p\n"); + fprintf (stdout, " -loss or -l\n"); fprintf (stdout, " -help or -h\n"); fprintf (stdout, " -version\n"); fprintf (stdout, "\n"); @@ -202,6 +208,58 @@ read_vcgt_from_profile(const char * filename, u_int16_t ** rRamp, u_int16_t ** g tagSize = BE_INT(cTmp); if(!bytesRead) goto cleanup_fileparser; + if(tagName == MLUT_TAG) + { + fseek(fp, 0+tagOffset, SEEK_SET); + message("mLUT found (Profile Mechanic)\n"); + redRamp = (unsigned short *) malloc ((256) * sizeof (unsigned short)); + greenRamp = (unsigned short *) malloc ((256) * sizeof (unsigned short)); + blueRamp = (unsigned short *) malloc ((256) * sizeof (unsigned short)); + { + for(j=0; j<256; j++) { + bytesRead = fread(cTmp, 1, 2, fp); + redRamp[j]= BE_SHORT(cTmp); + } + for(j=0; j<256; j++) { + bytesRead = fread(cTmp, 1, 2, fp); + greenRamp[j]= BE_SHORT(cTmp); + } + for(j=0; j<256; j++) { + bytesRead = fread(cTmp, 1, 2, fp); + blueRamp[j]= BE_SHORT(cTmp); + } + } + /* interpolate if vcgt size doesn't match video card's gamma table */ + if(*nEntries == 256) { + *rRamp = redRamp; + *gRamp = greenRamp; + *bRamp = blueRamp; + } + else if(*nEntries < 256) { + ratio = (unsigned int)(256 / (*nEntries)); + *rRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + *gRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + *bRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + for(j=0; j<*nEntries; j++) { + rRamp[0][j] = redRamp[ratio*j]; + gRamp[0][j] = greenRamp[ratio*j]; + bRamp[0][j] = blueRamp[ratio*j]; + } + } + /* interpolation of zero order - TODO: at least bilinear */ + else if(*nEntries > 256) { + ratio = (unsigned int)((*nEntries) / 256); + *rRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + *gRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + *bRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + for(j=0; j<*nEntries; j++) { + rRamp[0][j] = redRamp[j/ratio]; + gRamp[0][j] = greenRamp[j/ratio]; + bRamp[0][j] = blueRamp[j/ratio]; + } + } + goto cleanup_fileparser; + } if(tagName == VCGT_TAG) { fseek(fp, 0+tagOffset, SEEK_SET); @@ -245,6 +303,16 @@ read_vcgt_from_profile(const char * filename, u_int16_t ** rRamp, u_int16_t ** g uTmp = BE_INT(cTmp); bMax = (float)uTmp/65536.0; + if(rGamma > 5.0 || gGamma > 5.0 || bGamma > 5.0) + error("Gamma values out of range (> 5.0): \nR: %f \tG: %f \t B: %f", + rGamma, gGamma, bGamma); + if(rMin >= 1.0 || gMin >= 1.0 || bMin >= 1.0) + error("Gamma lower limit out of range (>= 1.0): \nRMin: %f \tGMin: %f \t BMin: %f", + rMin, gMin, bMin); + if(rMax > 1.0 || gMax > 1.0 || bMax > 1.0) + error("Gamma upper limit out of range (> 1.0): \nRMax: %f \tGMax: %f \t BMax: %f", + rMax, gMax, bMax); + message("Red: Gamma %f \tMin %f \tMax %f\n", rGamma, rMin, rMax); message("Green: Gamma %f \tMin %f \tMax %f\n", gGamma, gMin, gMax); message("Blue: Gamma %f \tMin %f \tMax %f\n", bGamma, bMin, bMax); @@ -253,21 +321,18 @@ read_vcgt_from_profile(const char * filename, u_int16_t ** rRamp, u_int16_t ** g *gRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); *bRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); for(j=0; j<*nEntries; j++) { - rRamp[0][j] = 65563 * - (double) pow ((double) j / - (double) (*nEntries), - rGamma * - (double) SYSTEM_GAMMA); - gRamp[0][j] = 65563 * - (double) pow ((double) j / - (double) (*nEntries), - gGamma * - (double) SYSTEM_GAMMA); - bRamp[0][j] = 65563 * - (double) pow ((double) j / - (double) (*nEntries), - bGamma * - (double) SYSTEM_GAMMA); + rRamp[0][j] = 65536 * + ((double) pow ((double) j * (rMax - rMin) / (double) (*nEntries), + rGamma * (double) SYSTEM_GAMMA + ) + rMin); + gRamp[0][j] = 65536 * + ((double) pow ((double) j * (gMax - gMin) / (double) (*nEntries), + gGamma * (double) SYSTEM_GAMMA + ) + gMin); + bRamp[0][j] = 65536 * + ((double) pow ((double) j * (bMax - bMin) / (double) (*nEntries), + bGamma * (double) SYSTEM_GAMMA + ) + bMin); } } /* VideoCardGammaTable */ @@ -279,9 +344,17 @@ read_vcgt_from_profile(const char * filename, u_int16_t ** rRamp, u_int16_t ** g bytesRead = fread(cTmp, 1, 2, fp); entrySize = BE_SHORT(cTmp); + /* conecealment for AdobeGamma-Profiles */ + if(tagSize == 1584) { + entrySize = 2; + numEntries = 256; + numChannels = 3; + } + message ("channels: \t%d\n", numChannels); message ("entry size: \t%dbits\n",entrySize * 8); message ("entries/channel: \t%d\n", numEntries); + message ("tag size: \t%d\n", tagSize); if(numChannels!=3) /* assume we have always RGB */ goto cleanup_fileparser; @@ -327,17 +400,12 @@ read_vcgt_from_profile(const char * filename, u_int16_t ** rRamp, u_int16_t ** g } } } + *rRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + *gRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); + *bRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); /* interpolate if vcgt size doesn't match video card's gamma table */ - if(*nEntries == numEntries) { - *rRamp = redRamp; - *gRamp = greenRamp; - *bRamp = blueRamp; - } - else if(*nEntries < numEntries) { + if(*nEntries <= numEntries) { ratio = (unsigned int)(numEntries / (*nEntries)); - *rRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); - *gRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); - *bRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); for(j=0; j<*nEntries; j++) { rRamp[0][j] = redRamp[ratio*j]; gRamp[0][j] = greenRamp[ratio*j]; @@ -347,15 +415,15 @@ read_vcgt_from_profile(const char * filename, u_int16_t ** rRamp, u_int16_t ** g /* interpolation of zero order - TODO: at least bilinear */ else if(*nEntries > numEntries) { ratio = (unsigned int)((*nEntries) / numEntries); - *rRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); - *gRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); - *bRamp = (unsigned short *) malloc ((*nEntries) * sizeof (unsigned short)); for(j=0; j<*nEntries; j++) { rRamp[0][j] = redRamp[j/ratio]; gRamp[0][j] = greenRamp[j/ratio]; bRamp[0][j] = blueRamp[j/ratio]; } } + free(redRamp); + free(greenRamp); + free(blueRamp); } goto cleanup_fileparser; } @@ -398,11 +466,14 @@ main (int argc, char *argv[]) #endif struct xcalib_state_t * x = NULL; int rv = 0; - u_int16_t *r_ramp, *g_ramp, *b_ramp; + u_int16_t *r_ramp = NULL, *g_ramp = NULL, *b_ramp = NULL; int i; int clear = 0; int donothing = 0; int printramps = 0; + int calcloss = 0; + u_int16_t tmpRampVal = 0; + unsigned int r_res, g_res, b_res; unsigned int ramp_size = 256; unsigned int ramp_scaling; @@ -413,6 +484,9 @@ main (int argc, char *argv[]) Display *dpy = NULL; int screen = -1; char *displayname = NULL; +#ifdef FGLRX + FGLRX_X11Gamma_C16native fglrx_gammaramps; +#endif #else char win_default_profile[MAX_PATH+1]; DWORD win_profile_len; @@ -481,6 +555,11 @@ main (int argc, char *argv[]) printramps = 1; continue; } + /* print ramps to stdout */ + if (!strcmp (argv[i], "-l") || !strcmp (argv[i], "-loss")) { + calcloss = 1; + continue; + } /* clear gamma lut */ if (!strcmp (argv[i], "-c") || !strcmp (argv[i], "-clear")) { clear = 1; @@ -528,7 +607,10 @@ main (int argc, char *argv[]) #ifndef WIN32GDI /* X11 initializing */ if ((dpy = XOpenDisplay (displayname)) == NULL) { - error ("Can't open display %s", XDisplayName (displayname)); + if(!donothing) + error ("Can't open display %s", XDisplayName (displayname)); + else + warning("Can't open display %s", XDisplayName (displayname)); } else if (screen == -1) screen = DefaultScreen (dpy); @@ -538,7 +620,16 @@ main (int argc, char *argv[]) gamma.green = 1.0; gamma.blue = 1.0; if (clear) { +#ifndef FGLRX if (!XF86VidModeSetGamma (dpy, screen, &gamma)) { +#else + for(i = 0; i < 256; i++) { + fglrx_gammaramps.RGamma[i] = i << 2; + fglrx_gammaramps.GGamma[i] = i << 2; + fglrx_gammaramps.BGamma[i] = i << 2; + } + if (!FGLRX_X11SetGammaRamp_C16native_1024(dpy, screen, -1, 256, &fglrx_gammaramps)) { +#endif XCloseDisplay (dpy); error ("Unable to reset display gamma"); } @@ -546,9 +637,18 @@ main (int argc, char *argv[]) } /* get number of entries for gamma ramps */ +#ifndef FGLRX if (!XF86VidModeGetGammaRampSize (dpy, screen, &ramp_size)) { +#else + if (!FGLRX_X11GetGammaRampSize(dpy, screen, &ramp_size)) { +#endif XCloseDisplay (dpy); - error ("Unable to query gamma ramp size"); + if(!donothing) + error ("Unable to query gamma ramp size"); + else { + warning ("Unable to query gamma ramp size"); + ramp_size = 256; + } } #else if(!hDc) @@ -688,17 +788,17 @@ main (int argc, char *argv[]) g_ramp = (unsigned short *) malloc ((ramp_size + 1) * sizeof (unsigned short)); b_ramp = (unsigned short *) malloc ((ramp_size + 1) * sizeof (unsigned short)); - ramp_scaling = 65563 / ramp_size; + ramp_scaling = 65536 / ramp_size; /* maths for gamma calculation: use system gamma as reference */ for (i = 0; i < ramp_size; i++) { - r_ramp[i] = 65563 * (double) + r_ramp[i] = 65536 * (double) pow ((double) i / (double) ramp_size, ob->u.formula.redGamma * (double) SYSTEM_GAMMA); - g_ramp[i] = 65563 * (double) + g_ramp[i] = 65536 * (double) pow ((double) i / (double) ramp_size, ob->u.formula.greenGamma * (double) SYSTEM_GAMMA); - b_ramp[i] = 65563 * (double) + b_ramp[i] = 65536 * (double) pow ((double) i / (double) ramp_size, ob->u.formula.blueGamma * (double) SYSTEM_GAMMA); } @@ -735,7 +835,35 @@ main (int argc, char *argv[]) warning ("nonsense content in green gamma table"); if (b_ramp[i + 1] < b_ramp[i]) warning ("nonsense content in blue gamma table"); -} + } + if(calcloss) { + fprintf(stdout, "Resolution loss for %d entries:\n", ramp_size); + r_res = 0; + g_res = 0; + b_res = 0; + tmpRampVal = 0xffff; + for(i = 0; i < ramp_size; i++) { + if ((r_ramp[i] & 0xff00) != (tmpRampVal & 0xff00)) { + r_res++; + } + tmpRampVal = r_ramp[i]; + } + tmpRampVal = 0xffff; + for(i = 0; i < ramp_size; i++) { + if ((g_ramp[i] & 0xff00) != (tmpRampVal & 0xff00)) { + g_res++; + } + tmpRampVal = g_ramp[i]; + } + tmpRampVal = 0xffff; + for(i = 0; i < ramp_size; i++) { + if ((b_ramp[i] & 0xff00) != (tmpRampVal & 0xff00)) { + b_res++; + } + tmpRampVal = b_ramp[i]; + } + fprintf(stdout, "R: %d\tG: %d\t B: %d\t colors lost\n", ramp_size - r_res, ramp_size - g_res, ramp_size - b_res ); + } #ifdef WIN32GDI for (i = 0; i < ramp_size; i++) { winGammaRamp.Red[i] = r_ramp[i]; @@ -749,14 +877,24 @@ main (int argc, char *argv[]) for(i=0; i> 6; + fglrx_gammaramps.GGamma[i] = g_ramp[i] >> 6; + fglrx_gammaramps.BGamma[i] = b_ramp[i] >> 6; + } + if (!FGLRX_X11SetGammaRamp_C16native_1024(dpy, screen, -1, ramp_size, &fglrx_gammaramps)) +# else if (!XF86VidModeSetGammaRamp (dpy, screen, ramp_size, r_ramp, g_ramp, b_ramp)) +# endif #else if (!SetDeviceGammaRamp(hDc, &winGammaRamp)) #endif warning ("Unable to calibrate display"); + } #ifdef ICCLIB icco->del (icco); @@ -768,13 +906,22 @@ main (int argc, char *argv[]) cmsFreeGamma(x->gGammaTable); if(x->bGammaTable!=NULL) cmsFreeGamma(x->bGammaTable); +#else + if(r_ramp) + free(r_ramp); + if(g_ramp) + free(g_ramp); + if(b_ramp) + free(b_ramp); #endif message ("X-LUT size: \t%d\n", ramp_size); cleanupX: #ifndef WIN32GDI - XCloseDisplay (dpy); + if(dpy) + if(!donothing) + XCloseDisplay (dpy); #endif return 0;