Commit 82d8cdde by Anton Mitrofanov Committed by Fiona Glaser

### Use TV range algorithm for bit-depth conversions

Such sources are more common, so better to be correct for the common case.
This also produces less error for the case of full range than the previous algorithm produced for the case of TV range.
parent 27a7b05b
 ... ... @@ -65,12 +65,12 @@ static int csp_num_interleaved( int csp, int plane ) * depth again is lossless. */ #define DITHER_PLANE( pitch ) \ static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int src_stride, \ int width, int height, int16_t *errors ) \ int width, int height, int16_t *errors ) \ { \ const int lshift = 16-BIT_DEPTH; \ const int rshift = 2*BIT_DEPTH-16; \ const int rshift = 16-BIT_DEPTH+2; \ const int half = 1 << (16-BIT_DEPTH+1); \ const int pixel_max = (1 << BIT_DEPTH)-1; \ const int half = 1 << (16-BIT_DEPTH); \ memset( errors, 0, (width+1) * sizeof(int16_t) ); \ for( int y = 0; y < height; y++, src += src_stride, dst += dst_stride ) \ { \ ... ... @@ -78,8 +78,8 @@ static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int for( int x = 0; x < width; x++ ) \ { \ err = err*2 + errors[x] + errors[x+1]; \ dst[x*pitch] = x264_clip3( (((src[x*pitch]+half)<<2)+err)*pixel_max >> 18, 0, pixel_max ); \ errors[x] = err = src[x*pitch] - (dst[x*pitch] << lshift) - (dst[x*pitch] >> rshift); \ dst[x*pitch] = x264_clip3( ((src[x*pitch]<<2)+err+half) >> rshift, 0, pixel_max ); \ errors[x] = err = src[x*pitch] - (dst[x*pitch] << lshift); \ } \ } \ } ... ... @@ -114,13 +114,8 @@ static void dither_image( cli_image_t *out, cli_image_t *img, int16_t *error_buf static void scale_image( cli_image_t *output, cli_image_t *img ) { /* this function mimics how swscale does upconversion. 8-bit is converted * to 16-bit through left shifting the orginal value with 8 and then adding * the original value to that. This effectively keeps the full color range * while also being fast. for n-bit we basically do the same thing, but we * discard the lower 16-n bits. */ int csp_mask = img->csp & X264_CSP_MASK; const int shift = 16-BIT_DEPTH; const int shift = BIT_DEPTH - 8; for( int i = 0; i < img->planes; i++ ) { uint8_t *src = img->plane[i]; ... ... @@ -131,7 +126,7 @@ static void scale_image( cli_image_t *output, cli_image_t *img ) for( int j = 0; j < height; j++ ) { for( int k = 0; k < width; k++ ) dst[k] = ((src[k] << 8) + src[k]) >> shift; dst[k] = src[k] << shift; src += img->stride[i]; dst += output->stride[i]/2; ... ...
 ... ... @@ -113,9 +113,8 @@ static int read_frame_internal( cli_pic_t *pic, raw_hnd_t *h ) uint16_t *plane = (uint16_t*)pic->img.plane[i]; uint64_t pixel_count = h->plane_size[i]; int lshift = 16 - h->bit_depth; int rshift = 2*h->bit_depth - 16; for( uint64_t j = 0; j < pixel_count; j++ ) plane[j] = (plane[j] << lshift) + (plane[j] >> rshift); plane[j] = plane[j] << lshift; } } return error; ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!