so, i am trying my luck again, this time in the jitter forums.
i need to convert sRGB (0 1) values to HCL values, but i aready fail at the rgb to xyz conversion.
the formulas i can find on the net are either java or some pseudo code, which i dont fully understand. do i need all the scaling stuff or do i need only the matrix transform?
from what most examples are telling me, rgb to xyz conversion would look about that:
vexpr (($f1>0.04045)*(srqt((($f1+0.055)/1.055)\,2.4)) + ($f1<=0.04045)*($f2/12.92))*100.
unpack 0. 0. 0.
expr ($f1*0.4124)+($f2*0.3576)+($f3*0.1805) X
expr ($f1*0.2126)+($f2*0.7152)+($f3*0.0722) Y
expr ($f1*0.0193)+($f2*0.1192)+($f3*0.9505) Z
there should be a working example for srgb-xyz-hcl in the processing language, maybe some of you would be so kind and explain the code so that it can be written in simple max. my current OSX doesnt not allow to run me processing due to the java version.
I can’t comment on your code, but last year I released a suite of shaders that perform various colorspace conversions. RGB to CIE-XYZ and CIE-XYZ to CIE-L*CH are included.
----------begin_max5_patcher---------- 1209.3oc0YtrbihCEFds8SgJV1UZWHgDW5UYlYwLK5Uyp4R0UJAVwQtwHOfb hmoq9cezEHltabLACxNKBtjPAN+e5necguLelWpXOqxC7AveClM6KymMyTkt hY0km4sgtOKmVYZlWlXyFVgz6F68jr8Ra847rOCjBPEiAn44fGo46TO551wW ZZkHc86CfMUdunPVP2vL25mJ4z712oh+el6.QK7aptbUptJ+mqoX2FdQNSZB N3gJE6jM01zzsTY1C7hU2UxxjVICg9wpGEHxbEhBz+fTOcvmz+Oec9b8ka5I ZR2IkhhNTLJw6kBWarJ+2sLaT4kRKV4A9TmpA9BpwmDpEPXj9ZPRy0AIlMrp J5J1OzOuMmVv.uG1kLICticaIqRkUQkbQQKEEFfMh.p6vAMWZSlCzDcLZN.R FhCsuWcDBHlf.FOPRtlKWjwxySyEYetKrEdZrUJdx7vv0kyD4eS4ifUUydhu T9ft53dxZL9LXcNuRYMnXdyeGg83Sy9lef5eRfCD9ErmTL9Gxh08IanxR9dP .39bAUFf.X.tqtmnwNqFEQL9LIImlzG0iPof6rJ3k3L53bFEasI7gVuOxY48 MD6Bz3aWDXGuRtH1EDehKrKBtRrKrrNJ4pvtfTOcWscA5xYWfGe6BrUg3q.6 BbB9BYW.SFavVmy.IWlUW.Q3QvtXHjLdvjbpYRDJxAVnvqiUbQ7MxDGbcrhq nPXaKT+KlEJjLN4mSnYXfkXvnwvL7joqX2lt55DOHIpchWv3m3sJeQUNMEb6 87bFX8pEe7czTzGe2u7aKVuuBbqVVOmTdKcmTnRO3Y.+t5MBlX2Sc14p76zB XWI67xPCiLqRKHH5rxPeMn8O9y+Bow6.HK5MDYwg9VxhbFY+8e8mQJ5N.vBe CAVTHxB1fIDr0Q5qDi9NXdoQCiPyhaQnIajegfWwTSgm8.s7Hyjm7FYhbX8D 41SCd7O.3Xmb9uMqJwZLE1bcr62ehWrT7D31G4U7TkyTWCUl5UvYHzv5xw0i K7sKcCNgtLkrhkrxtNjfqc7.igGRkFa5HAo.VIsh0kGqiHi88OX7TenSSh25 +rgIKEfftFWgm3IxGnySMU7MybGddSbKEqVk2Upwyq6dKsTobIq7NVAU4.09 i70ur.dgbvpL54E70gHMOT0ViJ99Opp4woq+aUdkXWYVSTUOiI3vQ.rjUI4E lyMnUazqCoUidfubIqnMDVxqzbwfN+N6BF0vAehvYCe4VgB40HAgIKH1wPpe BIGJc3EMZBHtGBHwY3D0KdF+53IzOzfvHnwytFnlRS.P6kDzeZmgHAbBokDL ktXRfLLIn+pdGRqMktTR.lLLI.g31iL0kl.In2T5o6Ehb2XSRehmP2EOQiQ7 78duIFS25MWW2CaJME8vn9n.r6HJtOwSvfHJAE1hnlRSwvdzXnfQrGNnO1PD 2EO8gOPGxm93wAQtKd76S7.cW7LJqubDim9rbQn6lC.RFi3o60eGgiaMKuoz TLGfJ1fmxvxc7rO1mNKZ5yzQtarXerxG5HQ61hoa29Hqrp9QZBD0V+WKJ0EC uwTjWXKZ1FtWISeHi11GXpgVp1UtTskb8AjqOYf8wgdy0umuN++gWN20T -----------end_max5_patcher-----------
i made up that max code from the same source you were using (easyrgb.com), but as it seems i have a serious error in it … srqt() instead of pow() … which is a returning error here … hence the weird output.
but so i was right using everything and not only the matrix transform, and i also understood the method how to interpret that quasi code right. at least.
can you explain what rectify() means in your shader and why you are using this where the source said *100?
ah you have the *100. in, i didnt see it at first. thanks so far.
I just got done doing this. Here is an accurate RGB to XYZ converter. Couldn’t figure out how to get my [if] expressions more efficient, but it works like a charm.
----------begin_max5_patcher---------- 2361.3oc6c00baZDE8Y4eEZzzmZcc2uYoOzYZeou2mRRmLdPRXYRvfFD1IMY x+8BrKxfMHt.BzJYlIibXAzdOm8du6GbX02uZ1hkge0c2h4+97+c9rYe+pYy xJJsfY5ims3Amutx2YW1ksXU3CO3FDu3Z04hc+ZbV4eHujfGevKv2MN6xw5B uKZyxziQ2fzkr0Id08dAatMxcUrx.HLYxoS9iH8OXY9my+n9d7VmUUgK+zuR P402cgAwANO3lcp+LxywufkD9XbtofJb8679V10iKXOQt6RvkSrWXPQahiJX SH8Gy+X5M8iqtJ8iq6Iy899ybXNGNygGGlCysFZl6c8m4D1vINx3PbV3gl29 qiWrJpYdCaOtgpzAi296iWjJDdSNtApnAi29miVbJDZSbrnsNv.24Gl7ceP3 VUvDQgtr1p4bzgfWqClH6q2njqN1M5V2.mk9t8HPiRugmZtjxdL56RU2w+2V W0kmRJNINEyWrzIXyhN4Y0MdEyzFJ.dUd54ULSk4234UNEr6p0HRqCAAkXbK ciZc.Mk7L0bXBhZBwyxzvDFP2NufSBmho1P4ThADKqrPpvn4TUfLDJEeJii6 O639kDP7pwk7M+46pI6GowdqwhrgMwXGj15b9OnbSJwX.jhtqVXjB+MBonBu fwIryNNYqymSRpo9WkLCs4XHZF0HNL0z5tHwskZLEZIOJBDsPdyPK53HPrB5 7hUluz+Q2OrxweUGGioc1mB7gHkVOiXZWGn8K9O6MlL6OY7IJBRyPIe+d9tO 4FsKYrSEP6rENa2Vn3YEtkTZ8SgYeQhq2WjWfpH79hhbexK+9o6K0IJgEiSn vGiTbvWkhEpSlzTdU9stek3xVqFLNKWEEmwwLJ6YRNoUeie3pO6ttvvZR3ms tAdAEGYXoSu18NmG8iusZ1s74uyYkas2bkMkyVrIxacXPpQT5NSKNu5RGfZF 13EAS1UD3rshadWBNdb2RmnTZUOLNR9IiCC8Kep8sjIQENAdO3D6F6oLVBZ+ Wp2CaiRGaWwJRMJw62sJJz2uzWk5LOUwYVmzXux8KdqiuuzBIkdljK2aadSv h8bzZuMt6hKWVrylckKozSGonWXwv8Rkenv9xg9+bRa99Tg0Nrh5WGwr3dhL KmHk+xv+WsrQ3h0T8NO0le7.4CNTNAUxxY4IL0QZlFaZyZGYhtzISzM1bDum NmTb1reUGbH9z5M.ehr1+7i5n6Ib5De4SmXY2cOYn1QmjoTmMQlfScxuv8M+ s4IiRjy6YGQjZVQtWxlL5kMa9KoIN6KahsE.YS1kMatM7KyI2v5ouoZcrZNs IiewGoStwty8oiSlxNeOc9r9SpkNEW1zo2cy+o6vy+izHdFhwmGeuaPVQt96 bmmXcjzipktwfREju3QM1OES1U5lzQ5tv5yNFNuDNumSWBSwv5ymbIjWUUGc 08KeFQ7r3bBO+yZc+pmSJB7bA2jsnEFCX0SWAJVomyXUOWBnXkbZwZFrpEpH HMqRILjhgEUW4y5sz2YSbwyKeouWPcqVWFbROe0jztvGiVkaA4orlWFaqc2E 6Ere0b+2m6m3EW38dqWWd0SUK33tzkuTsPwfZRaqMiAZxUfsSkImtvOvnYyw jgRyTywjIP8LLFS1FJKWgGzIylg5LWgKzoxl4f4Yyw2HKkKFRRCgYYyfRzYN Y5pf9p1lsg5O+f25sgIcvq6jFqeSGrTqkfdBwoGUtRMHjhNJHEQMdjxOJsoL 6SFP4CsyagFwSqyKencd0HUPK57ldjohT9QoM8D57Bd1GlyfLqvTpwl4GIaV u7N4B2YwNmmbWeaRUjLi0achii7V9XrZBgE0bTeUWSyp2oERNoRi3.UdcU5F +vkN9ZUVs+dqPYKW8LIdrTv1lHW2f22EIrokzuRBaVzCIgM9jD1NFRXKawaX XzjD1ljv1Hsv27zdQop2J2K8E9NK7BLVOqW3aZ6v5Y8BemosEtsgsv2WadZR Undj11vdtfR6IgU0jWGbxT9FPze3dn2BsyoDnp+DVW97oElS5o6IX57Mf6Ik aI5JcplIDb5bJ0YyjIzTmbzjlTaLRGKIvTQI0ZRSpMylbIP1TNoI0l6EBALs I0dRSp.FijhNAnIUzjlT6ilTUoBHBnZRkLoI0FHyboG1njTMoWbhgQAafedL lixNRmy0YlbvDxyN4fkN2gyL4fAVZilCKKgxxU3zexrYnNyByQ0qbnptqB29 S1yJm.UAaHyxlAknyb7MXP8Mj1cTvHBkt+UOUfhGM1JFALRk8CoT0q9CRMQg R6EJFFR4niARYxSEPo1CsyagFwqKAaiEox9gTcXZgiLUj1Ym2RsomPmWvCK1 bF8CE5rOn1SJX6hRAaQtqeWWzulZeoCxNvFaR9ZcR9ZB0dLMEgJrErQkxI8q MoeswQ+ZBTAkSd4qeMdKv5kvKtMTrdNqeMrN6obR.afB10+z6.PyUVSpvnor IvISwafMAPrMsuNmRJPIBQt74SBlH5o6IX57MvlpHCSX8ce.DJchlRc1HYBM 0IydR.aMO9GrkMPMWIlTvF.5T8KYG.57hei.rO5VQylRnBWgLoGvlYSBBX2P D7jf.O3XNUuC7J5rYAARlDDXeDDXdlUBEnh.wXyQQfCiJ1fp5.r4rmJIHmep X67aSMSftbUwl4XxRnOSTgAYyP2iiDlSNCFX0BZNJBiBkmIlCOSgtEBQMm8N NBz7FRqtJZD0n7T6my4i4K8nQV0HvQpneHkn2G1TOQDBwbQJy9XzlxNcMong 14UspNFfyKZncdKiTsyqIizN67VBomNmWL3gEyMmAYhApsbBZREaljJ1xZIJ O2Ykn1doGfVZautkuz7Iqae7sz07pF7W2X+JM1A1b3.LG43YNV.LG6wyb.XM rQyZH.rF9nYMT.ViX7ZofXN3QLtBRiEd7ZsvHH1y34KmVSjlLGZClyqFMMK6 2kah5m.Kpb+QOWQGM.vgB.Lb.PPjh.PKV4AB.Bn.fzB.HU+xniI4xLH+nAB. 3l..ok.PTrE.q1p.GRWHP.nEtPXKdgVfhGM..fAE.sHHV6yna.z+lxOfg.Ml SD0ROHFtH.PVCcRHP.nMdPLYA.ne5VCj8yfZ+svARGAqB.JbPiluZn8u3UpH 0xewqRwKdMJd8qPQcu9DI0yOt5+AvZHoL -----------end_max5_patcher-----------
http://www.brucelindbloom.com is also an excellent resource.
RGB XYZ matrices can be found here:
Can one of you gentlemen tell me how to make use of those .jxs shader files? Also, what is the best way to perform standard multiplication of matrices? I tried to multiply matrices using jit.op. only to discover that I suck at jitter.
you can get [if] more efficient when you use [expr] instead. :)
later when i am at max i will compare the results to see if my code is right finally.
i have yet to work out lab and luv – and if these are really getting me closer to what i was calling "hcl" above. my first aim is to get a perfect luminance parameter, and check out how big of a difference it makes compared to HSV.
oh, and i just saw that other thread. i find it interesting that you ponted out that rgb isnt a colorspace. but from what you say this also would mean that you can not "convert" rgb to srgb, isnt it?
i wonder in this context how one can be on the safe side when trying to convert R,G,B channels to a colorspace.
is it wrong to assume that a photoshop picture (which did not make use of custom palettes) or a quicktime-encoded movie file from after effects or u&i software provides or "contains" srgb (or at least something similar, like apple rgb) when used in max or jitter?
Yeah, you don’t really convert RGB to a colorspace as much as you specify RGB within a certain color space.. which is simply a matter of defining how the primaries mix together to form other colors …which all depends on how "white" is defined and how much red, green and blue is used. You can think of this ‘space’ as a way of scaling and interpolating primary color values to generate a spectrum.
sRGB is usually the safest bet, but it’s not ideal because it’s limited.. and lacks certain colors. Other spaces can be too big.. and go beyond the range of what we can see. That’s why XYZ and L*ab spaces are so useful. They both emphasize the range of what we can actually see.
A good general rule is that unless it’s specified otherwise, stick with sRGB.
This is the best calculator to use for checking your results..
i wonder if photoshop really jumps between colorspaces al the time, or if it not uses something like a 10-bit long table for scaling the "luminance" or "saturation" parameters before applying them directly to the individual R’G'B channels. (in max we could use a signal buffer for storing these curves)
normal people would probably just stay with photoshop and after effects, but well. i had an hour left today, fired up max, and got that lch stuff finished.
if you put the RGB 01 to XYZ, XYZ to L*a*b*, and L*a*b* to L*CH° conversions all in one patch, that will really look a bit weird in max/msp.
dont forget that when you use this data now to apply a change on the luma parameter as a part of a luma-depending blend mode, then you will have to add another bunch of cryptic math to convert that back to RGB.
and here are the individual patches.
the code is optimized for speed (which might sound like a joke when doing things like that on this platform) and the outlets follow a strict right to left order.
i would be really interested in the results of a clocker speed test between my versions and the ones from metamax.
hey Roman I think in this expression:
vexpr (($f1/$f2)>0.008856)*(pow(($f1/$f2)\,(1./3.))) + (($f1/$f2)<=0.008856)*((($f1/$f2)*7.787)+(16/116))
the 16/116 is going to return a zero as it's an int/int
I think it should be 16./116.
or even better just use a literal (0.13793…)
Roman, those are great. But given that my patch takes three separate ints and yours takes a list of floats.. it’s not clear how to design the best speed test.
In terms of accuracy (or at least getting similar output values).. both rgb-xyz patches output identical values (to six decimal places) about 7500/100000 calculations for red, 8000/100000 for green and 5600/100000 for blue. The mean difference in non-identical output values is 0.000002 for red, 0.000003 for green and 0.000004 for blue, respectively. Those numbers were stable over 100,000+ calculations. So accuracy isn’t the issue.
In terms of speed, depending on how things are tweaked so that both patches take the same kind of values, the results can vary quite a bit. It seems that processing a single list with a vector expressions is a lot more efficient than processing three separate inputs, but the time it takes to make a list (if needed) slows things down. iow, depending on the original source of data, your patch goes from about 70% faster to negligibly faster. If the source data is three ints, then you seem to lose much of the speed advantage processing them to a list of floats… Whereas, I don’t have much advantage either way because of the lack of vector processing in my patch. Or something like that?
It’s all interesting either way. Thanks for the input.
well, in a real life situation i would of course use [110.rgb2rgb01] – or [pak 0. 0. 0.]-[vexpr $f1/255.] – before going into the XYZ transform. feel free to add this at the beginning.
normally mine should be way faster because i saved tons of connections compared to using + – * / objects (except for the right to left triggers, which i am very anal about), but one never know, in some cases when you pack everything into expressions you calculate things two or three or even four times (like the atan2 variable in the 2HCL tranform), and expr is 64 bit internally (though am never sure if that makes a difference for atan() or log() calculation time, i only know it does for + and -.)
but doing all in float ("110.rgb01 objects") seemed just practically. this 3-stage conversion from rgb to hcl is the best example why you should not output int, int, int from _any color abstraction.
"lack of vector processing … or something like that" … the main issue in my version is the higher accuracy or expr, and the main issue of your version is that you are sending so many data via max connections at the patcher level. integrating [+ 0.] and [* 0.] into [epxr ($f1+$f2)*$f3] save you one time "a float is sent from + to *" which needs like 10 times more CPU compared to what happens inside expr.
btw., i am very proud of the elegant solution i found with that loadbanged list of constants. :D
thanks for checking out! expr should normally help to get more accuracy, too.
but when i was asking myself why they show you only 4 digits after the comma at easyrgb.com, i noticed that you will never need more accuracy than that, not for calculating something which ends up in a rounded 3×8 bit format.
last but not least, we´re not even going to use something like log() or a 8 decimalplaces shifting or range mapping here, where a high precision during such a calculation would be interesting.
in a C++ app you would probably try to do all these calculations in a 12-bit floating point space, that would be just fine for colors. well, or use translation tables for certain effects/parameters.
no, an int in an expr which contains a float variable just treats it as float. the symbol "16/116" is already parsed into the objects as floats. (not sure if i am using the right terminology here)
expr gets it mode from the $ variables only (if there is one. in [expr 3+3.] the presence of at least one float sets the mode to float).
sometimes it would be cool if expr also take ints when it is in float mode, but that it cannot has something to do with its general design.
i should still change that to 16./116., for better readability, and because i dont want to be inconsequent when it comes to style.
or i use 0.13793, which of course would be faster.
sorry Roman, but i tested the 16/116 and it returns a zero (0.00000) in an expr object– looks like it has to be typed explicitly with a point
but I made a speed test comparing your method and the jit.colorspace method (which seems to return spurious values anyway), and your patch is nearly twice as fast (about 75% faster) on my machine:
----------begin_max5_patcher---------- 3306.3oc6cs0iahjE94t+UfrxCscb6PUEEErZ2nYhzpQiTlWFsOrylLpE1lt CYnAKCtSmLJ+225BXCXtTkuPCNLQicaJi4TemSU047cNT72We0n4gO6FMR6e n8Asqt5uu9pq3GhcfqR97Uidz44E9NQ7u1n.2uDN+yilJZJ184X9gWo4E3Ee 2hvfnXmf3nzuPvlG8B7ci4mLH4fqbhW7IufGtas6hXwEGAgyzmpAzsXuYoy+ .8u09yjywaI+5Pu12Zl9ieeXPbfyit7V940dN9YtrgahKdcEGJ9qqbEWzQi1 9yy9oh79FuA.6pmQRcWmfGI.B8a6469j65HuvfL+9WMxY0pLG9pLmBCE+bH+ Gxb51C4EHNDX6gV69jW54i1dTm0T7JlBVaVK5rOaYNRz32uN8huCL4nG+ESC 9aFL.MsuR0vO3Gt3ub4Hpd5ACW4F3ErZsajaPrSbhLrs4kt26rwO9txAp7se uyB2JO4RUXWM5g0dKCCXBQtyjc3zK2GzL3clrcEd6ANqJ4ToFhwahl6rlgny 84+DvzFiCC8y2zVkH092Iv6QmX2XOgnB029i583p0dAw4tPtANzeiOEsXcnu eteJQKOURKKo54EtewaY7m3+VYAR5W2aUpBXzVDZo2CtQw4OVryCQ4ORtAzY M.yNvN2wqa.d9A49gNKm6D7P1FKa.dUCxwhg05BSy8FiWbbtU1qSNSmewMv8 ImBhw9C3KePOuGj6Zl0l1dldZCe+5qS+iomAvzKJVyFOS2vz1lvQE9zeVVHc cTkPLRJHFIdyD0DFCzOOfbaAvbfoRvRWFvRLEIDm9ZUPE7jYusH7wGcCRFJe BACwk93FcBEq.2LbfpFNzUnutapbeufpl4hKsr1KGDhB2rdQJbmLygVdAmNq ZrWv1k09vNq+BewO4sbY9ERDy8FwlIWrhoTZLUEYnjhrUmQhKA7JWjQmHQV6 OuNqGOihbdxc4czq.0D9Nm330dy2DKLgx5r1w5YRyd9nvB1kJD0bwq5hR8fa tieh6oaO2R7K35cfH+UglWFO8ofYLsKk5IbFGCy52Nh62tAZqKmY7zTUu+I1 hYfResLm+AJ5hexruGP+uxHcV6DrL7QuHZbAJ1OIjLA4XZWWPNHxPTNCQ4LD kS6GkiX3M02GyJ8jBVumT.hU1.cLZzIbyJcBOm4ihNdx0fU4FNyptcBz4Dfm .C0vSx.dJeb3MCmVWxv4JmE+klG6eGYL2P954FjFgS6yBb1ZX4QExMP2VoXt w+fDzMQR7fzgi5lorjKr6tSPrxKyjdnLa1cHKvVRYF1cvYfzzHY2cjYhJxLn aHylpHyvAlj5aLIcFXRAl5CqDTo.sFnRYfJkApTFnRYHz+ApTFnRYfJkApTF nRYfJkApTFnRYfJkApTFnRo2SkRr1bs4GV0nHV1zxpVFTPpxfBr15wYZAuJJ 0GqipbkTrhbLZtvifFuzUdzAojSHJS7JBNCWiVF180x26GREAUAAfgIW0Bf6 BSiUxYkd2kfqFEzdmOMDm5whUNqomSr656Dj4jYRk8wIZ2wItAfBbP.Ukbt9 e90e6e+62cyiQiOPTLgyUaPciVLspCEC8Wp8qwN9dKpeLESrWD5K37jQSIxf XZLsj+.jQLp.kKGcg8bpaMDlzhxvDf30gIjwG9.6sCr2dbz4Duc0FkiEGwmb .amNQa8z3XhNKz3T+M5S6QK1sT88gxun.HAlD1B2njUwpFIwvyBRleBz8gRT aAkwZ2qc+wYTBDNAIAVdvjKBaFKm1g.0Eq1rfsBwwgqV1LX0D1DrZpeAXhdT D2JvKHRNdJMMuv4sMANzAL6GIvitLuslxx+hIpyvyUIhRExb24tkyT168Lb2 gOQrr71xVDuivmHdepMqQl6H3rr2JkljgaLw9+MlnpULlLT88heSFt4adrhJ f9ek1MgM1ME2Jk3ZqKN.VU99PRw22z7Ejvof1uSNLI38UJTxn2fRO5FE47fq pXAvVP9OQbS3lDwY4ngcKTJkmR1N+8e4c2912+yu6N11sQzANXBfD.DvrNhi glGFwwphPfdNikjjp6QLQrchC+CLVNvX4AF6cEaMAPgEFFV1VSfxAsCSHZmb z6NJJT5Ymq.1Oq0vGTjkHBGi.11Mw9aOuF9pAKiV336pcaxV6D8EcpMStxvi EVyhvMBULrJ.2rA.WWf3Ht8NQvqjcqWiz+.g3LOAvpf33KbD+LafSxXemjTo 5PaiKVz9I2mWsV6U2CdCEmmcnLtJvSCtSsjFqY8KWzbk15Gle6ae9qe63PxD Lr4k5N3rygpEJml7+0BoE6H6haHO5UY7CUECQgSurXIpHdhpiono3JxEaQg3 KvbsgsXp4DuPvj7JkxCwPhvLjITiFC2PxPNpIrCYB8ngvOZLDjFBCowPQpJb j5CIo9vRpOzjZCOopPTJOLkxCUonodw4f1q8lRTVsS3T4M5.TW38gfoFb5q4 z70LyS8INau.O9eix111YjyOqb2.YfDfxHC5vQl+nGgLpCLFGNv7eaCfoHO. 0FReM3BmYO4gEb8vRQcQ8N9rGxQcHQGnw2afumWqKs.PtmGR48Rh6x4MTeNm PmoEXiF+Z5GfzO..1P9GPzOXi0wiqUafjalM1Z2BRVPkd++sW8.T7hV+lX7o QkUwFZb2PIAAPysJIB.uSIoSfviVIAEYHPIkDYPIUPIY.fFaURHLwbqRBXcB FIAUWGYMniXoTLfy.JiKiY4qayCcc2c2X35.YzC1Gsd.0jdnPMHVZwH1MUOB BPtgMH5sz4yLzMvimbypvubC+XuldLLd7a.7293GmBmYLdr1q4i59m+qcmAi BE.bFcArwSXLWcZzyHQlsLMkQOmaq2uCNfKefj6Ujb6qnKqPcJQcuWA6rWcQ USM6XU52szx1o5R2QIy2ioWATnWA5M8JnB8JXuoWIqEH4hzBjbQZARtHs.Mu Hs.MuHs.M6MVfVJXAZzar.IJzqP8ldkoB8JXuoWgUnWs+CelNa2pBQs79k8Y pakTh5EyaVSkpdwTCdpxpkbYP6.RjSkBVCBTcBR8kzdYk0ddEv4NI1O+0uc6 a8cp9l00PpxqHoJhrsZbWWaHK1m+rXalxnfX66vJYOq.MjG6g7X+hmG6RS8V UOgvvHVpGwUUEtGTZ6vhM5BLR971ALNqItqGkkbDzPrM.oq.5c3ICd9j9Cz. HHkglinzJb5QPCDpLxbDkVw6mzAx7crlO6em.jiWiAb2rP.nLIGv37mDnRc3 pam3T3su5dz3IvlRXCRtIA42NnVYps3lzJ3gTjlMM1TsAb7DbSZCnby6pr1X nxO1oMX2QBSXpiao+wwpMRlvRIkwPEdTH8zugoMX4nV2xBallj5zF93GmdCX 1aPyFKRO81F3IoN8T1c3IjYDKx3WeCU89Flxd73SiV1J4ljyrcJMgKAkr7EH BRVsfHPFnEVpBG.7igZ3zTfmVV78UHUhTD1+iT7jfc.LVYrCcVwt+n+TXwvc axWRBcm2JKt1Zxt0p0GfghICAbwk99gjmNj7zW3jm1a5UFWjElkghkES+oWI aYwf6OYuWoAV8mQV.jp8q9wJw.np8q9Q4YUgo0PUjLTEIsytVbRUh.ja+OBP 5za.RG2NVrfrLnNVRrvtCuiEK6l+Ka5GTmX+c0t+8nDyP1mXacmGLdJXVzcj XfjRLnyHwPIkXX+5QhmQ24o3mr6H61cGTFqfH2QdtCZnfH2QLLjczmYmRjkZ JNbmRjkZcDig8h893dw9AtkSKbZVpcbZbecGm9ydwwtqOvGHkI63zI6S8Uri SaLrgSKyFNsIvRDulnF5wbaOjNYXGmdXGm9Xu6a9luVjOUr0.G5S3MrfQEws 6gg8Y6luA13MeSGXG4jNm4LucyZpLyLBvDXaJ1GNZBLIVuf2JSsGhxeDpFsh NEj1OQmOaSLaQJsehJ2r+98SblLeh5aZuxoJDy1BDO1UP07bgiXdVrro8+6n Sbs164FzHfSpFIueQ4UIQtwKb88ot6pqsx2Ivk99Szkro.z9MA3M8JPYsAEs AKqMjnMzTMwSajJzt3iZVKbhWJbeVL0qQ4BuX2DgYCvDFXZFZK9jyZpJCbjy eAEOgkwM9fS05kcLid24gpHVoGphDiK3zSXIfBQ4a2LVXoqd5IduybwlTI86 1ZopPV5Or5POmBsjj+CR2gkIhzO+7r5Nxrr7OR5NoXgHKyzjNDNa0x4EZfNu SBcdbMQ94hEjbUz.Hgpq54wUlRUae889558nbSVowTBoAlaCk5rJNFRHN3VS ZPDIDGi1SWYIioCt0jGnkrFOsj7HiwrcqY8.kwXFhZO3AkqqKimHme4oI7Az dCufvNF9.kAeZwg6xrxUAg9bJO.b2ReUPUTA9zhxiQGCejY9vBK4Ju7H7KqP dxXhRg7iUH2X6mWrpxIF8578q++P4MFsA -----------end_max5_patcher-----------
converting the list into a matrix and then back again takes some time, but your method is still 35% faster than converting a single-cell rgb matrix to lab without converting to and from a list
wow, you are actually right.
can it be that i have never run into it during the last 10 years and during the making of almost 1000 abstractions using expressions? it seems so.
the second factor which my wrong assumption is based on i also interesting: not only that i was probably using 16/116 in an expr for the very first time, as it seems, i was testing my patch against the easyrgb.com calculator only for ($f1/$f2)>0.008856 but not for ($f1/$f2)<=0.008856
that is a classic! as soon as you leave the path of proper scientific methods to build you knowledge and make assumptions … you are wrong. :D
but it is a pretty weird behaviour, dont you think?
[expr $f1+16/116] returns 0, but [expr $f1/116] is performed in float.
this is a bit inconsequent, and it is not even reproducing the look and feel of other max objects. i wold understand when the divisor is determining float or int calculation, but [expr $f1+16./116] will also work.
now guess what happens with [expr $i1+16./116] … and then explain me the logic behind this.
i´ve just checked some older patches of mine (where i was using things like "1/3." … normally i always used one dot .. so luckily i at least dont patch based on my wrong assumptions.