[FFmpeg-cvslog] lavc/tiff: Convert DNGs to sRGB color space

Nick Renieris git at videolan.org
Mon Sep 2 11:52:47 EEST 2019


ffmpeg | branch: master | Nick Renieris <velocityra at gmail.com> | Thu Aug 29 16:10:42 2019 +0300| [4c8c4f2d43d5634ac76c877050691f7d6230b9b6] | committer: Paul B Mahol

lavc/tiff: Convert DNGs to sRGB color space

Signed-off-by: Nick Renieris <velocityra at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4c8c4f2d43d5634ac76c877050691f7d6230b9b6
---

 libavcodec/tiff.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 0ed550dc16..8ba3e510e3 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -731,14 +731,23 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid
     return 0;
 }
 
+static float av_always_inline linear_to_srgb(float value) {
+    if (value <= 0.0031308f)
+        return value * 12.92f;
+    else
+        return powf(value * 1.055f, 1.0f / 2.4f) - 0.055f;
+}
+
 /**
- * Map stored raw sensor values into linear reference values.
- * See: DNG Specification - Chapter 5
+ * Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5)
+ * Then convert to sRGB color space.
  */
-static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
-                                                    const uint16_t *lut,
-                                                    uint16_t black_level,
-                                                    float scale_factor) {
+static uint16_t av_always_inline dng_process_color16(uint16_t value,
+                                                     const uint16_t *lut,
+                                                     uint16_t black_level,
+                                                     float scale_factor) {
+    float value_norm;
+
     // Lookup table lookup
     if (lut)
         value = lut[value];
@@ -747,16 +756,19 @@ static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
     value = av_clip_uint16_c((unsigned)value - black_level);
 
     // Color scaling
-    value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 0xFFFF));
+    value_norm = (float)value * scale_factor;
+
+    // Color space conversion (sRGB)
+    value = av_clip_uint16_c((uint16_t)(linear_to_srgb(value_norm) * 0xFFFF));
 
     return value;
 }
 
-static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+static uint16_t av_always_inline dng_process_color8(uint16_t value,
                                                     const uint16_t *lut,
                                                     uint16_t black_level,
                                                     float scale_factor) {
-    return dng_raw_to_linear16(value, lut, black_level, scale_factor) >> 8;
+    return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
 }
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
@@ -774,7 +786,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
             uint16_t *src_u16 = (uint16_t *)src;
 
             for (col = 0; col < width; col++)
-                *dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
+                *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor);
 
             dst += dst_stride * sizeof(uint16_t);
             src += src_stride * sizeof(uint16_t);
@@ -782,7 +794,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
     } else {
         for (line = 0; line < height; line++) {
             for (col = 0; col < width; col++)
-                *dst++ = dng_raw_to_linear8(*src++, s->dng_lut, s->black_level, scale_factor);
+                *dst++ = dng_process_color8(*src++, s->dng_lut, s->black_level, scale_factor);
 
             dst += dst_stride;
             src += src_stride;



More information about the ffmpeg-cvslog mailing list