Skip to content

Refactored the decoder and encoder options. - #113

Merged
dlemstra merged 26 commits into
SixLabors:masterfrom
dlemstra:decoder-encoder-options
Feb 22, 2017
Merged

dlemstra merged 26 commits into
SixLabors:masterfrom
dlemstra:decoder-encoder-options

Conversation

@dlemstra

Copy link
Copy Markdown
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following matches the existing coding patterns and practise as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

This pull requests adds the features requested in #26:

  • Create Options classes to pass to the encoders and decoders to reduce parameter count.
  • Create overload for Image<TColor, TPacked> that allows passing a specific decoder or decoders with options.

This was already changed in my previous pull request (#99):

  • Remove Quality property from Image<TColor, TPacked>

This pull request also adds support for skipping reading/writing metadata as requested in #11.

Fixes #26
Fixes #11

@codecov-io

codecov-io commented Feb 21, 2017 •

Copy link
Copy Markdown

Codecov Report

Merging #113 into master will increase coverage by 0.07%.
The diff coverage is 88.69%.

@@            Coverage Diff            @@
##           master    #113      +/-   ##
=========================================
+ Coverage   88.12%   88.2%   +0.07%     
=========================================
  Files         429     441      +12     
  Lines       20042   20364     +322     
  Branches     1431    1448      +17     
=========================================
+ Hits        17663   17963     +300     
- Misses       1972    1995      +23     
+ Partials      407     406       -1
Impacted Files Coverage Δ
src/ImageSharp.Formats.Bmp/BmpDecoder.cs 100% <ø> (ø) ✅
...ts/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs 100% <ø> (ø)
...Sharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs 0% <ø> (ø) ✅
tests/ImageSharp.Tests/TestFile.cs 94.82% <100%> (+0.28%) ✅
src/ImageSharp.Formats.Png/PngDecoderOptions.cs 100% <100%> (ø)
src/ImageSharp.Formats.Gif/GifEncoder.cs 100% <100%> (ø) ✅
...harp.Tests/TestUtilities/ImagingTestCaseUtility.cs 95.23% <100%> (ø) ✅
src/ImageSharp.Formats.Png/ImageExtensions.cs 100% <100%> (ø) ✅
...s/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs 100% <100%> (ø) ✅
src/ImageSharp.Formats.Gif/GifDecoder.cs 100% <100%> (ø) ✅
... and 44 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b334834...ffe7f96. Read the comment docs.

@JimBobSquarePants JimBobSquarePants left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a great addition, really cleaning the the mess that was the codec options!

Just a few questions and a minor XML comment change.

/// <returns>The options for the <see cref="BmpEncoder"/>.</returns>
internal static IBmpEncoderOptions Create(IEncoderOptions options)
{
IBmpEncoderOptions bmpOptions = options as IBmpEncoderOptions;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Couldn't this be

return options as IBmpEncoderOptions ?? new BmpEncoderOptions(options);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah I could and should have done that.

/// <summary>
/// Gets the default encoding to use when reading comments.
/// </summary>
public static Encoding DefaultEncoding { get; } = Encoding.GetEncoding("ASCII");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Amazed that the specs don't restrict this. Good catch.

/// </summary>
/// <param name="options">The decoder options.</param>
public GifDecoderCore(IGifDecoderOptions options)
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When is it possible to call new GifDecoderCore(null) ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This will happen when you call the constructor of Image without options (options=null). The GifDecoder will just forward the value.

/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="image">The <see cref="ImageBase{TColor}"/> to be encoded.</param>
/// <param name="writer">The stream to write to.</param>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice addition!

/// <summary>
/// Gets or sets the transparency threshold.
/// </summary>
public byte Threshold { get; set; } = 128;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thinking about that we should probably reduce the value now we have dithering. Our output should be much cleaner. Do you know of any other encoders that offer this option? We should follow the most common default.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can take a look at what we do inside ImageMagick but I think we always use dithering.

=> source.Save(stream, new GifEncoder { Quality = quality });
{
GifEncoder encoder = new GifEncoder();
encoder.Encode(source, stream, options);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Well that answers my question earlier 😄

/// <value>The quality of the jpg image from 0 to 100.</value>
public int Quality
/// <inheritdoc/>
public void Encode<TColor>(Image<TColor> image, Stream stream, IEncoderOptions options)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So much cleaner!

}
quality = quality.Clamp(1, 100);

this.outputStream = stream;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we have that marked as 80 and below for 420 in the quality XML comments, 91 is the correct value for switching so we should say 90.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I updated the comments.

/// index must be between 0 and 100 (compression from max to min).
/// </summary>
/// <remarks>
/// If the quality is less than or equal to 80, the subsampling ratio will switch to <see cref="JpegSubsample.Ratio420"/>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yup, should be 90 here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed and removed the remarks from the interface.

}

if (this.Quantizer == null)
if (this.quantizer == null)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this something we should be handling in the options?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah IPngEncoderOptions.Quantizer is not used in PngEncoderCore!

@dlemstra dlemstra Feb 22, 2017 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It looks like a mistake that I forgot to use the quantizer from the options. Thanks @antonfirsov! I could not set it inside the options due to the {TColor} restriction.

@antonfirsov

Copy link
Copy Markdown
Member

Well done, seems OK to me!

@JimBobSquarePants JimBobSquarePants added this to the Beta 1 milestone Feb 22, 2017
@tocsoft

tocsoft commented Feb 22, 2017

Copy link
Copy Markdown
Member

My only concern is the usage of optional arguments.

We shouldn't be using them on out public API's it makes them a lot harder to version in the future. See this blog post for details http://haacked.com/archive/2010/08/10/versioning-issues-with-optional-arguments.aspx/

I understand there are more instances of this thru-out the codebase so its probably not worth bothering to fix it in this PR and we should instead creating a separate issue/PR fixing them all.

Apart from the optional arguments this looks good to me.

@dlemstra

Copy link
Copy Markdown
Member Author

I also prefer to use overloads instead of optional arguments. The current code base already uses a lot of optional arguments so that is why I used that. I can change it inside this pull request to use overloads instead of optional arguments. Your thought @JimBobSquarePants?

@JimBobSquarePants

Copy link
Copy Markdown
Member

@dlemstra @tocsoft We probably should change any to not use them. I've actually been burnt by that issue in the past.

@dlemstra

Copy link
Copy Markdown
Member Author

Just pushed the last change. I think we are ready to merge.

@dlemstra
dlemstra force-pushed the decoder-encoder-options branch from 9db6823 to a739109 Compare February 22, 2017 17:14

@tocsoft tocsoft left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

much better with the overloads instead of the optional args. 👍

@dlemstra
dlemstra force-pushed the decoder-encoder-options branch from a739109 to ffe7f96 Compare February 22, 2017 17:19
@dlemstra

Copy link
Copy Markdown
Member Author

We should probably create a new issue/pull request to remove all the optional arguments.

@tocsoft

tocsoft commented Feb 22, 2017

Copy link
Copy Markdown
Member

I've added an issue to track the required work.

@JimBobSquarePants

JimBobSquarePants commented Feb 22, 2017 •

Copy link
Copy Markdown
Member

Great. @dlemstra do you want to do the honours? :shipit:

@dlemstra
dlemstra merged commit 0853c66 into SixLabors:master Feb 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants