Skip to content

Commit

Permalink
Implement h1v2 fancy upsampling
Browse files Browse the repository at this point in the history
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 kornelski@f63aca9

Closes libjpeg-turbo#89
  • Loading branch information
kornelski authored and dcommander committed Jul 13, 2016
1 parent 1120ff2 commit 628c168
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
=====
Expand Down
47 changes: 47 additions & 0 deletions jdsample.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 628c168

Please sign in to comment.