Skip to content
/ jpezy Public

🖼 Full scratch simple JPEG encoder + decoder implementation.

License

Notifications You must be signed in to change notification settings

falgon/jpezy

Repository files navigation

   _
  (_)_ __   ___ _____   _
  | | '_ \ / _ \_  / | | |
  | | |_) |  __// /| |_| |
 _/ | .__/ \___/___|\__, |
|__/|_|             |___/

Build Status Codacy Badge

jpeg + lazy = jpezy

The lazy and simply JPEG encoder + JPEG decoder implementation. This project is not for practical because it was implemented for learning.

Requirements

Limitations and specifications

Encoder

$ convert -compress none <input image file> <output.ppm>
  • Huffman codes and quantization tables are fixed (Reference: ISO/IEC 10918-1 ITU-T 81 Annex K)
  • JFIF version 1.02
  • The sampling rate is fixed to 2 : 1
  • The restart interval is unabled
  • The thumbnail is unabled
  • Even if it is a gray scale image, this tool will use component that Cb and Cr

The following is an example of the result that compressed The Standart Test Images of Lena.

$ convert -compress none lena512color.tiff lena.ppm
$ ./jpezy_encode lena.ppm lena.jpg
   _
  (_)_ __   ___ _____   _
  | | '_ \ / _ \_  / | | |
  | | |_) |  __// /| |_| |
 _/ | .__/ \___/___|\__, |
|__/|_|             |___/       by roki

Reading the input file... width: 512 height: 512
Done! Processing time: 0.522(sec)
Start encoding and writing ...
Write JPEG Header ... Done! Processing time: 0(sec)
Encoding ... Done! Processing time: 0.042(sec)
Write EOI ... Done! Processing time: 0(sec)
Output size: 18010 byte
Done! Processing time: 0.045(sec)
Total processing time: 0.567

$ file lena.jpg
output.jpg: JPEG image data, JFIF standard 1.02, resolution (DPI), density 96x96, segment length 16, comment: "Encoded by jpezy", baseline, precision 8, 512x512, frames 3

Decoder

The following is an example of the result that compressed The Standart Test Images of Lena.

$ ./jpezy_decode lena.jpg output.ppm
   _
  (_)_ __   ___ _____   _
  | | '_ \ / _ \_  / | | |
  | | |_) |  __// /| |_| |
 _/ | .__/ \___/___|\__, |
|__/|_|             |___/       by roki

process started...
     Loaded JPEG: 512x512, presicion 8, "Encoded by jpezy", JFIF standart 1.02, dots inch, frames 3, density 96x96

Done! Processing time: 0.055(sec)
Decoded image: Netpbm image data, size = 512 x 512, pixmap, ASCII text
$ file output.ppm
output.ppm: Netpbm image data, size = 512 x 512, pixmap, ASCII text
$ ./jpezy_decode lena.jpg output.ppm -v
   _
  (_)_ __   ___ _____   _
  | | '_ \ / _ \_  / | | |
  | | |_) |  __// /| |_| |
 _/ | .__/ \___/___|\__, |
|__/|_|             |___/       by roki

process started...
     analyzing header...
             found marker: [APP0]
                     analyzing jfif... Done! Processing time: 0(sec)
             found marker: [COM]
             found marker: [DQT]
                     analyzing DQT... Done! Processing time: 0(sec)
             found marker: [DQT]
                     analyzing DQT... Done! Processing time: 0(sec)
             found marker: [DHT]
                     analyzing DHT...  size: 12
found DC Huffman Table...                       Done! Processing time: 0(sec)
             found marker: [DHT]
                     analyzing DHT...  size: 12
found DC Huffman Table...                       Done! Processing time: 0(sec)
             found marker: [DHT]
                     analyzing DHT...  size: 162
found AC Huffman Table...                       Done! Processing time: 0(sec)
             found marker: [DHT]
                     analyzing DHT...  size: 162
found AC Huffman Table...                       Done! Processing time: 0(sec)
             found marker: [SOF0]
                     analyzing frames... VSize: 512 HSize: 512 Done! Processing time: 0(sec)
             found marker: [SOS]
                     analyzing scan data... Done! Processing time: 0(sec)
     Done! Processing time: 0(sec)
     Loaded JPEG: 512x512, presicion 8, "Encoded by jpezy", JFIF standart 1.02, dots inch, frames 3, density 96x96

     decoding started...     Done! Processing time: 0.052(sec)
Done! Processing time: 0.052(sec)
Decoded image: Netpbm image data, size = 512 x 512, pixmap, ASCII text

Build

$ git clone https://github.com/falgon/jpezy.git
$ cd jpezy
$ mkdir build && cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make -j$(nproc)

or with Ninja

$ git clone https://github.com/falgon/jpezy.git
$ cd jpezy
$ mkdir build && cd build
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
$ ninja

Usage

Encoder

Usage: jpezy_encoder <input.ppm> ( <ouput.(jpeg | jpg) [OPT: --gray]> | <output.ppm> | --debug )
  • input.ppm: Input ppm image file
  • output.(jpeg | jpg) [OPT: --gray]: Output jpeg or jpg image. When you designate the --gray option, the image is output in gray scale.
  • output.ppm: When you designate ppm, the image is output ppm without doing anything.
  • --debug: When you designate this option, the image is not output, and ppm data are just output on standard output.

Decoder

Usage: jpezy_decoder <input.(jpg | jpeg)> ( <output.ppm | [OPT: --gray]> | -v )
  • input.(jpg | jpeg): Input JPEG image file
  • output.ppm: Output ppm image file
  • --gray: Image is output in gray scale.
  • -v: Verbose mode.

The examples using decoder as a library are as follows.

#include"jpezy_decoder.hpp"
#include"decode_io.hpp"

int main()
{
    jpezy::decoder<jpezy::Release> dec("input.jpg"); // appoint the input JPEG image file
    const auto raw = dec.decode<jpezy::COLOR_MODE>(); // Decoding and returning rgb raw data. This value wrapped optional.

    if (!raw) return EXIT_FAILURE;
    const auto& [r, g, b] = raw.value(); // getting rgb data by structure bindings. 

    std::ofstream ofs("output.ppm"); // appoint the output PPM image file.
    jpezy::decode_io decio(dec.pr.get<jpezy::property::At::HSize>(), dec.pr.get<jpezy::property::At::VSize>(), r, g, b); // passing data to helper that jpezy::decode_io
    ofs << decio; // Outputing the PPM file.
}

Reference

License

MIT License

About

🖼 Full scratch simple JPEG encoder + decoder implementation.

Resources

License

Stars

Watchers

Forks