JPEG (Joint Photographic Experts Group) is a widely used lossy compression standard,
developed by the Joint Photographic Experts Group, and has become an internationally
recognized standard for image compression. JPEG is not only applicable for static
image encoding but has also been extended for intra-frame compression in television
image sequences. The JPEG standard supported by JPU hardware is the Baseline Sequential
mode of ISO/IEC 10918-1.
JPEG decoding, realize the decoding of .jpg, .jpeg, .JPG, .JPEG image files.
Schematic Image
The main process of JPEG encoding is described by taking an 8x8 subregion of an image as an example.The values of the 8x8 image subregion are shown as belows:
A two-dimensional Discrete Cosine Transform (DCT) is first performed on the 8x8 subregion with the aim of transforming the YUV color space into the frequency domain space.
Since the range of values accepted for discrete cosine variation is [-128, 127], the following matrix is obtained by subtracting -128 from the values of the 8x8 image sub-region:
The coefficients at the points (0, 0) are called the direct current components (DC coefficients) and the coefficients at the remaining 63 points are called the alternating current components (AC coefficients).
Next, the DCT coefficients of the luminance and chrominance components are quantized, i.e., the DCT coefficients are divided by the quantization table and rounded to the nearest integer.
Since the human eye is more sensitive to luminance signals than to chromaticity signals, two quantization scales, for the luminance component and the chromaticity component, are used.
The default quantization tables are derived from extensive experiments, and custom quantization tables are also available.
The default quantization table for the luminance component:
The quantized DCT coefficients can be obtained by dividing the DCT coefficient matrix obtained earlier with the luminance table of the default values and rounding up:
Observe that the quantized DCT coefficients of the quantized data are a bit larger relative to the AC coefficients and that the AC coefficients kind of contain a large number of zeros.
Therefore, using Z-shaped encoding allows you to concatenate a large number of zeros together to reduce the size after encoding.
The main idea is to organize the quantized DCT coefficients in a zigzag pattern starting from the first pixel in the upper left corner of the quantized DCT coefficients:
Schematic Image
Since the DC coefficients of the DCT coefficients after zigzag coding have large values and the DC coefficients of the neighboring 8x8 image regions do not vary much,
therefore, differential pulse coding technique is used to encode the difference of DC coefficients between neighboring image regions;
for characters with AC coefficients that are repeated and occur many times in a row, the stroke length coding is used.
Both encoding methods have intermediate formats that are intended to further minimize storage.
After obtaining the intermediate format of DC coefficients and the intermediate format of AC coefficients, entropy coding of both is required for further compression of image data.
Compression is achieved by encoding characters with a higher probability of occurrence with a smaller number of bits.
The JPEG basic system specifies the Huffman coding method.
Different Huffman coding tables are used for DC coefficient and AC coefficient for Huffman coding, and different Huffman coding tables are used for luminance and chrominance.
Therefore, 4 Huffman coding tables are needed to complete the entropy coding, and waiting until the specific Huffman coding is done efficiently by using table lookups.
However, there is no default Huffman table defined in the JPEG standard, so you are free to choose one according to the actual application.
It is also possible to use the Huffman table recommended by the JPEG standard, or to predefine a generic Huffman table.
It is also possible to compute the value of the Huffman table for a particular image by collecting its statistical features before compression coding.
// Include the header#include "hobot/hb_ucp.h"#include "hobot/vp/hb_vp.h"#include "hobot/vp/hb_vp_jpeg_codec.h"// init jpeg_buf, alloc memory for jpeg datahbUCPSysMem jpeg_mem;hbUCPMalloc(&jpeg_mem, jpeg_size, 0);hbVPArray jpeg_buf;jpeg_buf.phyAddr = jpeg_mem.phyAddr;jpeg_buf.virAddr = jpeg_mem.virAddr;jpeg_buf.memSize = jpeg_mem.memSize;jpeg_buf.size = jpeg_mem.memSize;jpeg_buf.capacity = jpeg_mem.memSize;// init image_bufhbVPImage image_buf{0};// create decoding context and the JPU internally alloc the output bufferhbVPJPEGContext dec_context{nullptr};hbVPCreateJPEGDecContext(&dec_context, outbuf_count, image_format);// init task handle and schedule paramhbUCPTaskHandle_t task_handle{nullptr};hbUCPSchedParam sched_param;HB_UCP_INITIALIZE_SCHED_PARAM(&sched_param);sched_param.backend = HB_UCP_JPU_CORE_0;sched_param.priority = 0;// create decoding taskhbVPJPEGDecode(&task_handle, &jpeg_buf, dec_context);// submit decoding taskhbUCPSubmitTask(task_handle, &sched_param);// wait for decoding task donehbUCPWaitTaskDone(task_handle, 0);// get decoded buffer from JPUhbVPGetJPEGDecOutputBuffer(&image_buf, task_handle);// process image data// release task handle and dequeue output buffer from JPU// since the dequeue output buffer process relies on the context,// you must call the hbUCPReleaseTask interface before calling the hbVPReleaseJPEGEncContext interfacehbUCPReleaseTask(task_handle);// release encoding context and the JPU internally release the output bufferhbVPReleaseJPEGDecContext(dec_context);// release memoryhbUCPFree(&jpeg_mem);