From 4c8c4f2d43d5634ac76c877050691f7d6230b9b6 Mon Sep 17 00:00:00 2001 From: Nick Renieris Date: Thu, 29 Aug 2019 16:10:42 +0300 Subject: lavc/tiff: Convert DNGs to sRGB color space Signed-off-by: Nick Renieris --- libavcodec/tiff.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'libavcodec/tiff.c') 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; -- cgit v1.2.3