• Stars
    star
    210
  • Rank 187,585 (Top 4 %)
  • Language
    C
  • Created over 9 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

C++ JPEG compression/fuzzed low-RAM JPEG decompression codec with Public Domain or Apache 2.0 license

jpeg-compressor

A small (~1000 lines), easy to use public domain (or Apache 2.0) C++ class in a single source file jpge.cpp that writes baseline JPEG compressed images. It supports grayscale and H1V1/H2V1/H2V2 chroma subsampling factors, Libjpeg-compatible quality settings, and is reasonably fast with fairly low (typically less than 64KB) memory consumption. The core compression class consists of a single 890 line C++ file with a small header, along with a couple optional higher-level helper/example functions. The current release supports both single pass Huffman coding and more efficient (but slower) two pass coding, makes only a single dynamic memory allocation, and now accepts 32-bit source images.

The source distribution also includes an optional, completely stand-alone public domain (or Apache 2.0) JPEG decompression class with progressive image support in a single source file jpgd.cpp. It supports both box and linear chroma upsampling, and grayscale or H1V1/H2V1/H1V2/H2V2 chroma upsampling factors. Unlike every other small JPEG decompressor I've seen, this decompressor has been fuzz tested using zzuf and afl, making it resilent against crashing, overwriting memory, or bad memory reads when given accidently or purposely corrupted inputs. Also unlike many other small JPEG decompressors, jpgd.cpp does not require loading the entire image into memory, just single MCU rows at a time (even when doing linear chroma upsampling). This property makes the decompressor useful on small 32-bit microcontrollers.

The source distribution includes a sample VS2019 Win32/x64 solution and CMakeLists.txt file for compilation with gcc/clang.

Thanks to Alex Evans for adding several features to jpge (see a smaller jpg encoder).

Basic Usage (Compression)

Include jpge.h and call one of these helper functions in the "jpge" namespace:

// Writes JPEG image to a file. 
// num_channels must be 1 (Y), 3 (RGB), or 4 (RGBA), image pitch must be width*num_channels.
bool compress_image_to_jpeg_file(const char *pFilename, int width, int height, int num_channels, 
                                 const uint8 *pImage_data, const params &comp_params = params());

// Writes JPEG image to memory buffer. 
// On entry, buf_size is the size of the output buffer pointed at by pBuf, which should be at least ~1024 bytes. 
// If return value is true, buf_size will be set to the size of the compressed data.
bool compress_image_to_jpeg_file_in_memory(void *pBuf, int &buf_size, int width, int height, int num_channels, 
                                           const uint8 *pImage_data, const params &comp_params = params());

See tga2jpg.cpp for an example usage. This example uses Sean Barrett's stb_image.c module to load image files.

You can also call the jpge::jpeg_encoder class directly if you need more control over the image source or how/where the output stream is written.

Basic Usage (Decompression)

Include jpgd.h and call one of these helper functions in the "jpgd" namespace:

// Loads a JPEG image from a memory buffer.
// req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
// On return, width/height will be set to the image's dimensions, and actual_comps will be set 
// to either 1 (grayscale) or 3 (RGB).
unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, 
                                     int *width, int *height, int *actual_comps, int req_comps, uint32_t flags = 0);

// Loads a JPEG image from a file.
unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, 
                                     int *actual_comps, int req_comps, uint32_t flags = 0);

Just like the compressor, for more control you can directly utilize the jpgd::jpeg_decompressor class, or call the decompress_jpeg_image_from_stream() function.

The optional flags are:

cFlagBoxChromaFiltering: Uses much faster box filtering on the chroma components, but may lead to artifacts on some images

cFlagDisableSIMD: Do not use SSE2, even if it's been compiled in

Set the "JPGD_USE_SSE2" macro to 0 to completely disable SSE2 usage during compilation. By default, it's enabled (unless it's x86/x64 gcc and SSE2 is not defined).

jpgd supports a superset of JPEG features utilized by jpge, so it can decompress any file generated by jpge along with most (if not almost all) JPEG files you're likely to encounter in the wild. It supports progressive and baseline sequential JPEG image files and the H1V1, H2V1, H1V2, and H2V2 chroma subsampling factors.

Testing

The source distribution includes a simple example command line tool called "jpge.exe" (or jpge_x64.exe for Win64 systems) that converts images from any format that stb_image.c supports (such as PNG, TGA, BMP, etc.) to baseline JPEG using the jpeg_encoder class. Its usage is: bin/jpge source_file.png destination_file.jpg quality_factor Where quality_factor ranges from 1-100 (higher is better).

jpge.exe also includes a few other modes for exhaustive testing of the codec (-x option) and JPEG to TGA decompression (-d option) -- see the help text for more info.

Licenses

The license of jpgd.cpp/.h and jpge.cpp/.h is either Public Domain or Apache 2.0. Choose whatever you want.

The license for the optional file jpgd_idct.h (and ONLY this file) is Copyright 2009 Intel Corporation:

Permission is granted to use, copy, distribute and prepare derivative works of this software for any purpose and without fee, provided, that the above copyright notice and this statement appear in all copies. Intel makes no representations about the suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS." INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not assume any responsibility for any errors which may appear in this software nor any responsibility to update it.

(Set JPGD_USE_SSE2 to 0 to completely disable usage of jpgd_idct.h.)

Revisions

  • March 25, 2020 - Upgraded jpgd.cpp to latest version (fuzzed, linear chroma upsampling), added CMakeLists.txt, tested with clang/gcc under Linux, upgraded stb_image.h/stb_image_read.h to latest versions.
  • v1.04, May 20, 2012 - Fixed double fclose() bug in cfile_stream::close() reported by Owen Kaluza. (m_pFile should have been set to NULL here. Crap.) Also put jpge.cpp and jpgd.cpp through MSVC 2008's static code analysis and fixed every warning. They where all harmless things, but it's the right thing to do.
  • v1.03, Apr. 16, 2011 - Added jpgd.cpp/.h (derived from my older http://code.google.com/p/jpgd/ project), integrated changes from Alex Evans, added support for two pass compression, added more modes/options and timer to example command line app, lots of testing.
  • v1.02, Apr. 6, 2011 - Removed 2x2 ordered dither in the H2V1 chroma subsampling method jpeg_encoder::load_block_16_8_8(). (This was a last minute addition and there was actually a typo here - the dither rounding factor was 2 when it should have been 1. It turns out that chroma subsample dithering in the H2V1 case typically lowers PSNR even with the intended rounding factor, unlike H2V2.)
  • v1.01, Dec. 18, 2010 - Initial stable release

History

This codec was originally written in C and 16-bit x86 asm way back in 1994 for a DOS image viewer. The primary reference was Pennebaker's and Mitchell's book JPEG: Still Image Data Compression Standard. The original version supported a simple form of adaptive quantization, used a quantized DCT, and two pass Huffman coding. Around 2000 I ported it to C++, but I didn't really have the time to release it until now.

Note if you're generating texture mipmaps from loaded images, you may be interested in my imageresampler project.

For any questions or problems with this code please contact Rich Geldreich at . Here's my twitter page.

More Repositories

1

miniz

miniz: Single C source file zlib-replacement library, originally from code.google.com/p/miniz
C++
2,104
star
2

fpng

Super fast C++ .PNG writer/reader
C
877
star
3

lzham_codec

Lossless data compression codec with LZMA-like ratios but 1.5x-8x faster decompression speed, C/C++
C++
690
star
4

bc7enc

Single source file BC1-5 and BC7 encoders and BC1-5/7 decoders with MIT or Public Domain licenses
C++
207
star
5

bc7enc_rdo

State of the art RDO BC1-7 GPU texture encoders
C++
180
star
6

uap_resources

Key OSINT UAP Related Materials
155
star
7

bc7enc16

Fast single source file BC7/BPTC texture encoder with perceptual metric support
C++
150
star
8

crunch

Advanced DXTc texture compression library
141
star
9

CppSPMD_Fast

Optimized CppSPMD test project: macro control flow, SSE4.1/AVX1/AVX2/AVX2 FMA support
C++
113
star
10

ufo_data

The Dataset of the Damned, and UFO/UAP event chronology creation tool
HTML
86
star
11

rdopng

Rate-Distortion Optimized Lossy PNG/QOI Encoding Tool
C++
80
star
12

picojpeg

picojpeg: Tiny JPEG decoder for 8/16-bit microcontrollers
C
75
star
13

lzham_codec_devel

LZHAM codec - unstable/experimental repo. Much faster compression and higher ratios in extreme mode. This is well tested but isn't the official version just yet, see lzham_codec instead. Still 100% backwards compatible with lzham v1.0.
C++
68
star
14

astc_dec

Single source file LDR ASTC texture decompression in C++ (derived from Google's open source Android project)
C++
42
star
15

triglib

Public Domain double precision trigonometry functions in C
C
39
star
16

simple_opencl

Simple C++ sample showing how to use OpenCL v1.2 on Windows/Linux/OSX with no 3rd party SDK installs
C
33
star
17

rg-etc1

Automatically exported from code.google.com/p/rg-etc1
C++
32
star
18

FastAC

FastAC - Amir Said's Arithmetic and Huffman coding library, example code, and documentation
C++
28
star
19

fasthf

Amir Said's C++ fast Huffman coding example (FastHF)
C++
25
star
20

sserangecoding

Fast vectorized (SSE 4.1) range coder for 8-bit alphabets
C++
23
star
21

imageresampler

Automatically exported from code.google.com/p/imageresampler
C
22
star
22

FloatMath

C++
17
star
23

fxdis-d3d1x

Automatically exported from code.google.com/p/fxdis-d3d1x
C++
15
star
24

dr_shirley_wright

Public record evidence showing the accomplishments of Dr. Shirley Jean Wright PhD
8
star
25

ufo_glasnost

English Translation of Col. Dr. Marina Popowitsch's book "UFO Glasnost"
8
star
26

shufrand

SSE 4.1 vectorized pseudorandom number generator (PCG variant)
C++
7
star
27

cpng

Compatible Network Graphics (CPNG) SDR/HDR Image Format Specification
7
star
28

random_pngs

A collection of random PNG test files
7
star
29

bc7enc_rdo_devel

C++
7
star
30

QBMOD

An Amiga MOD player written in QuickBASIC 4.5/PDS 7.1
VBA
7
star
31

ufo_data_search

ufo-search's client side search engine source code
C
5
star
32

png16

test repo
C++
4
star
33

lzham_alpha

This is LZHAM Alpha8, now supplanted by LZHAM 1.x here: https://github.com/richgel999/lzham_codec
C++
3
star
34

tga_test_files

A collection of .tga image format files in various formats (some obscure), for testing new decoders/readers
3
star
35

frank_scully

Scanned documents from the Frank Scully papers at the American Heritage Center
3
star
36

june_crain_files

Wright-Patterson AFB worker June Crain's official scanned personnel documents
2
star
37

junkdrawer

nothing special
1
star