Skip to content

Use decoded quantization tables for Jpeg encoding, store them in JpegMetadata #1705

@br3aker

Description

@br3aker

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

https://user-images.githubusercontent.com/20967409/126037087-16a8bd51-8cc5-46c8-ab8a-e66d625a8595.jpg
This image gains a lot of noise after decode-encode scenario (you better download it and magnify with some app or use a histogram):

9483_comparison

Steps to Reproduce

Image above with:

using var image = Image.Load(loadPath);
JpegEncoder encoder = new JpegEncoder { };
image.SaveAsJpeg(savePath, encoder);

Cause

Given photo uses some really strange quantization tables:

image

Non-standard tables are not a problem but current QualityEvaluator misses this one quiet drastically:

// DQT #1
Quality estimation:
        Standard: False
        Quality: 70

// DQT #2
Quality estimation:
        Standard: False
        Quality: 52

// image.Metadata.GetJpegMetadata().Quality
Loaded image quality: 52

// JPEGsnoop output:
Approx quality factor = 71.19 (scaling=57.62 variance=593.35) - Luminance
Approx quality factor = 80.24 (scaling=39.51 variance=961.47) - Chrominance

So now we have 2 problems:

  1. Huge miss on quality
  2. Deducting quality twice as current code does not differ 2+ DQT markers

Proposal

Save decoded jpeg quantization tables to the jpeg metadata and use it as backup in the encoder:

// somewhere in the jpeg encoder

// always prefer explicit quality
if(options.Quality != null) 
{
    return GetStandardQuantizationTablesFromQuality(options.Quality);
}
if(metadata.UsesStandardQuantizationTables)
{
    return GetStandardQuantizationTablesFromQuality(metadata.Quality);
}
return metadata.QuantizationTables;

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions