• Stars
    star
    399
  • Rank 108,092 (Top 3 %)
  • Language
    C
  • License
    Apache License 2.0
  • Created over 4 years ago
  • Updated 2 months ago

Reviews

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

Repository Details

An optimized JPEG decoder suitable for microcontrollers and PCs.

JPEGDEC

Copyright (c) 2020 BitBank Software, Inc.
Written by Larry Bank
[email protected]

I optimize other people's code for a living. This library is a good example of the kind of work I do for my commercial clients; it contains many unique and clever optimizations that allows it to perform better than anything else available. I'm happy to contribute optimized libraries to the open source community in addition to working on commercial projects. Whatever platform you're using, I can make significant improvements to your native code. Please contact me so that I can show you how.

JPEGDEC
I started working with image and video files around 1989 and soon turned my interest into a Document Imaging product based on my own imaging library. Over the years I added support for more and more formats until I had supported all of the standard ones, including DICOM. I sold my Document Imaging business in 1997. I started over with a new library design in 2000 and added even more formats. Over the years, I found uses for my imaging code in projects such as retro gaming. I recently went looking to see if there was a good JPEG viewer for Arduino and only found ones which sacrificed speed to work on MCUs with almost no RAM. I thought it would be possible to create an optimized JPEG decoder that could run on any MCU with at least 20K of RAM, so I started modifying my old JPEG code for this purpose. There are a lot of clever optimizations contained in the code that I kept as trade secrets for many years. I decided that it's time to share the code with the community. This code doesn't look like other JPEG libraries because I wrote it from a "blank sheet". It took many hundreds of hours of work to get it working correctly and find all of the optimizations. If you appreciate my work, please consider sponsoring me.


Features:
---------

  • Supports any MCU with at least 20K of RAM (Cortex-M0+ is the simplest I've tested)
  • Optimized for speed; the main limitation will be how fast you can copy the pixels to the display. You can use DMA assisted SPI to help.
  • JPEG image data can come from memory (FLASH/RAM), SDCard or any media you provide.
  • Simple class and callback design allows you to easily add JPEG support to any application.
  • The C code doing the heavy lifting is completely portable and has no external dependencies.
  • Includes fast downscaling options (1/2, 1/4, 1/8).
  • Includes option to detect and decode the embedded Exif thumbnail
  • Supports Baseline Huffman images (grayscale or YCbCr)
  • Includes optional Floyd-Steinberg dithering to 1, 2 or 4-bpp grayscale output; useful for e-paper displays


A note about performance
The chart above gives you an idea of how the code performs on various MCUs with the different scaling options. The test image used is both large in dimension and large in terms of the compressed data size. The two factors that have the most influence on performance are the compressed data size and the output scaling options. This is because the time to decode JPEG data scales mostly linearly with the amount of data to decode. To get the fastest decode speed, choose the lowest acceptable quality for your image; this will produce the smallest compressed data size. When you must use an image that is too large, the scaling options allow you to display it at a lower resolution than the original.



Floyd-Steinberg dithering
I added the option to dither the output to 1, 2 or 4-bit per pixel grayscale using the FS error diffusion algorithm. It creates a pleasant output without visible blocking nor repeating patterns. This seemed useful for generating output suitable for high resolution e-paper displays. The image above was decoded from a 800x600 color JPEG and rendered as 2-bits per pixels (4 gray levels) on a 400x300 4.2" e-paper display. See the Wiki for info on how to use this option.

Acquiring JPEG files to play:

You'll notice that the images provided in the test_images folder have been turned into C code. Each byte is now in the form 0xAB so that it can be compiled into your program and stored in FLASH memory alongside your other code. You can use a command line tool I wrote called image_to_c (https://github.com/bitbank2/image_to_c) or an older Linux tool called xxd to convert a binary file into this type of text. Make sure to add a const/PROGMEM modifier in front of the JPEG data array to ensure that it gets written to FLASH and not RAM by your build environment.

The Callback functions:

One of the ways to allow this code to run on any embedded platform was to define a set of callback functions. These isolate the JPEG decoding logic from the display and file I/O. This allows the core code to run on any system, but you need to help it a little. At a minimum, your code must provide a function to draw (or store) each block of image pixels emitted by the library. If you're displaying a JPEG file from memory (RAM or FLASH), this is the only function you need to provide. In the examples folder there are multiple sketches to show how this is done on various display libraries. For reading from SD cards, 4 other functions must be provided: open, close, read, seek. There is an example for implementing these in the examples folder as well. Note: If you're using the ESP32 or ESP8266 (or another MCU which uses the Harvard Architecture) and decoding JPEG images stored in RAM or FLASH, you'll need to use the correct open function (openRAM or openFLASH). For MCUs based on the ARM Cortex-M, they are interchangeable.

The API:

Please consult the Wiki for detailed info about each method exposed by the JPEGDEC class.

If you find this code useful, please consider becoming a sponsor or sending a donation.

paypal

More Repositories

1

Thermal_Printer

Arduino library to draw text and graphics on BLE thermal printers
C
373
star
2

AnimatedGIF

An optimized GIF decoder suitable for microcontrollers and PCs
C
363
star
3

BitBang_I2C

A software I2C implementation to run on any GPIO pins on any system
C++
240
star
4

image_to_c

Convert image files into C arrays of uint8_t for compiling into your project
C
198
star
5

OneBitDisplay

A full featured Arduino display library for 1-bit per pixel OLED, LCD and e-paper displays
C
195
star
6

ss_oled

Simple and small library to control 1-bpp OLED displays (Linux + Arduino)
C++
188
star
7

PNGdec

An optimized PNG decoder suitable for microcontrollers and PCs
C
180
star
8

SPI_LCD

A simple C library for directly communicating with SPI-connected LCD displays
C
112
star
9

bb_spi_lcd

SPI LCD/OLED library which can be built for Arduino and Linux
C++
91
star
10

SmartResponseXE

Arduino library with LCD, Keyboard and SPI Flash support for the SMART Response XE classroom communicator
C++
89
star
11

SLIC

Simple lossless imaging codec
C++
80
star
12

oled_96

A simple C library (Linux + Arduino) for drawing text and graphics on SSD1306/SH1106 OLED displays
C
79
star
13

ArmbianIO

A C (+ Python and Java) library for simplifying access to I2C, SPI and GPIO on boards supported by Armbian
C
78
star
14

Multi_OLED

Control multiple OLED displays on one or more I2C buses simultaneously
C++
76
star
15

Print2BLE

MacOS app which allows drag and drop of images to BLE thermal printers
Objective-C
72
star
16

CYD_Projects

A collection of Arduino sketches for the "Cheap Yellow Display" board(s)
C
58
star
17

JPEGENC

Arduino JPEG encoder
C++
55
star
18

VL53L0X

A simple C library to read the distance values from the VL53L0X time of flight sensor
C
54
star
19

unzipLIB

An embedded-friendly library for decompressing files from zip archives
C
51
star
20

oled_turbo

An experiment to push the limits of the SSD1306 through bit banging on Arduinos
C++
45
star
21

PNGenc

An embedded-friendly PNG encoder
C
39
star
22

Multi_BitBang

A software I2C implementation to create multiple I2C buses using GPIO lines
C++
38
star
23

giflib-turbo

A faster drop-in replacement for giflib. It uses more RAM, but you get more speed.
C
37
star
24

SMART_bootloader

Send sketches wirelessly from the Arduino IDE to your SMART Response XE
C
35
star
25

BB-CP

A faster replacement for FBTFT + FBCP
C
31
star
26

LCD1602

A C library (Linux + Arduino) to control 2 line x 16 character I2C LCD displays
C
28
star
27

ssd1327

SSD1327 and SSD1322 OLED display library for Arduino+Linux
C++
26
star
28

oled_animator

C code for converting animated GIF images into a form to run on MCUs and SSD1306 OLED displays
C
26
star
29

Pocket_CO2

A CH32V003 low cost pocket CO2 sensor
C
24
star
30

BLE_Keyboard

An HID keyboard sketch for the Arduino Nano 33 BLE
C++
23
star
31

TIFF_G4

A set of highly optimized functions for decoding and displaying 1-bpp CCITT G4 images
C
22
star
32

I2C_Detector

Scan I2C buses and identify devices which respond.
C++
22
star
33

MAX7219

A C library for controlling any number of Maxim LED matrix controllers
C
21
star
34

bb_captouch

An ESP32/Arduino library to talk to CST820, FT6x36 and GT911 capacitive touch sensors (auto-detects)
C++
21
star
35

Pi_Pico_C_Projects

A collection of C code for the Raspberry Pi Pico
C
20
star
36

uc1701

A C library (Linux + Arduino) to control the UC1701/ST7565/ST7920 128x64 monochrome LCD
C
20
star
37

sg_free

The open source version of SmartGear - a multi-system game emulator
C
19
star
38

epd_image

Prepare image data for writing directly to e-paper displays
C++
18
star
39

bbgfx

BitBank Graphics Library - optimized primitives for RGB565 surfaces on ARMv5
C
17
star
40

Nano_33_Gamepad

A sketch to connect BLE HID gamepads to the Arduino Nano 33 BLE
C++
15
star
41

sense_hat_unchained

A C library to work with the Sense Hat on non-RPI hardware
C
15
star
42

tm1637

A C library for controlling Titan Micro Electronic's 7-segment LED controller
C
13
star
43

esp32_gamepad

Arduino library to connect a SteelSeries:Free gamepad to your ESP32 microcontroller
C++
13
star
44

BLE_2_EPaper

A collection of projects to send images over BLE to e-paper displays
C
12
star
45

KiCad_Projects

A place to share all of my PCB projects
12
star
46

gcc_perf

Test ARM/X86 C/SIMD/ASM perf on 32-bit and 64-bit Linux to see machine/compiler differences
C
12
star
47

bb_truetype

An incomplete, but fast + useful truetype font renderer for embedded devices
C++
11
star
48

Animated_Sand

Arduino demo for SSD1306 I2C display + MPU-6050 accelerometer.
C++
11
star
49

G4Enc

Optimized CCITT G4 encoder for embedded and larger systems
C++
10
star
50

FastIO

A fast substitute for Arduino digital pin functions on AVR MCUs
C++
10
star
51

bin_to_c

A simple Linux command line tool for turning binary files into C source code (array of unsigned chars)
C
9
star
52

gif_play

Play animated GIF images directly on a Linux framebuffer or SPI LCD
C
9
star
53

ESP_NOW_Weather

An e-paper weather project which uses a client/server approach to save battery life
C
9
star
54

bb_epaper

A frustration-free library for working with all 24-pin eink panels
C
8
star
55

NeoPixel

A simple NeoPixel (WS2812B) sketch for generating long light patterns with low RAM usage
C++
8
star
56

TwoBitDisplay

An Arduino library to control 2-bit (4 gray level) LCD displays
C++
8
star
57

RemoteDisplay

An Arduino library to control local or remote (BLE/I2C/UART/WiFi) displays with optional button input
C++
8
star
58

CH32V_Experiments

A place to share code and projects related to the WCH CH32V RISC-V processors
C
8
star
59

CCS811

A simple C library for working with the CCS811 air quality sensor
C
8
star
60

ESLImageTransfer

An Android native app to transfer images to the hacked ESLs
Java
7
star
61

gnu_asm

A C command line tool to convert Microsoft ASM files to GAS (GNU assembler) format
C
7
star
62

hx1230

A C library (Linux + Arduino) to control hx1230 monochrome LCDs
C++
7
star
63

bme280

A simple C library (Linux + Arduino) to read the calibrated temperature/pressure/humidity values from a Bosch BME280 I2C sensor
C
6
star
64

CH32V003_Sensor_Platform

Firmware for a small PCB with LCD which allows easy plug-n-play field-testing of some I2C sensors
C
6
star
65

zlib_turbo

Optimized zlib inflate (+gzip) library for embedded
C++
6
star
66

SmartGear_ESP32

multi-game emulator for the ESP32
C++
5
star
67

ir_receiver

C code to receive NEC codes from a GPIO connected to a IR demodulator
C
5
star
68

LED_Clock

A low cost PCB project (w/firmware) for a dark-room-friendly digital clock
C
5
star
69

CH32V_Color_LCD

A set of functions to control Sitronix color LCDs on CH32V RISC-V MCUs
C
5
star
70

rtc_eeprom

C code to talk to the DS3231 and AT24C32 (usually sold together)
C++
5
star
71

zeemouse

Use 'undocumented' bluetooth game controllers to control your mouse and/or generate keypresses from buttons and stick movements
C
5
star
72

bb_uc1701

Arduino ST7565/UC1701 128x64 LCD display library
C++
5
star
73

CO2_USB_033

A portable CO2 monitor based on the CH32X033 MCU
C
5
star
74

W600FastIO

Optimized GPIO pin functions for the WinnerMicro W600 SoC
C++
4
star
75

arduinoVNC

A VNC client for Arduino
C++
4
star
76

max44009

A simple C library to initialize and read the ambient light value
C
3
star
77

bb_rtc

An Arduino RealTime Clock library which auto-detects DS3231, RV-3032 and PCF8563
C++
3
star
78

oled_sprites

A sprite and tile system for the ATtiny85 & SSD1306 (or more powerful MCU)
C++
3
star
79

imageinfo

A lightweight (aka fast) tool for identifying and displaying the relevant info for image files.
C
3
star
80

accelerometers

A C library to read the accelerometer and gyroscope values from a collection of popular sensors
C
3
star
81

nokia5110

A simple C library (Linux + Arduino) to talk to Nokia 5110 LCD displays
C
3
star
82

nrf24_test_rig

An Arduino sketch for nRF24 range testing using a Pro Mini, 64x32 OLED and 2 buttons
C++
3
star
83

Nano_33_BeetleC

Control the M5Stack Beetle-C car over BLE with an Arduino Nano 33 BLE
C++
3
star
84

weather_mon

A sample weather monitoring program which records the output to a CSV file
C
3
star
85

galactic_unicorn_test

A simple Arduino project to display time + temp + humidity + CO2
C++
3
star
86

rtc_setter

An Arduino sketch to set the local time (corrected for DST) to your DS3231 RTC
C++
3
star
87

bb_hx1230

Arduino library to control HX1230 / STE2007 96x68 LCD displays
C++
3
star
88

FT6236G

An Arduino library for FocalTech FT6x36 capacitive touch controllers
C++
3
star
89

ISBIC

Incredibly Simple Bitonal Image Compression
C
3
star
90

Fusion_360_Projects

A place to share 3D projects
3
star
91

bb_temperature

A multi-device temperature/humidity/pressure sensor library with auto-detection.
C++
3
star
92

bb_scd41

Sensiron SCD4x Arduino library
C++
2
star
93

framebuffer

Experiments with using the Linux framebuffer directly (mostly on Raspberry Pi)
C
2
star
94

min_search_arm

Arm NEON demo to search an unsorted list of integers for the minimum value
C
2
star
95

NXP_Test

Experimental code for the OKDO E1 (NXP LPC55S69)
C
2
star
96

bb_ltr390

visible/UV light sensor Arduino library
C++
2
star
97

armbian_oled

A C library for SSD1306 displays (I2C+SPI) which uses my ArmbianIO library
C
2
star
98

pi_car

A bluetooth gamepad controlled 4wd car with a Rasberry Pi Zero as its brain
C
1
star
99

oled_example

Sample code to talk to a SSD1306 OLED display utilizing my oled_96 library
C
1
star
100

bb-hole

A DNS black hole for filtering out ads/dangerous sites
C
1
star