Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add force subsample argument to JPEG save #1552

Merged
merged 15 commits into from
Feb 18, 2020
Merged

Conversation

Elad-Laufer
Copy link
Contributor

If Q >= 90 then subsampling is disabled, this argument forces it

@jcupitt
Copy link
Member

jcupitt commented Feb 16, 2020

Hello @Elad-Laufer,

We already have no-subsample and Q. Perhaps we should deprecate no-subsample and have a three way switch: force on, force off, automatic (set by Q), with auto as the default.

@lovell
Copy link
Member

lovell commented Feb 17, 2020

If there's a plan to offer more fine-grained control over subsampling, perhaps we should consider allowing 4:2:2 as well as 4:4:4 ("no-subsample") and 4:2:0 ("force-subsample")?

@jcupitt
Copy link
Member

jcupitt commented Feb 17, 2020

I looked into this when we added jpeg-chroma-subsample to jpegload: the only two supported settings for JPEG are 4:4:4 (no subsampling) and 4:2:0 (subsample both Cb and Cr by 2). It's very confusing :(

http://poynton.ca/PDFs/Chroma_subsampling_notation.pdf

edit: of course there are CMYK JPG too, but they never have subsampled K, so the full set of chroma subsample settings are:

4:2:0:4
4:4:4:4
4:2:0
4:4:4

@jcupitt
Copy link
Member

jcupitt commented Feb 17, 2020

(or that's my understanding from that useful PDF)

@lovell
Copy link
Member

lovell commented Feb 17, 2020

@jcupitt Thanks for the info, no worries, let's keep this as simple as possible.

Copy link
Member

@jcupitt jcupitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks great! Thank you very much for doing this work.

I think we should deprecate no_subsample, otherwise it's just nitpicks.

libvips/foreign/jpegsave.c Show resolved Hide resolved
@@ -230,7 +241,7 @@ vips_foreign_save_jpeg_target_build( VipsObject *object )
jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not pass no_subsample. Instead, a little higher up, have something like:

if arg-set("no_subsample") && !arg_set("subsample_mode")
  subsample_mode = no_subsample ? OFF : ON

ie. old code using the no_subsample arg is able to set the default for the new subsample_mode value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I add the check to each _build(...) function? currently I only check once at vips__jpeg_write_target(...).

Is there a way to perform the check in single point without code duplication?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, add a build method to the base class for jpegsave and do the test after chaining up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiffsave has something a little like this:

https://github.com/libvips/libvips/blob/master/libvips/foreign/tiffsave.c#L153

A _build method on the base class and use of isset to set defaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -297,7 +307,7 @@ vips_foreign_save_jpeg_file_build( VipsObject *object )
jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, remove no_subsample.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -367,7 +377,7 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object )
jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove 'no_subsample`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -440,7 +450,7 @@ vips_foreign_save_jpeg_mime_build( VipsObject *object )
jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

break;
case VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO:
/* Turn off chroma subsampling. Follow IM and do it automatically for
* high Q.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asterisks should line up.

/* Like 
 * this.
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

break;
}
case VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF:
default: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline before {, like a func definition, and for formatted as:

for( i = 0; i < xxx; i++ ) { 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if( no_subsample ) {
subsample_mode = VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if() can go if we have the extra logic in _build().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


# higher Q should mean a bigger buffer
q10 = im.jpegsave_buffer(Q=10)
q10_subsample_off = im.jpegsave_buffer(Q=10, subsample_mode=2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use the string value here, ie. "off".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

# higher Q should mean a bigger buffer
q10 = im.jpegsave_buffer(Q=10)
q10_subsample_off = im.jpegsave_buffer(Q=10, subsample_mode=2)
q10_subsample_no = im.jpegsave_buffer(Q=10, no_subsample=1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should have deprecated API being tested in the test suite, let's remove this.

Same for the case below. Just test on, off, auto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

@jcupitt jcupitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look great! Thanks again, I'll merge.

@jcupitt jcupitt merged commit fefefdf into libvips:master Feb 18, 2020
jcupitt added a commit that referenced this pull request Feb 18, 2020
fix up some formatting from #1552

plus some other small changes
@jcupitt
Copy link
Member

jcupitt commented Feb 18, 2020

I revised the formatting slightly and added some docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants