From 628c168c86383e6a95f2c54e88021fe7f1713fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Lesi=C5=84ski?= Date: Sun, 10 Jul 2016 19:01:51 +0100 Subject: [PATCH] Implement h1v2 fancy upsampling This allows fancy upsampling to be used when decompressing 4:2:2 images that have been losslessly rotated or transposed. (docs and comments added by DRC) Based on https://github.com/pornel/libjpeg-turbo/commit/f63aca945debde07e7c6476a1f667b71728c3d44 Closes #89 --- ChangeLog.md | 5 +++++ jdsample.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 33b46dc37..dfd11b44b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -43,6 +43,11 @@ Clang/LLVM optimizer uses load combining to transfer multiple adjacent 32-bit structure members into a single 64-bit register, and this exposed the ABI conformance issue. +4. Fancy upsampling is now supported when decompressing JPEG images that use +4:4:0 (h1v2) chroma subsampling. These images are generated when losslessly +rotating or transposing JPEG images that use 4:2:2 (h2v1) chroma subsampling. +The h1v2 fancy upsampling algorithm is not currently SIMD-accelerated. + 1.5.0 ===== diff --git a/jdsample.c b/jdsample.c index 91e29dfb2..b1378e151 100644 --- a/jdsample.c +++ b/jdsample.c @@ -303,6 +303,48 @@ h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr, } +/* + * Fancy processing for 1:1 horizontal and 2:1 vertical (4:4:0 subsampling). + * + * This is a less common case, but it can be encountered when losslessly + * rotating/transposing a JPEG file that uses 4:2:2 chroma subsampling. + */ + +METHODDEF(void) +h1v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr, + JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + JSAMPROW inptr0, inptr1, outptr; +#if BITS_IN_JSAMPLE == 8 + int thiscolsum; +#else + JLONG thiscolsum; +#endif + JDIMENSION colctr; + int inrow, outrow, v; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + for (v = 0; v < 2; v++) { + /* inptr0 points to nearest input row, inptr1 points to next nearest */ + inptr0 = input_data[inrow]; + if (v == 0) /* next nearest is row above */ + inptr1 = input_data[inrow-1]; + else /* next nearest is row below */ + inptr1 = input_data[inrow+1]; + outptr = output_data[outrow++]; + + for(colctr = 0; colctr < compptr->downsampled_width; colctr++) { + thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum + 1) >> 2); + } + } + inrow++; + } +} + + /* * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. * Again a triangle filter; see comments for h2v1 case, above. @@ -431,6 +473,11 @@ jinit_upsampler (j_decompress_ptr cinfo) else upsample->methods[ci] = h2v1_upsample; } + } else if (h_in_group == h_out_group && + v_in_group * 2 == v_out_group && do_fancy) { + /* Non-fancy upsampling is handled by the generic method */ + upsample->methods[ci] = h1v2_fancy_upsample; + upsample->pub.need_context_rows = TRUE; } else if (h_in_group * 2 == h_out_group && v_in_group * 2 == v_out_group) { /* Special cases for 2h2v upsampling */