Skip to content

Commit

Permalink
add XML docs, bump version numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
saucecontrol committed Aug 15, 2018
1 parent e91083d commit 9c5ad98
Show file tree
Hide file tree
Showing 23 changed files with 460 additions and 53 deletions.
74 changes: 61 additions & 13 deletions doc/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Enables MagicImageProcessor's planar format pipeline for images stored in planar
Most image processing software will convert YCbCr JPEG input to RGB for processing and then convert back to YCbCr for JPEG output. In addition to saving the processing time spent on this unnecessary conversion, planar processing allows for other work savings.

* [Chroma subsampled](https://en.wikipedia.org/wiki/Chroma_subsampling) images do not need to have their chroma planes upsampled to the luma size, only to have them rescaled again. MagicScaler can scale the subsampled chroma plane directly to its final size.
* When saving in a chroma subsampled format, the final chroma scaling is done with a high-quality resampler rather than the Linear resampler used by the encoder.
* When processing in [linear light](http://web.archive.org/web/20160826144709/http://www.4p8.com/eric.brasseur/gamma.html), gamma correction needs only be performed on the luma plane.
* When saving in a chroma subsampled format, the final chroma scaling is done with a high-quality resampler rather than the default resampler used by the encoder.
* When processing in [linear light](http://www.ericbrasseur.org/gamma.html), gamma correction needs only be performed on the luma plane.
* When sharpening is applied, it also needs only be performed on the luma plane.

This feature is only available if WIC supports it (Windows 8.1/Windows Server 2012 and above) and the input image format is YCbCr. The output results will be slightly different than those produced with RGB processing but no less correct or visually appealing.
Expand All @@ -19,21 +19,21 @@ Default Value: true

### EnableSimd : static bool

Enables [SIMD](https://en.wikipedia.org/wiki/SIMD) versions of MagicScaler's image convolution and matting/compositing algorithms. For high-quality resampling, SIMD processing yields significant performance improvements. This is most notable with linear light processing, which now has no performance penalty compared with sRGB processing.

If processing predominately with low-quality resampling or in sRGB blending mode, there can be a slight performance penalty for SIMD processing. You can disable this if your use cases do not follow the high-quality MagicScaler defaults.
Enables [SIMD](https://en.wikipedia.org/wiki/SIMD) versions of many of MagicScaler's algorithms. For high-quality resampling, SIMD processing yields significant performance improvements.

Note that the SIMD processing is done in floating point whereas the standard processing is done in fixed point math. This will result in very slight output differences due to rounding. Differences will not be visually significant but can be detected with a binary compare.

This property should only be used for testing/troubleshooting. Forcing floating point processing on incompatible hardware or runtimes will result in very poor performance, and disabling it when supported will sacrifice much of MagicScaler's current and future optimization.

Default Value: true if the runtime/JIT and hardware support hardware-accelerated System.Numerics.Vectors, otherwise false

### ProcessImage(string, Stream, ProcessImageSettings)

Accepts a file path for the input image, a stream for the output image, and a [ProcessImageSettings](#processimagesettings) object for settings. The output stream must allow Seek and Write. Returns a [ProcessImageResult](#processimageresult).

### ProcessImage(ArraySegment<byte>, Stream, ProcessImageSettings)
### ProcessImage(ReadOnlySpan<byte>, Stream, ProcessImageSettings)

Accepts a byte ArraySegment for the input image, a stream for the output image, and a [ProcessImageSettings](#processimagesettings) object for settings. The output stream must allow Seek and Write. Returns a [ProcessImageResult](#processimageresult).
Accepts a ReadOnlySpan for the input image, a stream for the output image, and a [ProcessImageSettings](#processimagesettings) object for settings. The output stream must allow Seek and Write. Returns a [ProcessImageResult](#processimageresult).

### ProcessImage(Stream, Stream, ProcessImageSettings)

Expand All @@ -47,9 +47,9 @@ Accepts an [IPixelSource](#ipixelsource) input, a stream for the output image, a

Accepts a file path for the input image and a [ProcessImageSettings](#processimagesettings) object for settings. Returns a [ProcessingPipeline](#processingpipeline) for custom processing.

### BuildPipeline(ArraySegment<byte>, ProcessImageSettings)
### BuildPipeline(ReadOnlySpan<byte>, ProcessImageSettings)

Accepts a byte ArraySegment for the input image and a [ProcessImageSettings](#processimagesettings) object for settings. Returns a [ProcessingPipeline](#processingpipeline) for custom processing.
Accepts a ReadOnlySpan for the input image and a [ProcessImageSettings](#processimagesettings) object for settings. Returns a [ProcessingPipeline](#processingpipeline) for custom processing.

### BuildPipeline(Stream, ProcessImageSettings)

Expand Down Expand Up @@ -187,6 +187,18 @@ An [UnsharpMaskSettings](#unsharpmasksettings) object specifying sharpening sett

Default value: unset

### ColorProfileMode : ColorProfileMode

A [ColorProfileMode](#colorprofilemode) value indicating how embedded [ICC Color Profiles](https://en.wikipedia.org/wiki/ICC_profile) are handled during processing.

Default value: Normalize

### OrientationMode : OrientationMode

An [OrientationMode](#orientationmode) value indicating how [Exif Orientation](https://magnushoff.com/jpeg-orientation.html) correction is handled during processing.

Default value: Normalize

## CropAnchor

A flags enumeration for specifying auto-crop anchor.
Expand Down Expand Up @@ -255,11 +267,11 @@ An enumeration for specifying the light blending mode used for high-quality scal

### Linear

Perform the high-quality scaling in [linear light](http://web.archive.org/web/20160826144709/http://www.4p8.com/eric.brasseur/gamma.html) colorspace. This will give better results in most cases but at a performance cost.
Convert values to linear RGB before blending. This is more [mathematically correct](http://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/) and more visually pleasing in most cases.

### sRGB
### Companded

Perform the high-quality scaling in gamma-corrected sRGB colorspace. This will yield output more similar to other scaling software but will be less correct in most cases.
Blend companded R'G'B' values directly. This is usually a poor choice but may be used for compatibility with other software or where speed is more important than image quality.

## ChromaSubsampleMode

Expand Down Expand Up @@ -313,6 +325,42 @@ JPEG. Use JpegQuality and JpegSubsampleMode settings to control output.

Uncompressed 24-bit or 32-bit TIFF, depending on whether or not the input image contains an alpha channel.

## ColorProfileMode

An enumeration for indicating how embedded [ICC Color Profiles](https://en.wikipedia.org/wiki/ICC_profile) are handled.

### Normalize

Convert the input image to the [sRGB color space](https://en.wikipedia.org/wiki/SRGB) during processing. Output an untagged sRGB image.

### NormalizeAndEmbed

Convert the input image to the sRGB color space during processing. Embed a [compact sRGB profile](https://github.com/saucecontrol/Compact-ICC-Profiles) in the output. This option ensures maximum compatibility with web browsers and other software but results slightly larger (+456 bytes) output files.

### Preserve

Preserve the input image color space during processing. Embed the ICC profile in the output image. If the output format does not support embedded profiles, it will be discarded. Use this option only if the output format and viewing software support color management.

### Ignore

Ignore any embedded profiles and treat the image as sRGB data. Do not tag the output image. This option may result in significant changes to output color and should only be used if the embedded profile is known to be incorrect.

## OrientationMode

An enumeration for indicating how [Exif Orientation](https://magnushoff.com/jpeg-orientation.html) is handled.

### Normalize

Correct the image orientation according to the Exif tag on load. Save the output in normal orientation. This option ensures maximum compatibility with viewer software.

### Preserve

Preserve the orientation of the input image and tag the output image to reflect the orientation. If the output format does not support orientation tagging, it will be discarded. Use this option only if the output format and viewing software support orientation correction.

### Ignore

Ignore any orientation tag and treat the image as if its stored orientation is normal. Do not tag the output image. This option should only be used if the Exif orientation of the input image is known to be incorrect.

## UnsharpMaskSettings

A structure for specifying the settings used for the post-resize [sharpening](https://en.wikipedia.org/wiki/Unsharp_masking) of the output image. These settings are designed to function similarly to the Unsharp Mask settings in Photoshop.
Expand Down Expand Up @@ -505,4 +553,4 @@ True if the image frame has a separate alpha channel or if it is in an indexed f

### ExifOrientation: Orientation

The [Exif Orientation](http://www.impulseadventure.com/photo/exif-orientation.html) value stored for this image frame. The Width and Height values are pre-corrected according to this value, so you can ignore it if you are using MagicScaler to process the image, as it performs orientation correction automatically. The integer values defined in the Orientation enumeration match the stored Exif values.
The [Exif Orientation](https://magnushoff.com/jpeg-orientation.html) value stored for this image frame. The Width and Height values are pre-corrected according to this value, so you can ignore it if you are using MagicScaler to process the image, as it performs orientation correction automatically. The integer values defined in the Orientation enumeration match the stored Exif values.
17 changes: 1 addition & 16 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,6 @@ WebRSize must be configured in your application's web.config file. It will not
See the [documentation page](doc/web.md) for more details.


Release History
---------------
#### MagicScaler 0.8.4.0
* Fixed an issue that caused sharpening to be a no-op when working with some pixel formats in sRGB blending mode.
* Improved quality of scaling and sharpening with partially-transparent images.
* Added [GitLink](https://github.com/GitTools/GitLink) to enable github source server support for debugging.

#### WebRSize 0.3.2.0
* Fixed incorrect file extension for 404 images in the disk cache
* Added exception handler for "Client Disconnected" errors when transmitting images from the HttpHandler
* Added devicePixelRatio (dpr) setting to enable automatic size and quality adjustments for retina clients
* Added "q" shortcut for quality setting

See the [releases page](https://github.com/saucecontrol/PhotoSauce/releases) for previous updates.

Versioning
----------

Expand All @@ -88,7 +73,7 @@ This project is using [semantic versioning](http://semver.org/). Releases witho
Contributing
------------

Because this project is still under active design and development, I am not accepting unsolicited pull requests at this time. If you find a bug or would like to see a new feature implemented, please open a new issue for further discussion. This will hopefully save any wasted or duplicate efforts. If we can agree on a direction, help would be most welcome.
Contributions are welcome, but please open a new issue for discussion before submitting any pull requests. This will hopefully save any wasted or duplicate efforts.

License
-------
Expand Down
31 changes: 31 additions & 0 deletions src/MagicScaler/Core/ImageFileInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@

namespace PhotoSauce.MagicScaler
{
/// <summary>Represents basic information about an image container.</summary>
public sealed class ImageFileInfo
{
/// <summary>Represents basic information about an image frame within a container.</summary>
public readonly struct FrameInfo
{
/// <summary>The width of the image frame in pixels.</summary>
public int Width { get; }
/// <summary>The height of the image frame in pixels.</summary>
public int Height { get; }
/// <summary>True if the image frame contains transparency data, otherwise false.</summary>
public bool HasAlpha { get; }
/// <summary>
/// The stored <a href="https://magnushoff.com/jpeg-orientation.html">Exif orientation</a> for the image frame.
/// The <see cref="Width" /> and <see cref="Height" /> values reflect the corrected orientation, not the stored orientation.
/// </summary>
public Orientation ExifOrientation { get; }

/// <summary>Constructs a new <see cref="FrameInfo" /> instance with the supplied values.</summary>
/// <param name="width">The width of the image frame in pixels.</param>
/// <param name="height">The height of the image frame in pixels.</param>
/// <param name="hasAlpha">True if the image frame contains transparency data, otherwise false.</param>
/// <param name="orientation">The Exif orientation associated with the image frame.</param>
public FrameInfo(int width, int height, bool hasAlpha, Orientation orientation)
{
Width = width;
Expand All @@ -21,17 +35,26 @@ public FrameInfo(int width, int height, bool hasAlpha, Orientation orientation)
}
}

/// <summary>The size of the image container in bytes.</summary>
public long FileSize { get; private set; }
/// <summary>The last modified date of the image container, if applicable.</summary>
public DateTime FileDate { get; private set; }
/// <summary>The format of the image container (e.g. JPEG, PNG).</summary>
public FileFormat ContainerType { get; private set; }
/// <summary>One or more <see cref="FrameInfo" /> instances describing each image frame in the container.</summary>
public FrameInfo[] Frames { get; private set; }

/// <summary>Constructs a new <see cref="ImageFileInfo" /> instance with a single frame of the specified <paramref name="width" /> and <paramref name="height" />.</summary>
/// <param name="width">The width of the image frame in pixels.</param>
/// <param name="height">The height of the image frame in pixels.</param>
public ImageFileInfo(int width, int height)
{
Frames = new[] { new FrameInfo(width, height, false, Orientation.Normal) };
ContainerType = FileFormat.Unknown;
}

/// <summary>Constructs a new <see cref="ImageFileInfo" /> instance by reading the metadata from an image file header.</summary>
/// <param name="imgPath">The path to the image file.</param>
public ImageFileInfo(string imgPath)
{
var fi = new FileInfo(imgPath);
Expand All @@ -45,8 +68,12 @@ public ImageFileInfo(string imgPath)
FileDate = fi.LastWriteTimeUtc;
}

/// <inheritdoc cref="ImageFileInfo(ReadOnlySpan{byte}, DateTime)" />
public ImageFileInfo(ReadOnlySpan<byte> imgBuffer) : this(imgBuffer, DateTime.MinValue) { }

/// <summary>Constructs a new <see cref="ImageFileInfo" /> instance by reading the metadata from an image file contained in a <see cref="ReadOnlySpan{T}" />.</summary>
/// <param name="imgBuffer">The buffer containing the image data.</param>
/// <param name="lastModified">The last modified date of the image container.</param>
public ImageFileInfo(ReadOnlySpan<byte> imgBuffer, DateTime lastModified)
{
if (imgBuffer == default) throw new ArgumentNullException(nameof(imgBuffer));
Expand All @@ -58,8 +85,12 @@ public ImageFileInfo(ReadOnlySpan<byte> imgBuffer, DateTime lastModified)
FileDate = lastModified;
}

/// <inheritdoc cref="ImageFileInfo(Stream, DateTime)" />
public ImageFileInfo(Stream imgStream) : this(imgStream, DateTime.MinValue) { }

/// <summary>Constructs a new <see cref="ImageFileInfo" /> instance by reading the metadata from an image file exposed by a <see cref="Stream" />.</summary>
/// <param name="imgStream">The stream containing the image data.</param>
/// <param name="lastModified">The last modified date of the image container.</param>
public ImageFileInfo(Stream imgStream, DateTime lastModified)
{
if (imgStream is null) throw new ArgumentNullException(nameof(imgStream));
Expand Down
Loading

0 comments on commit 9c5ad98

Please sign in to comment.