<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 5 Ð°Ð²Ð³. 2022 Ð³., 20:05 Einar Rünkaru <<a href="mailto:einarrunkaru@gmail.com">einarrunkaru@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
On 05/08/2022 08:08, Andrew Randrianasulu wrote:<br>
> <br>
> <br>
> Ñ‡Ñ‚, 4 Ð°Ð²Ð³. 2022 Ð³., 14:36 Andrew Randrianasulu <<a href="mailto:randrianasulu@gmail.com" target="_blank" rel="noreferrer">randrianasulu@gmail.com</a> <br>
> <mailto:<a href="mailto:randrianasulu@gmail.com" target="_blank" rel="noreferrer">randrianasulu@gmail.com</a>>>:<br>
> <br>
>  Â  Â <a href="https://ninedegreesbelow.com/photography/lcms2-unbounded-mode.html" rel="noreferrer noreferrer" target="_blank">https://ninedegreesbelow.com/photography/lcms2-unbounded-mode.html</a><br>
>  Â  Â <<a href="https://ninedegreesbelow.com/photography/lcms2-unbounded-mode.html" rel="noreferrer noreferrer" target="_blank">https://ninedegreesbelow.com/photography/lcms2-unbounded-mode.html</a>><br>
> <br>
> <br>
>  Â  Â It seems not all icc profiles are the same ...<br>
<br>
Conversion from one profile to another may be done different ways.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Well, I was amazed by existence of unbounded mode (where values can be less than zero or more than 1.0) but I guess Cinelerra not ready for this )</div><div dir="auto"><br></div><div dir="auto">Also, I was surprized there is more than one method for describing those tone curves ...</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Profiles are of course not the same <br>
<a href="https://www.color.org/version4html.xalter" rel="noreferrer noreferrer" target="_blank">https://www.color.org/version4html.xalter</a><br>
> <br>
> <br>
>  Â  Â I think for cin-gg it makes sense converting from biggest rgba-float<br>
>  Â  Â (32 bit floating point value per color channel) , and for CVE from<br>
>  Â  Â 16 bit/channel int format .... (I think back in time Adam deleted<br>
>  Â  Â int 16 formats from Cinelerra 2.0 as opposed to cin 1.2 saying they<br>
>  Â  Â were not as good as true 32 fp)<br>
<br>
32 bit fp is not 32 bits - it has only 24 significant bits. Fp pixel <br>
value is 0 <= value < 1.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">Yeah, thanks for correction </div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> <br>
>  Â  Â I put some emphasis on opengl output because it offloads some of<br>
>  Â  Â per-pixel math to graphics hw, but slower sw only mode probably will<br>
>  Â  Â work as proof of concept.<br>
> <br>
>  Â  Â As far as I understand you even can have colord daemon monitoring<br>
>  Â  Â hot-plugged output devices incl. monitors and providing associated<br>
>  Â  Â profile via some api (?) yet I only compiled it and newer used ...<br>
> <br>
>  Â  Â It seems at least two display pathes needed, one for traditional 8<br>
>  Â  Â bit displays and another for newer 10 bit ones. i thought because<br>
>  Â  Â color profiles known and used ever since 1996 or so, 8 bit output<br>
>  Â  Â can be done first ..<br>
> <br>
>  Â  Â I'll try to find simpler lcms2 examples ...<br>
<br>
Cin should detect the output device and select appropriate conversion<br>
> <br>
> <br>
> <br>
> <br>
> Does this example count as useful tutorial?<br>
> <br>
> <a href="https://stackoverflow.com/questions/22561176/lcms2-convert-cmyk-to-rgb-through-profiles-in-c-help-on-input-output-values" rel="noreferrer noreferrer" target="_blank">https://stackoverflow.com/questions/22561176/lcms2-convert-cmyk-to-rgb-through-profiles-in-c-help-on-input-output-values</a> <br>
> <<a href="https://stackoverflow.com/questions/22561176/lcms2-convert-cmyk-to-rgb-through-profiles-in-c-help-on-input-output-values" rel="noreferrer noreferrer" target="_blank">https://stackoverflow.com/questions/22561176/lcms2-convert-cmyk-to-rgb-through-profiles-in-c-help-on-input-output-values</a>><br>
> <br>
> It uses rgb to cmyk and two profiles, but hopefully one just can call <br>
> this with one real and one built-in profile? It was nice to know you can <br>
> do scanlines with lcms, too ....<br>
<br>
Looks reasonable</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">----</blockquote></div></div><div dir="auto"><br></div><div dir="auto">Also, littecms pdf documentation in doc folder says you can use same buffer for input and output as long as its organization remain the same ...</div><div dir="auto"><br></div><div dir="auto">---</div><div dir="auto">Scanline overlap</div><div dir="auto"><br></div><div dir="auto">It is safe to use same block for input and output, but only if the input and output are coded</div><div dir="auto">in same format. For example, you can safely use only one buffer for RGB to RGB but you</div><div dir="auto">cannot use same buffer for RGB as input and CMYK as output.</div><div dir="auto"><br></div><div dir="auto">---</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> <br>
> I also was reading <a href="http://ninedegreesbelow.com" rel="noreferrer noreferrer" target="_blank">ninedegreesbelow.com</a> <<a href="http://ninedegreesbelow.com" rel="noreferrer noreferrer" target="_blank">http://ninedegreesbelow.com</a>> <br>
> articles on color spaces and it seems some of our trouble with blend <br>
> modes with text and fades caused by (missing?) linearization, see<br>
> <br>
> <a href="https://ninedegreesbelow.com/photography/test-for-linear-processing.html" rel="noreferrer noreferrer" target="_blank">https://ninedegreesbelow.com/photography/test-for-linear-processing.html</a> <br>
> <<a href="https://ninedegreesbelow.com/photography/test-for-linear-processing.html" rel="noreferrer noreferrer" target="_blank">https://ninedegreesbelow.com/photography/test-for-linear-processing.html</a>><br>
> <br>
> I did some hack for normal blend mode using code from stackoverflow and <br>
> code posted in our bugzilla<br>
> <br>
> See<br>
> <a href="https://www.cinelerra-gg.org/bugtracker/view.php?id=559" rel="noreferrer noreferrer" target="_blank">https://www.cinelerra-gg.org/bugtracker/view.php?id=559</a> <br>
> <<a href="https://www.cinelerra-gg.org/bugtracker/view.php?id=559" rel="noreferrer noreferrer" target="_blank">https://www.cinelerra-gg.org/bugtracker/view.php?id=559</a>><br>
<br>
There are broken links - not very useful.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">Sorry, most likely gmail client on Android not very like copy pasted links....</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
If I understand right, the problem is related to alpha. When you mix one <br>
frame with frame with shaped alpha, the second frame "cuts" itself into <br>
the first. The result may be unexpected.<br>
> <br>
> So, in theory this (fast) linearization step should be added to all <br>
> modes, or at image-reading stage only?<br>
<br>
My idea is that video/image loading converts to internal format <br>
including linearization. What is mode?<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">If I look at right place native png reader outputs into rgb(a)8 or rgb(a)16 ..</div><div dir="auto"><br></div><div dir="auto">int FilePNG::colormodel_supported(int colormodel)</div><div dir="auto">{</div><div dir="auto">  Â  Â  Â  if( colormodel == BC_RGB888 || colormodel == BC_RGBA8888 )</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  return colormodel;</div><div dir="auto">  Â  Â  Â  if( colormodel == BC_RGB161616 && native_cmodel == BC_RGBA161616</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  return colormodel;</div><div dir="auto">  Â  Â  Â  if( native_cmodel >= 0 )</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  return native_cmodel;</div><div dir="auto">  Â  Â  Â  int use_16bit = BC_CModels::is_float(colormodel) ||</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â BC_CModels::calculate_max(colormodel) > 255 ? 1 : 0;</div><div dir="auto">  Â  Â  Â  return BC_CModels::has_alpha(colormodel) ?</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  (use_16bit ? BC_RGBA16161616 : BC_RGBA8888) :</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  (use_16bit ? BC_RGB161616 : BC_RGB888);</div><div dir="auto">}</div><div dir="auto"><br></div><div dir="auto">No specific icc handling ...</div><div dir="auto"><br></div><div dir="auto">I guess ffmpeg png reader also was dropping icc profile info until very recently ....</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> <br>
> Also, good way to put lcms transform code in our rgb2rgb function <br>
> (somewhere in guicast? ..but in cingg some of this code python-generated <br>
> and I do not know python at all ..), just with additional parameters <br>
> like pointer to in and out profiles? If any of them null then just not <br>
> execute transform call ...<br>
> <br>
I don't know python too.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">I think I found point where new function can be inserted for display:</div><div dir="auto"><br></div><div dir="auto">vdevicex11</div><div dir="auto"><br></div><div dir="auto">In function</div><div dir="auto">VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)</div><div dir="auto"><br></div><div dir="auto">// printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels);</div><div dir="auto">// printf("VDeviceX11::write_buffer %d input color_model=%d output color_model=%d\n",</div><div dir="auto">// __LINE__, output_channels->get_color_model(), bitmap->get_color_model());</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  if( bitmap->hardware_scaling() ) {</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0,</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  0, 0, output_channels->get_w(), output_channels->get_h(),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  0, 0, bitmap->get_w(), bitmap->get_h(),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  output_channels->get_color_model(), bitmap->get_color_model(),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  -1, output_channels->get_w(), bitmap->get_w());</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  }</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  else {</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0,</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (int)output_x1, (int)output_y1, (int)(output_x2 - output_x1), (int)(output_y2 - out</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  0, 0, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  output_channels->get_color_model(), bitmap->get_color_model(),</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  -1, output_channels->get_w(), bitmap->get_w());</div><div dir="auto">  Â  Â  Â  Â  Â  Â  Â  }</div><div dir="auto"><br></div><div dir="auto">So bitmap->get_row_pointers() can be used as buffer argument for cms* functions?</div><div dir="auto"><br></div><div dir="auto">I ignore direct mode above for now ...</div><div dir="auto"><br></div><div dir="auto">For initial experiments even just hardcoded path to monitor profile should be enough to see difference and experience speed lost?</div><div dir="auto"><br></div><div dir="auto">And for encoding this profile into media/file 'asset' structure must be altered first to hold icc profile type from lcms2.h and then encoder functions should look if there attached profile and pass it to libacvodec/libavformat ...</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> <br>
> <br>
>  Â  Â Adding profile to some video container hopefully will be not very<br>
>  Â  Â hard task (i forgot about this patch for ffmpeg's mov muxer from<br>
>  Â  Â 2019 i talked about in cingg bug ...)<br>
> <br>
> <br>
> <a href="http://ffmpeg.org/pipermail/ffmpeg-devel/2019-September/250398.html" rel="noreferrer noreferrer" target="_blank">http://ffmpeg.org/pipermail/ffmpeg-devel/2019-September/250398.html</a> <br>
> <<a href="http://ffmpeg.org/pipermail/ffmpeg-devel/2019-September/250398.html" rel="noreferrer noreferrer" target="_blank">http://ffmpeg.org/pipermail/ffmpeg-devel/2019-September/250398.html</a>><br>
<br>
This patch is applied.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">Thanks for checking!</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> <br>
> <br>
>  Â  Â Input side hopefully already covered by ffmpeg.git patches (input<br>
>  Â  Â image format icc profile only should matter at decompressing into<br>
>  Â  Â some pixel array? Because further processing will alter those pixels<br>
>  Â  Â ...or I am wrong and input media profiles must be somewhat combined<br>
>  Â  Â during track  compositing?)<br>
> <br>
<br>
You have to select the best internal format or you have to change and <br>
test 6 x N paths in every effect. N is in hundreds.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">But then is there any sense in making profile-based transfer functions to be available for rest of cinelerra, like in cingg's case guicast/bcxfer.C place? (Where BC_CModels::transfer currently defined )</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Einar<br>
</blockquote></div></div></div>