Browse Source

* Apply Merge request !468 (use JPEG out_color_space)

Michaël Van Canneyt 2 years ago
parent
commit
30e7bfb666

+ 92 - 33
packages/fcl-image/src/fpcolorspace.pas

@@ -277,6 +277,10 @@ type
     function ToExpanded(AGammaExpansion: boolean = true): TExpandedPixel;
     function ToExpanded(AGammaExpansion: boolean = true): TExpandedPixel;
     function ToHSLAPixel(AGammaExpansion: boolean = true): THSLAPixel;
     function ToHSLAPixel(AGammaExpansion: boolean = true): THSLAPixel;
     function ToGSBAPixel(AGammaExpansion: boolean = true): TGSBAPixel;
     function ToGSBAPixel(AGammaExpansion: boolean = true): TGSBAPixel;
+    function ToStdRGBA: TStdRGBA;
+    function ToStdHSLA: TStdHSLA;
+    function ToStdHSVA: TStdHSVA;
+    function ToStdCMYK: TStdCMYK;
   end;
   end;
 
 
   { TExpandedPixelHelper }
   { TExpandedPixelHelper }
@@ -300,11 +304,15 @@ type
   { TStdRGBAHelper }
   { TStdRGBAHelper }
 
 
   TStdRGBAHelper = record helper for TStdRGBA
   TStdRGBAHelper = record helper for TStdRGBA
+    function ToFPColor: TFPColor;
     function ToExpandedPixel: TExpandedPixel;
     function ToExpandedPixel: TExpandedPixel;
     function ToLinearRGBA: TLinearRGBA;
     function ToLinearRGBA: TLinearRGBA;
     function ToStdHSLA: TStdHSLA;
     function ToStdHSLA: TStdHSLA;
     function ToStdHSVA: TStdHSVA;
     function ToStdHSVA: TStdHSVA;
     function ToStdCMYK: TStdCMYK;
     function ToStdCMYK: TStdCMYK;
+    {** SamplePrecision = 2^(YCbCrSamplePrecision-1) }
+    function ToYCbCr(const AStd:TYCbCrSTD=YCbCr_JPG; ASamplePrecision:Single=0.5): TYCbCr; overload;
+    function ToYCbCr(LumaRed:Single=0.299; LumaGreen:Single=0.587; LumaBlue:Single=0.114): TYCbCr; overload;
   end;
   end;
 
 
   { TAdobeRGBAHelper }
   { TAdobeRGBAHelper }
@@ -317,6 +325,7 @@ type
   { TStdHSLAHelper }
   { TStdHSLAHelper }
 
 
   TStdHSLAHelper = record helper for TStdHSLA
   TStdHSLAHelper = record helper for TStdHSLA
+    function ToFPColor: TFPColor;
     function ToStdRGBA: TStdRGBA;
     function ToStdRGBA: TStdRGBA;
     function ToStdHSVA: TStdHSVA;
     function ToStdHSVA: TStdHSVA;
     function ToExpandedPixel: TExpandedPixel;
     function ToExpandedPixel: TExpandedPixel;
@@ -325,6 +334,7 @@ type
   { TStdHSVAHelper }
   { TStdHSVAHelper }
 
 
   TStdHSVAHelper = record helper for TStdHSVA
   TStdHSVAHelper = record helper for TStdHSVA
+    function ToFPColor: TFPColor;
     function ToStdRGBA: TStdRGBA;
     function ToStdRGBA: TStdRGBA;
     function ToStdHSLA: TStdHSLA;
     function ToStdHSLA: TStdHSLA;
   end;
   end;
@@ -332,6 +342,7 @@ type
   { TStdCMYKHelper }
   { TStdCMYKHelper }
 
 
   TStdCMYKHelper = record helper for TStdCMYK
   TStdCMYKHelper = record helper for TStdCMYK
+    function ToFPColor(const AAlpha: Word=$ffff): TFPColor;
     function ToStdRGBA(AAlpha: Single = 1): TStdRGBA;
     function ToStdRGBA(AAlpha: Single = 1): TStdRGBA;
     function ToExpandedPixel: TExpandedPixel;overload;
     function ToExpandedPixel: TExpandedPixel;overload;
     function ToExpandedPixel(AAlpha: word): TExpandedPixel;overload;
     function ToExpandedPixel(AAlpha: word): TExpandedPixel;overload;
@@ -350,9 +361,6 @@ type
     function ToXYZA: TXYZA; overload;
     function ToXYZA: TXYZA; overload;
     function ToXYZA(const AReferenceWhite: TXYZReferenceWhite): TXYZA; overload;
     function ToXYZA(const AReferenceWhite: TXYZReferenceWhite): TXYZA; overload;
     function ToStdRGBA: TStdRGBA;
     function ToStdRGBA: TStdRGBA;
-    {** SamplePrecision = 2^(YCbCrSamplePrecision-1) }
-    function ToYCbCr(const AStd:TYCbCrSTD=YCbCr_JPG; ASamplePrecision:Single=0.5): TYCbCr; overload;
-    function ToYCbCr(LumaRed:Single=0.299; LumaGreen:Single=0.587; LumaBlue:Single=0.114): TYCbCr; overload;
   end;
   end;
 
 
   { TXYZAHelper }
   { TXYZAHelper }
@@ -399,8 +407,8 @@ type
 
 
   TYCbCrHelper = record helper for TYCbCr
   TYCbCrHelper = record helper for TYCbCr
     {** SamplePrecision = 2^(YCbCrSamplePrecision-1) }
     {** SamplePrecision = 2^(YCbCrSamplePrecision-1) }
-    function ToLinearRGBA(const AStd:TYCbCrSTD=YCbCr_JPG; ASamplePrecision:Single=0.5): TLinearRGBA; overload;
-    function ToLinearRGBA(LumaRed:Single=0.299; LumaGreen:Single=0.587; LumaBlue:Single=0.114): TLinearRGBA; overload;
+    function ToStdRGBA(const AStd:TYCbCrSTD=YCbCr_601; ASamplePrecision:Single=0.5): TStdRGBA; overload;
+    function ToStdRGBA(LumaRed:Single=0.299; LumaGreen:Single=0.587; LumaBlue:Single=0.114; ASamplePrecision:Single=0.5): TStdRGBA; overload;
   end;
   end;
 
 
   {* How to handle overflow when converting from XYZ }
   {* How to handle overflow when converting from XYZ }
@@ -1396,6 +1404,30 @@ begin
   result.FromFPColor(self, AGammaExpansion);
   result.FromFPColor(self, AGammaExpansion);
 end;
 end;
 
 
+function TFPColorHelper.ToStdRGBA: TStdRGBA;
+const oneOver65535 = 1/65535;
+begin
+    result.red := red * oneOver65535;
+    result.green := green * oneOver65535;
+    result.blue := blue * oneOver65535;
+    result.alpha := alpha * oneOver65535;
+end;
+
+function TFPColorHelper.ToStdHSLA: TStdHSLA;
+begin
+  result :=self.ToStdRGBA.ToStdHSLA;
+end;
+
+function TFPColorHelper.ToStdHSVA: TStdHSVA;
+begin
+  result :=self.ToStdRGBA.ToStdHSVA;
+end;
+
+function TFPColorHelper.ToStdCMYK: TStdCMYK;
+begin
+  result :=self.ToStdRGBA.ToStdCMYK;
+end;
+
 { TExpandedPixelHelper }
 { TExpandedPixelHelper }
 
 
 function TExpandedPixelHelper.ToHSLAPixel: THSLAPixel;
 function TExpandedPixelHelper.ToHSLAPixel: THSLAPixel;
@@ -1470,6 +1502,14 @@ end;
 
 
 { TStdRGBAHelper }
 { TStdRGBAHelper }
 
 
+function TStdRGBAHelper.ToFPColor: TFPColor;
+begin
+  result.red := ClampInt(round(red * 65535), 0, 65535);
+  result.green := ClampInt(round(green * 65535), 0, 65535);
+  result.blue := ClampInt(round(blue * 65535), 0, 65535);
+  result.alpha := ClampInt(round(alpha * 65535), 0, 65535);
+end;
+
 function TStdRGBAHelper.ToExpandedPixel: TExpandedPixel;
 function TStdRGBAHelper.ToExpandedPixel: TExpandedPixel;
 begin
 begin
   result.red := FPGammaExpansion(self.red);
   result.red := FPGammaExpansion(self.red);
@@ -1576,6 +1616,26 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TStdRGBAHelper.ToYCbCr(const AStd: TYCbCrSTD; ASamplePrecision:Single=0.5): TYCbCr;
+begin
+  with self, YCbCrSTD_Factors[AStd]  do
+  begin
+    result.Y := a * red + b * green + c * blue;
+    result.Cb := ((blue - result.Y) / d)+ASamplePrecision;
+    result.Cr := ((red - result.Y) / e)+ASamplePrecision;
+  end;
+end;
+
+function TStdRGBAHelper.ToYCbCr(LumaRed: Single; LumaGreen: Single; LumaBlue: Single): TYCbCr;
+begin
+  with self  do
+  begin
+    result.Y :=  ( LumaRed * red + LumaGreen * green + LumaBlue * blue );
+    result.Cb := ( blue - result.Y ) / ( 2 - 2 * LumaBlue );
+    result.Cr := ( red - result.Y ) / ( 2 - 2 * LumaRed );
+  end;
+end;
+
 { TAdobeRGBAHelper }
 { TAdobeRGBAHelper }
 
 
 function TAdobeRGBAHelper.ToXYZA: TXYZA;
 function TAdobeRGBAHelper.ToXYZA: TXYZA;
@@ -1608,6 +1668,11 @@ end;
 
 
 { TStdHSLAHelper }
 { TStdHSLAHelper }
 
 
+function TStdHSLAHelper.ToFPColor: TFPColor;
+begin
+  result :=self.ToStdRGBA.ToFPColor;
+end;
+
 function TStdHSLAHelper.ToStdRGBA: TStdRGBA;
 function TStdHSLAHelper.ToStdRGBA: TStdRGBA;
 var
 var
   C, X, M, rp, gp, bp, sp, lp, h360: single;
   C, X, M, rp, gp, bp, sp, lp, h360: single;
@@ -1687,6 +1752,11 @@ end;
 
 
 { TStdHSVAHelper }
 { TStdHSVAHelper }
 
 
+function TStdHSVAHelper.ToFPColor: TFPColor;
+begin
+  result :=self.ToStdRGBA.ToFPColor;
+end;
+
 function TStdHSVAHelper.ToStdRGBA: TStdRGBA;
 function TStdHSVAHelper.ToStdRGBA: TStdRGBA;
 var
 var
   C, X, M, rp, gp, bp, sp, vp: single;
   C, X, M, rp, gp, bp, sp, vp: single;
@@ -1775,24 +1845,30 @@ end;
 
 
 function TStdCMYKHelper.ToExpandedPixel: TExpandedPixel;
 function TStdCMYKHelper.ToExpandedPixel: TExpandedPixel;
 begin
 begin
-  self.ToStdRGBA.ToExpandedPixel;
+  result :=self.ToStdRGBA.ToExpandedPixel;
 end;
 end;
 
 
 function TStdCMYKHelper.ToExpandedPixel(AAlpha: word): TExpandedPixel;
 function TStdCMYKHelper.ToExpandedPixel(AAlpha: word): TExpandedPixel;
 begin
 begin
-  self.ToStdRGBA(AAlpha).ToExpandedPixel;
+  result :=self.ToStdRGBA(AAlpha).ToExpandedPixel;
+end;
+
+function TStdCMYKHelper.ToFPColor(const AAlpha: Word): TFPColor;
+begin
+  result :=self.ToStdRGBA.ToFPColor;
+  result.alpha := AAlpha
 end;
 end;
 
 
 { TLabAHelper }
 { TLabAHelper }
 
 
 function TLabAHelper.ToExpandedPixel: TExpandedPixel;
 function TLabAHelper.ToExpandedPixel: TExpandedPixel;
 begin
 begin
-  self.ToXYZA.ToLinearRGBA.ToExpandedPixel;
+  result :=self.ToXYZA.ToLinearRGBA.ToExpandedPixel;
 end;
 end;
 
 
 function TLabAHelper.ToExpandedPixel(const AReferenceWhite: TXYZReferenceWhite): TExpandedPixel;
 function TLabAHelper.ToExpandedPixel(const AReferenceWhite: TXYZReferenceWhite): TExpandedPixel;
 begin
 begin
-  self.ToXYZA(AReferenceWhite).ToLinearRGBA(AReferenceWhite).ToExpandedPixel;
+  result :=self.ToXYZA(AReferenceWhite).ToLinearRGBA(AReferenceWhite).ToExpandedPixel;
 end;
 end;
 
 
 function TLabAHelper.ToXYZA: TXYZA;
 function TLabAHelper.ToXYZA: TXYZA;
@@ -1854,22 +1930,25 @@ end;
 
 
 { TYCbCrHelper }
 { TYCbCrHelper }
 
 
-function TYCbCrHelper.ToLinearRGBA(const AStd: TYCbCrSTD; ASamplePrecision:Single): TLinearRGBA;
+function TYCbCrHelper.ToStdRGBA(const AStd: TYCbCrSTD; ASamplePrecision:Single): TStdRGBA;
 begin
 begin
   with self, YCbCrSTD_Factors[AStd]  do
   with self, YCbCrSTD_Factors[AStd]  do
   begin
   begin
+    //"analog" Y is in the range 0 to 1 ; Cb and Cr in the range -0.5 to +0.5
+    //"digital" are normalized to 0..255; In 601 Standard values are between 16 and 235 for Y, 16 to 240 for Cb and Cr.
+
     result.red := Y + e * (Cr-ASamplePrecision);
     result.red := Y + e * (Cr-ASamplePrecision);
     result.green := Y - (a * e / b) * (Cr-ASamplePrecision) - (c * d / b) * (Cb-ASamplePrecision);
     result.green := Y - (a * e / b) * (Cr-ASamplePrecision) - (c * d / b) * (Cb-ASamplePrecision);
     result.blue := Y + d * (Cb-ASamplePrecision);
     result.blue := Y + d * (Cb-ASamplePrecision);
   end;
   end;
 end;
 end;
 
 
-function TYCbCrHelper.ToLinearRGBA(LumaRed: Single; LumaGreen: Single; LumaBlue: Single): TLinearRGBA;
+function TYCbCrHelper.ToStdRGBA(LumaRed: Single; LumaGreen: Single; LumaBlue: Single; ASamplePrecision:Single): TStdRGBA;
 begin
 begin
   with self  do
   with self  do
   begin
   begin
-    result.red := Cr * ( 2 - 2 * LumaRed ) + Y;
-    result.blue := Cb * ( 2 - 2 * LumaBlue ) + Y;
+    result.red := (Cr-ASamplePrecision) * ( 2 - 2 * LumaRed ) + Y;
+    result.blue := (Cb-ASamplePrecision) * ( 2 - 2 * LumaBlue ) + Y;
     result.green :=  ( Y - LumaBlue * result.blue - LumaRed * result.red ) / LumaGreen;
     result.green :=  ( Y - LumaBlue * result.blue - LumaRed * result.red ) / LumaGreen;
   end;
   end;
 end;
 end;
@@ -1933,26 +2012,6 @@ begin
   result.alpha := self.alpha;
   result.alpha := self.alpha;
 end;
 end;
 
 
-function TLinearRGBAHelper.ToYCbCr(const AStd: TYCbCrSTD; ASamplePrecision:Single=0.5): TYCbCr;
-begin
-  with self, YCbCrSTD_Factors[AStd]  do
-  begin
-    result.Y := a * red + b * green + c * blue;
-    result.Cb := ((blue - result.Y) / d)+ASamplePrecision;
-    result.Cr := ((red - result.Y) / e)+ASamplePrecision;
-  end;
-end;
-
-function TLinearRGBAHelper.ToYCbCr(LumaRed: Single; LumaGreen: Single; LumaBlue: Single): TYCbCr;
-begin
-  with self  do
-  begin
-    result.Y :=  ( LumaRed * red + LumaGreen * green + LumaBlue * blue );
-    result.Cb := ( blue - result.Y ) / ( 2 - 2 * LumaBlue );
-    result.Cr := ( red - result.Y ) / ( 2 - 2 * LumaRed );
-  end;
-end;
-
 { TXYZAHelper }
 { TXYZAHelper }
 
 
 function TXYZAHelper.ToLinearRGBA: TLinearRGBA;
 function TXYZAHelper.ToLinearRGBA: TLinearRGBA;

+ 85 - 48
packages/fcl-image/src/fpreadjpeg.pas

@@ -109,6 +109,25 @@ type
 
 
 implementation
 implementation
 
 
+uses FPColorSpace;
+
+type
+  int_Color_Table = array[0..MAXJSAMPLE+1-1] of int;
+  int_table_ptr = ^int_Color_Table;
+  INT32_Color_Table = array[0..MAXJSAMPLE+1-1] of INT32;
+  INT32_table_ptr = ^INT32_Color_Table;
+  my_cconvert_ptr = ^my_color_deconverter;
+  my_color_deconverter = record
+    pub : jpeg_color_deconverter; { public fields }
+
+    { Private state for YCC^.RGB conversion }
+    Cr_r_tab : int_table_ptr;   { => table for Cr to R conversion }
+    Cb_b_tab : int_table_ptr;   { => table for Cb to B conversion }
+    Cr_g_tab : INT32_table_ptr; { => table for Cr to G conversion }
+    Cb_g_tab : INT32_table_ptr; { => table for Cb to G conversion }
+  end;
+
+
 procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream;
 procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream;
                                      StartSize: integer);
                                      StartSize: integer);
 var
 var
@@ -353,24 +372,15 @@ var
     Result.alpha:=alphaOpaque;
     Result.alpha:=alphaOpaque;
   end;
   end;
 
 
-  function CorrectYCCK(const C: TFPColor): TFPColor;
-  var
-    MinColor: word;
-  begin
-    if C.red<C.green then MinColor:=C.red
-    else MinColor:= C.green;
-    if C.blue<MinColor then MinColor:= C.blue;
-    if MinColor+ C.alpha>$FF then MinColor:=$FF-C.alpha;
-    Result.red:=(C.red-MinColor) shl 8;
-    Result.green:=(C.green-MinColor) shl 8;
-    Result.blue:=(C.blue-MinColor) shl 8;
-    Result.alpha:=alphaOpaque;
-  end;
-
-
   procedure OutputScanLines();
   procedure OutputScanLines();
   var
   var
     x: integer;
     x: integer;
+    //ycbcr:TYCbCr;
+    cmyk:TStdCMYK;
+    yy,cb,cr :Int;
+    shift_temp : INT32;
+    cconvert : my_cconvert_ptr;
+
   begin
   begin
     Color.Alpha:=alphaOpaque;
     Color.Alpha:=alphaOpaque;
     y:=0;
     y:=0;
@@ -381,41 +391,68 @@ var
         ReturnValue:=false;
         ReturnValue:=false;
         break;
         break;
       end;
       end;
-      if (FInfo.jpeg_color_space = JCS_CMYK) then
-      for x:=0 to FInfo.output_width-1 do begin
-        Color.Red:=SampRow^[x*4+0];
-        Color.Green:=SampRow^[x*4+1];
-        Color.Blue:=SampRow^[x*4+2];
-        Color.alpha:=SampRow^[x*4+3];
-        SetPixel(x, y, CorrectCMYK(Color));
-      end
-      else
-      if (FInfo.jpeg_color_space = JCS_YCCK) then
-      for x:=0 to FInfo.output_width-1 do begin
-        Color.Red:=SampRow^[x*4+0];
-        Color.Green:=SampRow^[x*4+1];
-        Color.Blue:=SampRow^[x*4+2];
-        Color.alpha:=SampRow^[x*4+3];
-        SetPixel(x, y, CorrectYCCK(Color));
-      end
+
+      Case FInfo.out_color_space of
+      JCS_GRAYSCALE :
+        for x:=0 to FInfo.output_width-1 do
+        begin
+          c:= SampRow^[x] shl 8;
+          Color.Red:=c;
+          Color.Green:=c;
+          Color.Blue:=c;
+          SetPixel(x, y, Color);
+        end;
+      JCS_YCbCr :
+        for x:=0 to FInfo.output_width-1 do
+        begin
+          //MaxM: YCbCr is defined per CCIR 601-1
+          //      Y (0 to 1.0) and Cb,Cr (-0.5 to 0.5) is normalized to the range 0..MAXJSAMPLE
+          //      We have two ways to convert them, the most accurate is to denormalize
+          //      the values like the following commented code, or as is and set SamplePrecision to CENTERJSAMPLE
+          //      ycbcr.Y :=SampRow^[x*3+0]/256;
+          //      ycbcr.Cb :=(SampRow^[x*3+1]-128)/256;
+          //      ycbcr.Cr :=(SampRow^[x*3+2]-128)/256;
+          //ycbcr :=TYCbCr.New(SampRow^[x*3+0], SampRow^[x*3+1], SampRow^[x*3+2]);
+          //SetPixel(x, y, ycbcr.ToStdRGBA(YCBCr_601, CENTERJSAMPLE).ToExpandedPixel.ToFPColor(false));
+
+          //Use the same Code of PasJPeg (ycc_rgb_convert function)
+          yy :=SampRow^[x*3+0];
+          cb :=SampRow^[x*3+1];
+          cr :=SampRow^[x*3+2];
+          cconvert :=my_cconvert_ptr(FInfo.cconvert);
+          Color.Red :=  (FInfo.sample_range_limit^[yy + cconvert^.Cr_r_tab^[cr]]);
+          shift_temp := cconvert^.Cb_g_tab^[cb] + cconvert^.Cr_g_tab^[cr];
+          if shift_temp < 0 then   { SHIFT arithmetic RIGHT }
+            Color.Green := (FInfo.sample_range_limit^[yy + int((shift_temp shr 16)
+                                  or ( (not INT32(0)) shl (32-16)))])
+          else
+            Color.Green := (FInfo.sample_range_limit^[yy + int(shift_temp shr 16)]);
+
+          Color.Blue :=  (FInfo.sample_range_limit^[yy + cconvert^.Cb_b_tab^[cb]]);
+
+          Color.Red:=Color.Red shl 8;
+          Color.Green:=Color.Green shl 8;
+          Color.Blue:=Color.Blue shl 8;
+
+          SetPixel(x, y, Color);
+        end;
+      JCS_CMYK, JCS_YCCK:
+        for x:=0 to FInfo.output_width-1 do
+        begin
+          //SetPixel(x, y, CorrectCMYK(TFPColor.New(SampRow^[x*4+0], SampRow^[x*4+1], SampRow^[x*4+2], SampRow^[x*4+3])));
+
+          cmyk :=TStdCMYK.New(SampRow^[x*4+0], SampRow^[x*4+1], SampRow^[x*4+2], SampRow^[x*4+3]);
+          SetPixel(x, y, cmyk.ToExpandedPixel.ToFPColor(false));
+        end;
       else
       else
-      if fgrayscale then begin
-       for x:=0 to FInfo.output_width-1 do begin
-         c:= SampRow^[x] shl 8;
-         Color.Red:=c;
-         Color.Green:=c;
-         Color.Blue:=c;
-         SetPixel(x, y, Color);
-       end;
-      end
-      else begin
-       for x:=0 to FInfo.output_width-1 do begin
-         Color.Red:=SampRow^[x*3+0] shl 8;
-         Color.Green:=SampRow^[x*3+1] shl 8;
-         Color.Blue:=SampRow^[x*3+2] shl 8;
-         SetPixel(x, y, Color);
-       end;
+        for x:=0 to FInfo.output_width-1 do begin
+          Color.Red:=SampRow^[x*3+0] shl 8;
+          Color.Green:=SampRow^[x*3+1] shl 8;
+          Color.Blue:=SampRow^[x*3+2] shl 8;
+          SetPixel(x, y, Color);
+        end;
       end;
       end;
+
       inc(y);
       inc(y);
     end;
     end;
   end;
   end;

+ 4 - 3
packages/fcl-image/src/fpreadtiff.pas

@@ -1928,7 +1928,8 @@ var
         //MaxM: Test the difference
         //MaxM: Test the difference
         //  result:=CMYKToFPColor(ChannelValues[0],ChannelValues[1],ChannelValues[2],ChannelValues[3]);
         //  result:=CMYKToFPColor(ChannelValues[0],ChannelValues[1],ChannelValues[2],ChannelValues[3]);
         cmyk :=TStdCMYK.New(ChannelValues[0]/$ffff, ChannelValues[1]/$ffff, ChannelValues[2]/$ffff, ChannelValues[3]/$ffff);
         cmyk :=TStdCMYK.New(ChannelValues[0]/$ffff, ChannelValues[1]/$ffff, ChannelValues[2]/$ffff, ChannelValues[3]/$ffff);
-        result :=cmyk.ToExpandedPixel.ToFPColor(true); //MaxM: in Future we can use GammaCompression
+        result :=cmyk.ToExpandedPixel.ToFPColor(true); //Use of GammaCompression or direct?
+        //result :=cmyk.ToFPColor;
       end;
       end;
 
 
     6: // YCBCR: CCIR 601
     6: // YCBCR: CCIR 601
@@ -1936,8 +1937,8 @@ var
         ycbcr :=TYCbCr.New(ChannelValues[0]/$ffff, ChannelValues[1]/$ffff, ChannelValues[2]/$ffff);
         ycbcr :=TYCbCr.New(ChannelValues[0]/$ffff, ChannelValues[1]/$ffff, ChannelValues[2]/$ffff);
 
 
         if IFD.YCbCr_LumaRed<>0
         if IFD.YCbCr_LumaRed<>0
-        then result :=ycbcr.ToLinearRGBA(IFD.YCbCr_LumaRed, IFD.YCbCr_LumaGreen, IFD.YCbCr_LumaBlue).ToExpandedPixel.ToFPColor(false)
-        else result :=ycbcr.ToLinearRGBA(YCbCr_601).ToExpandedPixel.ToFPColor(false);
+        then result :=ycbcr.ToStdRGBA(IFD.YCbCr_LumaRed, IFD.YCbCr_LumaGreen, IFD.YCbCr_LumaBlue).ToFPColor
+        else result :=ycbcr.ToStdRGBA(YCbCr_601).ToFPColor;
       end;
       end;
 
 
      //8: CIELAB: 1976 CIE L*a*b*
      //8: CIELAB: 1976 CIE L*a*b*