Giter VIP home page Giter VIP logo

png-decoder's Introduction

PNG Decoder

Demonstration:


Transmitting PNG images into JPG images:

In the video the png images are being transformed into jpg images by first being decoded into a pixel based image structure using the PNG decoder and then transformed into jpg images using external library.

Supported features:


The decoder conforms to the requirements of decoders mentioned in standard PNG specification supporting all the required chunks of the PNG format (i.e. IHDR Image header, PLTE Palette, IDAT Image data, and IEND Image trailer).

Supported images:

  • Grayscale images
  • Regular RGB images
  • Indexed images (i.e. with a fixed palette of colors)
  • Images containing alpha-channel (transparency)

Note: bit depth <= 8 supported. The entry point is Image ReadPng(std::string_view filename) function in png_decoder.h.

Project details:


The pipeline of decoding:

  1. Read signature bytes and validate it.
  2. Read chunks and validate its CRC until IEND chunk encountered.
  3. Save the information provided by IHDR and PLTE chunks for future decoding use.
  4. Concatenate the content of all IDAT chunks into a single byte vector (lets call it V).
  5. Once IEND chunk reached, decoding of V starts: deflate to decompress V into another byte vector D.
  6. Process D by scanlines, applying specified filters.
  7. In case of interlaced image use Adam7 algorithm to decode the image.

External libraries:

  1. zlib1g-dev (zlib) - deflate algorithm for decompressing the image data.
  2. Boost - CRC calculation.

Implementation details:

  1. Decoder is implemented as a class, receiving std::istream& (assuming binary mode) in it's constructor.
  2. Deflate logic is completely separated from the decoder. Since zlib1g-dev (zlib) is a C libraries, there is a RAII wrapper written around the library functionality (see Inflate).
  3. Error handling:
    1. CRC validation for ancillary chunks.
    2. Checking of EOF when reading from the input stream.
    3. Exceptions throwing for invalid png images.
  4. In case of bit depth being less than 8 bits bits reading functionality is used which takes a sequence of bytes and reads it bitwise.

Implementation:


Defiltering data scanlines:

There are 3 main classes that are responsible for decoding the image after deflate algorithm is used: ScanlineReader, Defilter, and PixelStrategy.

ScanlineReader applies defilters to the scanlines to remove additional encoding layer from the actual image data, after that depending on the pixel storing format (which is stored inside IHDR chunk) a concrete implementation of abstract PixelStrategy used to convert scanline bytes into image pixels.

Defilters are concrete implementations of abstact class Defilter that comform to Applicable Design Pattern: the caller (i.e. ScanlineReader) provides every scanline to the method Defilter::applicable which tells whether the currect defilter can be used in order to apply defiltering (it can be determined by a header stored in scanlines), in case of success the caller invokes Defilter::apply:

// ScanlineReader workflow:
for (const auto& defilter : m_defilters) {
    if (defilter->applicable(scanline)) {
        defilter->apply(scanline, m_previousScanline, bpp);
    }
}

Pixel recovery:

PNG format supports 3 main image formats: grayscale, RGB, and color pallete images, where the former two may also contain alpha-channel, which leads to having 5 completely different image formats.

In order to uniformly treat all the image formats the Strategy Design Pattern is applied: factory method PixelStrategy::create determines which image format is used in the current image and returns the concrete implementor of the image format, i.e. one of PixelGrayscaleStrategy, PixelRGBStrategy, PixelPaletteIndexStrategy, PixelGrayscaleAlphaStrategy, and PixelRGBAlphaStrategy:

std::unique_ptr<PixelStrategy> PixelStrategy::create(uint8_t colorType, uint8_t bitDepth, PLTE plte) {
    if (colorType == PIXEL_GRAYSCALE_COLOR_TYPE) {
        return std::make_unique<PixelGrayscaleStrategy>(bitDepth, std::move(plte));
    }
    else if (colorType == PIXEL_RGB_COLOR_TYPE) {
        return std::make_unique<PixelRGBStrategy>(bitDepth, std::move(plte));
    }
    else if (colorType == PIXEL_PALETTE_INDEX_COLOR_TYPE) {
        return std::make_unique<PixelPaletteIndexStrategy>(bitDepth, std::move(plte));
    }
    else if (colorType == PIXEL_GRAYSCALE_ALPHA_COLOR_TYPE) {
        return std::make_unique<PixelGrayscaleAlphaStrategy>(bitDepth, std::move(plte));
    }
    else if (colorType == PIXEL_RGB_ALPHA_COLOR_TYPE) {
        return std::make_unique<PixelRGBAlphaStrategy>(bitDepth, std::move(plte));
    }

    throw exceptions::InvalidColorTypeChunkException(
        PNG_DECODER_ERROR_MESSAGE("Unsupported color type in IHDR: " + std::to_string(colorType)));
}

png-decoder's People

Contributors

vladislav0art avatar

Watchers

 avatar

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.