Code Monkey home page Code Monkey logo

pingu's Introduction

Pingu

Join the chat at https://gitter.im/pingu-png/Lobby Build status

Pingu is a fully managed PNG encoder, written in C#.

Goals

Pingu's goal is to be a full-featured PNG encoder, written entirely in C#, with as few external dependencies as possible.

It intends to produce images that pass pngcheck, and that validate in all of the most common encoders. Performance, while important, is a secondary concern for Pingu. Code will prefer to be clean rather than fast, unless it can balance both.

License

Pingu is licensed under the MIT license. See LICENSE.md.

pingu's People

Contributors

bojanrajkovic avatar gitter-badger avatar

Stargazers

 avatar

Watchers

James Cloos avatar

pingu's Issues

CI

Set up CI & produce packages

Implement Paeth predictor filter

The Paeth predictor filter is based on 3 neighbors: left, up, and up and left. The

Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))

Prior and Raw are defined the same way as in the other predictors. All math must be done exactly, without overflow, except for the final step of subtracting the Paeth predictor value from the Raw value.

The predictor pseudocode is as follows:

function PaethPredictor (a, b, c)
   begin
        ; a = left, b = above, c = upper left
        p := a + b - c        ; initial estimate
        pa := abs(p - a)      ; distances to a, b, c
        pb := abs(p - b)
        pc := abs(p - c)
        ; return nearest of a,b,c,
        ; breaking ties in order a,b,c.
        if pa <= pb AND pa <= pc then return a
        else if pb <= pc then return b
        else return c
   end

The tiebreak order is important. To reverse the order, apply the following calculation:

Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))

The same predictor function is used.

Implement alpha separation

Section 4.3.2 of the standard says that encoders should, as part of encoding, implement alpha separation as follows: "If all alpha samples in a reference image have the maximum value, then the alpha channel may be omitted, resulting in an equivalent image that can be encoded more compactly."

Implement alpha compaction

4.3.5 Alpha compaction

For non-indexed images, if there exists an RGB (or greyscale) value such that all pixels with that value
are fully transparent while all other pixels are fully opaque, then the alpha channel can be represented
more compactly by merely identifying the RGB (or greyscale) value that is transparent.

This allows you to transform an image type with alpha into one without it if there is a fully transparent RGB/grayscale value by writing an image w/o an alpha channel and then using a tRNS chunk to indicate the transparent value. See 4.2.1.1. tRNS Transparency.

Implement Sub filter

The Sub filter is filter type 1, and operates as follows:

Sub(x) = Raw(x) - Raw(x - bpp)

For the first pixel in any given scanline, Sub(x) does not wrap around and Raw(x - bpp) is assumed to be 0.

To restore the value, calculate Sub(x) + Raw(x - bpp).

Implement RGB merging

Section 4.3.4 of the standard, RGB merging:

"If the red, green, and blue channels have the same sample depth, and for each pixel the values of the red, green, and blue samples are equal, then these three channels may be merged into a single greyscale channel."

We already support grayscale conversions via Color.

Implement Up filter

The Up filter is filter type 2, and operates as follows:

Up(x) = Raw(x) - Prior(x)

For any byte in the first scanline, Prior(x) is 0, otherwise it's byte x in the previous scanline. Arithmetic is unsigned, done modulo 256.

To restore the pixel value, calculate Up(x) + Prior(x)

Revisit Filter API

In deb9423, I changed the API to be FilterInto rather than Filter. Upon some reflection, it might be better to have Filter do the allocation, and the caller can just write the single filter type byte directly to the compressed stream. It should be buffering, so WriteByte won't kill performance.

Implement Avg filter

The Avg filter is filter type 3, and operates as follows:

Average(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2)

Raw(x-bpp) and Prior(x) are defined as in the Sub and Up filters

To restore the pixel value, calculate Average(x) + floor((Raw(x-bpp)+Prior(x))/2).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.