*/}}
Browse Source

Window soft proofing feature

YimingWu 1 day ago
parent
commit
73682d8dcf

+ 2 - 1
.gitignore

@@ -1,4 +1,5 @@
 build/*
 .vscode/
 screenshots/
-*.udf
+*.udf
+BuildResources/*

+ 24 - 2
CMakeLists.txt

@@ -54,11 +54,33 @@ add_compile_options(-fpermissive
 )
 endif()
 
+# embed func
+function(embed_resource resource_file_name source_file_name variable_name)
+    if(EXISTS "${source_file_name}")
+        if("${source_file_name}" IS_NEWER_THAN "${resource_file_name}")
+            return()
+        endif()
+    endif()
+    file(READ "${resource_file_name}" hex_content HEX)
+    string(REPEAT "[0-9a-f]" 32 pattern)
+    string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}")
+    string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}")
+    string(REGEX REPLACE ", $" "" content "${content}")
+    set(array_definition "unsigned char ${variable_name}[] =\n{\n${content}\n};")
+    set(source "// Auto generated file.\n${array_definition}\n")
+    file(WRITE "${source_file_name}" "${source}")
+endfunction()
+
+file(MAKE_DIRECTORY "BuildResources")
+embed_resource("resources/soft_proof_table_sRGB.lagui.lut" "BuildResources/soft_proof_table_sRGB.lagui.lut.c" "DATA_LUT_PROOF_SRGB")
+embed_resource("resources/soft_proof_table_Clay.lagui.lut" "BuildResources/soft_proof_table_Clay.lagui.lut.c" "DATA_LUT_PROOF_CLAY")
+embed_resource("resources/soft_proof_table_D65P3.lagui.lut" "BuildResources/soft_proof_table_D65P3.lagui.lut.c" "DATA_LUT_PROOF_D65P3")
+
 file(GLOB SOURCE_FILES 
-	./*.c ./*.cpp ./resources/*.c ./resources/*.cpp)
+	./*.c ./*.cpp ./resources/*.c ./resources/*.cpp BuildResources/*.c)
 
 file(GLOB HEADER_FILES 
-	./*.h ./*.hpp ./resources/*.h ./resources/*.hpp)
+	./*.h ./*.hpp ./resources/*.h ./resources/*.hpp BuildResources/*.h)
 
 add_definitions(-DLAGUI_FONT_CUSTOM_PATH=\"${LAGUI_FONT_CUSTOM_PATH}\")
 add_definitions(-w)

+ 13 - 2
la_interface.h

@@ -362,6 +362,9 @@ NEED_STRUCTURE(laAnimation);
 NEED_STRUCTURE(laAudio);
 NEED_STRUCTURE(laInputMappingBundle);
 
+#define LA_LUT_PRECISION 33
+#define LA_LUT_PIXCOUNT (LA_LUT_PRECISION * LA_LUT_PRECISION * LA_LUT_PRECISION)
+
 STRUCTURE(LA){
     laListItem Hyper;
 
@@ -671,13 +674,16 @@ STRUCTURE(LA){
     laGetBaseNodeTypeF ExtraGetInputNodeType;
     laGetBaseNodeTypeF ExtraGetDriverNodeType;
 
+    void* ProofingLUT[3]; //srgb/clay/d65p3
+    int LutNeedsRefreshing, CurrentLut;
+    GLuint LutTexture;
+
     //laHash256 RootNodes;
     //LLVMContextRef llvmContext;
     //LLVMModuleRef llvmModule;
 
     //SYSLOCK csMediaPlay;
 
-    int DetachedViewSwitch;
     int example_int;
     laSafeString* example_string;
 };
@@ -735,7 +741,7 @@ STRUCTURE(laWindow){
     int Activated;
     int Shown;
     int IsDocking;
-    int OutputColorSpace;
+    int OutputColorSpace,OutputProofing;
     int OutputShowStripes;
     int UseComposing; real ComposingGamma,ComposingBlackpoint;
     int IsFullScreen;
@@ -893,6 +899,10 @@ extern laPropContainer* LA_PROP_SOCKET_OUT;
 extern laPropContainer* LA_PC_RACK_PAGE;
 extern laProp* LA_PROP_CONTROLLER;
 
+extern unsigned char DATA_LUT_PROOF_SRGB[];
+extern unsigned char DATA_LUT_PROOF_CLAY[];
+extern unsigned char DATA_LUT_PROOF_D65P3[];
+
 #define LA_UI_NORMAL  0
 #define LA_UI_ACTIVE  (1<<0)
 #define LA_UI_EDITING  (1<<1)
@@ -2365,6 +2375,7 @@ void laAddExtraPreferencePage(const char* name, laUiDefineFunc Func);
 void laSetFrameCallbacks(laPreFrameF PreFrame, laPreDrawF PreDraw, laPostFrameF PostFrame);
 void laSetCleanupCallback(laCleanupF Cleanup);
 void laSetInputProcessCallback(laInputProcessF InputProcess);
+void laSetProofingLut(void* data, int which);
 void laSetMenuBarTemplates(laUiDefineFunc MenuButtons, laUiDefineFunc MenuExtras, const char* ProgramName);
 void laSetAboutTemplates(laUiDefineFunc AboutContent, laUiDefineFunc AboutVersion, laUiDefineFunc AboutAuthor);
 void laSetPreferenceTemplates(laUiDefineFunc PreferencePageDisplay, laUiDefineFunc PreferencePageInput, laUiDefineFunc PreferencePageResource, laUiDefineFunc PreferencePageTheme);

+ 54 - 13
la_kernel.c

@@ -1432,6 +1432,10 @@ int laGetReadyWith(laInitArguments* ia){
 
     if(MAIN.InitArgs.EnableLogStdOut){ MAIN.EnableLogStdOut=1; }
 
+    laSetProofingLut(DATA_LUT_PROOF_SRGB, 0);
+    laSetProofingLut(DATA_LUT_PROOF_CLAY, 1);
+    laSetProofingLut(DATA_LUT_PROOF_D65P3, 2);
+
     logPrintNew("Initialization Completed\n");
     MAIN.InitDone=1;
 
@@ -2230,6 +2234,40 @@ void la_RefreshThemeColor(laTheme* th){
     }
 }
 
+void laSetProofingLut(void* data, int which){
+    TNS_CLAMP(which,0,2);
+    MAIN.ProofingLUT[which]=data;
+    MAIN.LutNeedsRefreshing=1;
+}
+void la_RefreshProofingLut(){
+    if(!MAIN.CurrentWindow) return;
+    int table = MAIN.CurrentWindow->OutputColorSpace;
+
+    if(MAIN.CurrentLut != table+1){ MAIN.LutNeedsRefreshing=1; }
+    if(!MAIN.LutNeedsRefreshing) return;
+
+    tnsEnableShaderv(T->immShader);
+    tnsShader* s = T->immShader;
+    if(!MAIN.ProofingLUT[table] || !MAIN.CurrentWindow->OutputProofing){
+        return;
+    }
+
+    if(!MAIN.LutTexture) glGenTextures(1, &MAIN.LutTexture);
+    tnsActiveTexture(GL_TEXTURE3);
+    glBindTexture(GL_TEXTURE_3D, MAIN.LutTexture);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glTexImage3D(GL_TEXTURE_3D,0,GL_RGB,LA_LUT_PRECISION,LA_LUT_PRECISION,LA_LUT_PRECISION,0,GL_RGB, GL_UNSIGNED_BYTE,MAIN.ProofingLUT[table]);
+    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    //glBindTexture(GL_TEXTURE_3D,0);
+    tnsActiveTexture(GL_TEXTURE0);
+    MAIN.CurrentLut = table+1;
+    MAIN.LutNeedsRefreshing=0;
+}
+
 //I FUCKING HATE THIS STUPID FUNCTION
 int la_SetUpUiListMatrix(laUiListDraw *uild, laUiList *Target, int _L, int _R, int LimH, int PanelH, int GlobalX, int GlobalY){
     laUiListDrawItem *uildi = memAcquireSimple(sizeof(laUiListDrawItem));
@@ -2490,11 +2528,11 @@ void la_PanelDrawToWindow(laPanel *p, laWindow *w){
     if(MAIN.EnableColorManagement){
         tnsUniformOutputColorSpace(T->immShader,w->OutputColorSpace);
         tnsUniformShowColorOverflowStripes(T->immShader,w->OutputShowStripes);
-        tnsUniformColorComposing(T->immShader,w->UseComposing,w->ComposingGamma,w->ComposingBlackpoint);
+        tnsUniformColorComposing(T->immShader,w->UseComposing,w->ComposingGamma,w->ComposingBlackpoint,w->OutputProofing);
     }else{
         tnsUniformOutputColorSpace(T->immShader,0);
         tnsUniformShowColorOverflowStripes(T->immShader,0);
-        tnsUniformColorComposing(T->immShader,0,0,0);
+        tnsUniformColorComposing(T->immShader,0,0,0,0);
     }
 
     if (p->Mode && (!p->AnimationMode || (p->AnimationMode && p->AnimationRatio > 0.99) || p->AnimationMode==LA_PANEL_ANIMATION_FLASH)){
@@ -2616,7 +2654,7 @@ void la_PanelDrawToWindow(laPanel *p, laWindow *w){
 
     tnsUniformOutputColorSpace(T->immShader,0);
     tnsUniformShowColorOverflowStripes(T->immShader,0);
-    tnsUniformColorComposing(T->immShader,0,0,0);
+    tnsUniformColorComposing(T->immShader,0,0,0,0);
 }
 void la_PanelDrawToOffsceen(laPanel *p, laUiList *uil){
     if (p->OffScr){ tnsEnsureOffscreenStatus(p->OffScr, p->W,p->H); }
@@ -2888,11 +2926,12 @@ void la_BlockDefDrawSelf(laBlock *b, int CH){
 
     tnsUseImmShader(); tnsEnableShaderv(T->immShader);
     if(MAIN.EnableColorManagement){
-        tnsUniformOutputColorSpace(T->immShader,MAIN.CurrentWindow->OutputColorSpace);
-        tnsUniformColorComposing(T->immShader,MAIN.CurrentWindow->UseComposing,MAIN.CurrentWindow->ComposingGamma,MAIN.CurrentWindow->ComposingBlackpoint);
+        laWindow* w=MAIN.CurrentWindow;
+        tnsUniformOutputColorSpace(T->immShader,w->OutputColorSpace);
+        tnsUniformColorComposing(T->immShader,w->UseComposing,w->ComposingGamma,w->ComposingBlackpoint,w->OutputProofing);
     }else{
         tnsUniformOutputColorSpace(T->immShader,0);
-        tnsUniformColorComposing(T->immShader,0,0,0);
+        tnsUniformColorComposing(T->immShader,0,0,0,0);
     }
 
     for (p = b->Panels.pFirst; p; p = p->Item.pNext){
@@ -2956,7 +2995,7 @@ void la_BlockDefDrawSelf(laBlock *b, int CH){
     tnsFlush();
 
     tnsUniformOutputColorSpace(T->immShader,0);
-    tnsUniformColorComposing(T->immShader,0,0,0);
+    tnsUniformColorComposing(T->immShader,0,0,0,0);
 }
 void la_BlockDefDrawSelfEmpty(laBlock *b, int CH){
     laBoxedTheme *bt = _LA_THEME_PANEL;
@@ -2964,11 +3003,12 @@ void la_BlockDefDrawSelfEmpty(laBlock *b, int CH){
 
     tnsUseImmShader(); tnsEnableShaderv(T->immShader);
     if(MAIN.EnableColorManagement){
-        tnsUniformOutputColorSpace(T->immShader,MAIN.CurrentWindow->OutputColorSpace);
-        tnsUniformColorComposing(T->immShader,MAIN.CurrentWindow->UseComposing,MAIN.CurrentWindow->ComposingGamma,MAIN.CurrentWindow->ComposingBlackpoint);
+        laWindow* w=MAIN.CurrentWindow;
+        tnsUniformOutputColorSpace(T->immShader,w->OutputColorSpace);
+        tnsUniformColorComposing(T->immShader,w->UseComposing,w->ComposingGamma,w->ComposingBlackpoint,w->OutputProofing);
     }else{
         tnsUniformOutputColorSpace(T->immShader,0);
-        tnsUniformColorComposing(T->immShader,0,0,0);
+        tnsUniformColorComposing(T->immShader,0,0,0,0);
     }
     
     tnsUseNoTexture();
@@ -2985,7 +3025,7 @@ void la_BlockDefDrawSelfEmpty(laBlock *b, int CH){
     tnsFlush();
 
     tnsUniformOutputColorSpace(T->immShader,0);
-    tnsUniformColorComposing(T->immShader,0,0,0);
+    tnsUniformColorComposing(T->immShader,0,0,0,0);
 }
 void la_BlockDefDrawRecursive(laWindow *w, laBoxedTheme *bt, laBlock *b){
     if (b->B1){
@@ -3070,6 +3110,7 @@ void la_WindowDefDraw(laWindow *w, laBoxedTheme *bt){
     la_ClearUnusedFramebuffers(w);
 
     tnsDrawToScreen();
+    la_RefreshProofingLut();
 
     tnsViewportWithScissor(0, 0, w->CW, w->CH);
     glClearColor(0.2, 0.2, 0.3, 1.0);
@@ -3093,10 +3134,10 @@ void la_WindowDefDraw(laWindow *w, laBoxedTheme *bt){
             tnsUseShader(T->immShader);tnsEnableShaderv(T->immShader);
             if(MAIN.EnableColorManagement){
                 tnsUniformOutputColorSpace(T->immShader,w->OutputColorSpace);
-                tnsUniformColorComposing(T->immShader,w->UseComposing,w->ComposingGamma,w->ComposingBlackpoint);
+                tnsUniformColorComposing(T->immShader,w->UseComposing,w->ComposingGamma,w->ComposingBlackpoint,w->OutputProofing);
             }else{
                 tnsUniformOutputColorSpace(T->immShader,0);
-                tnsUniformColorComposing(T->immShader,0,0,0);
+                tnsUniformColorComposing(T->immShader,0,0,0,0);
             }
             if(p->Refresh&LA_TAG_RECALC){
                 laRecalcPanelImmediate(p);

+ 2 - 2
la_tns.h

@@ -106,7 +106,7 @@ struct _tnsShader{
     int iMultiplyColor, StateMultiplyColor;
     int iTextureMode, StateTextureMode, iColorMode,iHCYGamma;
     int iSampleAmount, StateSampleAmount;
-    int iInputColorSpace, iOutputColorSpace, iShowStripes;
+    int iInputColorSpace, iOutputColorSpace, iShowStripes, iTexLut, iUseLut;
     int iComposing, iComposingGamma, iComposingBlackpoint;
     int iDoOffset;
     int iUseHalftone,iHalftoneSize;
@@ -1404,7 +1404,7 @@ void tnsUniformHCYGamma(tnsShader* s, float Gamma);
 void tnsUniformInputColorSpace(tnsShader* s, int ColorSpace);
 void tnsUniformOutputColorSpace(tnsShader* s, int ColorSpace);
 void tnsUniformShowColorOverflowStripes(tnsShader* s, int Show);
-void tnsUniformColorComposing(tnsShader* s, int Composing, real gamma, real blackpoint);
+void tnsUniformColorComposing(tnsShader* s, int Composing, real gamma, real blackpoint, int UseLut);
 void tnsUniformUseMultiplyColor(tnsShader* s, int enable);
 void tnsUseMaskTexture(tnsTexture *t);
 void tnsUseTexture(tnsTexture *t);

+ 6 - 2
la_tns_kernel.c

@@ -341,9 +341,11 @@ void tnsShaderMakeIndex(tnsShader *tns){
     tns->iTexColor = glGetUniformLocation(program, "TexColor");
     tns->iTexColorU = glGetUniformLocation(program, "TexColorUI");
     tns->iTexColorMS = glGetUniformLocation(program, "TexColorMS");
+    tns->iTexLut=glGetUniformLocation(program, "TexLut");
     if(tns->iTexColor>=0){glUniform1i(tns->iTexColor, 0);}
     if(tns->iTexColorMS>=0){glUniform1i(tns->iTexColorMS, 1);}
     if(tns->iTexColorU>=0){glUniform1i(tns->iTexColorU, 2);}
+    if(tns->iTexLut>=0){glUniform1i(tns->iTexLut, 3);}
     tns->iTexNormal = glGetUniformLocation(program, "TexNormal");
     tns->iTexGPos = glGetUniformLocation(program, "TexGPos");
     tns->iMultiplyColor = glGetUniformLocation(program, "MultiplyColor");
@@ -354,6 +356,7 @@ void tnsShaderMakeIndex(tnsShader *tns){
     tns->iUseNormal = glGetUniformLocation(program, "UseNormal");
     tns->iOutputColorSpace=glGetUniformLocation(program, "OutputColorSpace");
     tns->iInputColorSpace=glGetUniformLocation(program, "InputColorSpace");
+    tns->iUseLut=glGetUniformLocation(program, "UseLut");
     tns->iShowStripes=glGetUniformLocation(program, "ShowStripes");
     tns->iComposing=glGetUniformLocation(program, "Composing");
     tns->iComposingGamma=glGetUniformLocation(program, "ComposingGamma");
@@ -463,7 +466,7 @@ int tnsNewFragmentShaderMaterial(char *Content, char* Library, char* Material){
     glCompileShader(FragmentShaderObject);
     glGetShaderiv(FragmentShaderObject, GL_COMPILE_STATUS, &status);
     if (status == GL_FALSE){
-        glGetShaderInfoLog(FragmentShaderObject, sizeof(error), 0, error); logPrint("Fragment shader error:\n%s", error);
+        glGetShaderInfoLog(FragmentShaderObject, sizeof(error), 0, error); printf("Fragment shader error:\n%s", error);
         glDeleteShader(FragmentShaderObject); free(UseContent);
         return -1;
     } else {
@@ -2004,9 +2007,10 @@ void tnsUniformOutputColorSpace(tnsShader* s, int ColorSpace){
 void tnsUniformShowColorOverflowStripes(tnsShader* s, int Show){
     glUniform1i(s->iShowStripes,Show);
 }
-void tnsUniformColorComposing(tnsShader* s, int Composing, real gamma, real blackpoint){
+void tnsUniformColorComposing(tnsShader* s, int Composing, real gamma, real blackpoint, int UseLut){
     glUniform1i(s->iComposing,Composing); glUniform1f(s->iComposingGamma,gamma);
     glUniform1f(s->iComposingBlackpoint,blackpoint);
+    glUniform1i(s->iUseLut,UseLut);
 }
 
 void tnsDraw2DTextureDirectly(tnsTexture *t, real x, real y, real w, real h){

+ 6 - 5
resources/la_properties.c

@@ -561,7 +561,8 @@ void laset_ScreenColorSpace(laScreen* s, int space){
     }
 }
 
-void laset_WindowColorSpace(laWindow* w, int space){ w->OutputColorSpace=space; if(w->win) laRedrawCurrentWindow(); }
+void laset_WindowColorSpace(laWindow* w, int space){ w->OutputColorSpace=space; MAIN.LutNeedsRefreshing=1; if(w->win) laRedrawCurrentWindow(); }
+void laset_WindowOutputProofing(laWindow* w, int v){ w->OutputProofing=v; MAIN.LutNeedsRefreshing=1; if(w->win) laRedrawCurrentWindow(); }
 void laset_WindowShowStripes(laWindow* w, int stripes){ w->OutputShowStripes=stripes; if(w->win) laRedrawCurrentWindow(); }
 void laset_WindowUseComposing(laWindow* w, int comp){ w->UseComposing=comp; if(w->win) laRedrawCurrentWindow(); }
 void laset_WindowComposingGamma(laWindow* w, real v){ w->ComposingGamma=v; if(w->win) laRedrawCurrentWindow(); }
@@ -1585,10 +1586,6 @@ void la_RegisterInternalProps(){
             
             laAddStringProperty(p, "identifier", "Identifier", "Identifier", 0,0,0,0,0,0,0,laget_MainIdentifier, 0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
   
-            ep=laAddEnumProperty(p, "detached_view_switch", "View Detached", "Use detached view on panels", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(LA, DetachedViewSwitch),0,0,0,0,0,0,0,0,0,LA_UDF_IGNORE);
-            laAddEnumItemAs(ep, "LINKED", "Linked", "View is linked to global current states", 0, U'🔗');
-            laAddEnumItemAs(ep, "DETACHED", "Detached", "View is detached from global states and is pinned to panel", 1, U'📌');
-
             laAddIntProperty(p, "example_int", "Example Integer", "Example integer", 0,0,0,100,0,1, 50,0,offsetof(LA, example_int), 0,0,0,0,0,0,0,0,0,0,0);
             laAddStringProperty(p, "example_string", "Example String", "Example string", 0,0,0,0,1, offsetof(LA,example_string), 0,0,0,0,0);
             laAddStringProperty(p, "unknown_prop", "Unknown Property", "Placeholder for unknown property, probably due to a wrong property path, or not setting LA_AS_IDENTIFIER in any of the properties.",
@@ -1860,6 +1857,10 @@ void la_RegisterInternalProps(){
                 laAddEnumItemAs(ep, "CLAY", "Clay", "Clay color space (AdobeRGB 1998 compatible)", TNS_COLOR_SPACE_CLAY, 0);
                 laAddEnumItemAs(ep, "D65_P3", "D65 P3", "D65 P3 color space", TNS_COLOR_SPACE_D65_P3, 0);
             }
+            ep = laAddEnumProperty(p, "output_proofing", "Proofing", "Show soft proofing in this window", 0,0,0,0,0,offsetof(laWindow, OutputProofing), 0,laset_WindowOutputProofing, 0,0,0,0,0,0,0,0);{
+                laAddEnumItemAs(ep, "NONE", "None", "Not doing soft proofing", 0, L'🖵');
+                laAddEnumItemAs(ep, "PROOFING", "Proofing", "Show soft proofing", 1, L'🖶');
+            }
             ep = laAddEnumProperty(p, "output_show_overflow", "Show Overflow", "Show stripes on overflowing colors", LA_WIDGET_ENUM_HIGHLIGHT, 0,0,0,0,offsetof(laWindow, OutputShowStripes), 0,laset_WindowShowStripes, 0,0,0,0,0,0,0,0);{
                 laAddEnumItemAs(ep, "NONE", "None", "Don't show overflow", 0,0);
                 laAddEnumItemAs(ep, "STRIPES", "Stripes", "Show overflowing colors as stripes", 1, 0);

+ 1 - 0
resources/la_templates.c

@@ -595,6 +595,7 @@ void laui_DefaultMenuBarActual(laUiList *uil, laPropPack *pp, laPropPack *actins
                     laShowItem(uil,c,0,"la.windows.output_color_space");
                 }laEndCondition(uil, uc1);
                 laShowItemFull(uil,c,0,"la.windows.output_show_overflow",0,"text=🟩;",0,0)->Flags|=LA_UI_FLAGS_NO_CONFIRM;
+                laShowItemFull(uil,c,0,"la.windows.output_proofing",0,0,0,0)->Flags|=LA_UI_FLAGS_CYCLE|LA_UI_FLAGS_ICON|LA_UI_FLAGS_HIGHLIGHT|LA_UI_FLAGS_NO_CONFIRM;
                 laShowItemFull(uil,c,0,"la.windows.use_composing",0,"text=☀",0,0)->Flags|=LA_UI_FLAGS_NO_CONFIRM;
                 laUiItem* cmp=laOnConditionThat(uil,c,laPropExpression(0,"la.windows.use_composing"));{
                     muil = laMakeMenuPageEx(uil, c, "⯆",LA_UI_FLAGS_NO_CONFIRM);{ mc = laFirstColumn(muil);

+ 8 - 2
resources/la_tns_shaders.cpp

@@ -684,6 +684,8 @@ precision highp int;
 uniform highp sampler2D TexColor;
 uniform highp sampler2DMS TexColorMS;
 uniform highp usampler2D TexColorUI;
+uniform highp sampler3D TexLut;
+uniform int UseLut;
 uniform int TextureMode;
 uniform int ColorMode;
 uniform int MultiplyColor;
@@ -732,8 +734,9 @@ vec4 ConvertColorSpace(vec4 _rgba){
     	else if(OutputColorSpace==2){ color=to_log_srgb(XYZ2D65P3(xyz)); /*_rgba.a=pow(_rgba.a,1.0/2.19921875);*/ }
     }else{
         if(ColorMode==1){ color.y=pow(color.y,max(HCYGamma,1.)); color=okhsl_to_srgb(color); }
-        else if(ColorMode==0){ color=color; }
-        else{
+        else if(ColorMode==0){
+			color = color;
+		}else{
                  if(OutputColorSpace==0){ color=to_log_srgb(color); /*_rgba.a=srgb_transfer_function(_rgba.a);*/ }
             else if(OutputColorSpace==1){ color=to_log_clay(color); /*_rgba.a=pow(_rgba.a,1.0/2.19921875);*/ }
             else if(OutputColorSpace==2){ color=to_log_srgb(color); /*_rgba.a=pow(_rgba.a,1.0/2.19921875);*/ }
@@ -818,6 +821,9 @@ void main(){
 			color.rgb=vec3(ComposingBlackpoint,ComposingBlackpoint,ComposingBlackpoint);
 		}
 	}
+	if(UseLut!=0){
+		color.rgb = texture(TexLut,color.bgr).rgb;
+	}
 	if(UseHalftone>1e-6){ color=mix(color,halftone(color),UseHalftone); }
     outColor = color;
     outGPos = fGPos;

+ 11 - 6
resources/la_widgets.c

@@ -1258,21 +1258,24 @@ void la_ColorCircleDrawHCY(laUiItem *ui, int h){
 
     int IsClay=ui->Flags&LA_UI_FLAGS_COLOR_SPACE_CLAY;
     int IsP3=ui->Flags&LA_UI_FLAGS_COLOR_SPACE_D65_P3;
-    int ShowInfo=0;
+    int ShowInfo=0,ShowProof=0;
 
     if(MAIN.CurrentWindow->OutputColorSpace!=TNS_COLOR_SPACE_SRGB && (!IsClay) && (!IsP3)){
         tnsUniformShowColorOverflowStripes(T->immShader,1);
     }
 
+    laWindow* win=MAIN.CurrentWindow;
+
     if(IsClay){
         tnsUniformInputColorSpace(T->immShader,TNS_COLOR_SPACE_CLAY);
-        if(MAIN.CurrentWindow->OutputColorSpace!=TNS_COLOR_SPACE_CLAY) ShowInfo=1;
+        if(win->OutputColorSpace!=TNS_COLOR_SPACE_CLAY) ShowInfo=1;
     }elif(IsP3){
         tnsUniformInputColorSpace(T->immShader,TNS_COLOR_SPACE_D65_P3);
-        if(MAIN.CurrentWindow->OutputColorSpace!=TNS_COLOR_SPACE_D65_P3) ShowInfo=1;
+        if(win->OutputColorSpace!=TNS_COLOR_SPACE_D65_P3) ShowInfo=1;
     }else{
         tnsUniformInputColorSpace(T->immShader,TNS_COLOR_SPACE_SRGB);
     }
+    if(win->OutputProofing){ ShowProof=1; }
 
     tnsUseNoTexture();
     tnsVectorSet4(&colors[576],1,1,hcy[2],1);
@@ -1343,9 +1346,11 @@ void la_ColorCircleDrawHCY(laUiItem *ui, int h){
 
     if(ui->Extra->HeightCoeff>=0) tnsDrawStringAuto("◿",laThemeColor(bt,LA_BT_BORDER),ui->R-LA_RH, ui->R, ui->B-bt->BM-LA_RH, LA_TEXT_ALIGN_CENTER);
 
-    if(IsClay) tnsDrawStringAuto("Clay",laThemeColor(bt,LA_BT_BORDER),ui->L, c-r+LA_RH, ui->U+bt->TM, LA_TEXT_ALIGN_RIGHT|LA_TEXT_MONO);
-    if(IsP3) tnsDrawStringAuto("D65 P3",laThemeColor(bt,LA_BT_BORDER),ui->L, c-r+LA_RH, ui->U+bt->TM, LA_TEXT_ALIGN_RIGHT|LA_TEXT_MONO);
-    if(ShowInfo) tnsDrawStringAuto("🛈",laThemeColor(bt,LA_BT_TEXT),c-r, ui->R, ui->B-bt->BM-LA_RH, LA_TEXT_ALIGN_LEFT);
+    if(IsClay) tnsDrawStringAuto("Clay",laThemeColor(bt,LA_BT_TEXT),ui->L, c-r+LA_RH, ui->U+bt->TM, LA_TEXT_ALIGN_RIGHT|LA_TEXT_MONO);
+    if(IsP3) tnsDrawStringAuto("D65 P3",laThemeColor(bt,LA_BT_TEXT),ui->L, c-r+LA_RH, ui->U+bt->TM, LA_TEXT_ALIGN_RIGHT|LA_TEXT_MONO);
+    char bufinfo[64];
+    sprintf(bufinfo,"%s%s",ShowInfo?"🛈":"",ShowProof?"🖶":"");
+    if(ShowInfo||ShowProof) tnsDrawStringAuto(bufinfo,laThemeColor(bt,LA_BT_TEXT),c-r, ui->R, ui->B-bt->BM-LA_RH, LA_TEXT_ALIGN_LEFT);
 
     tnsFlush();
 

File diff suppressed because it is too large
+ 0 - 0
resources/soft_proof_table_Clay.lagui.lut


BIN
resources/soft_proof_table_D65P3.lagui.lut


BIN
resources/soft_proof_table_sRGB.lagui.lut


Some files were not shown because too many files changed in this diff