RA Flexible Software Package Documentation  Release v5.2.0

 
JPEG Codec (r_jpeg)

Functions

fsp_err_t R_JPEG_Open (jpeg_ctrl_t *const p_api_ctrl, jpeg_cfg_t const *const p_cfg)
 
fsp_err_t R_JPEG_OutputBufferSet (jpeg_ctrl_t *p_api_ctrl, void *p_output_buffer, uint32_t output_buffer_size)
 
fsp_err_t R_JPEG_InputBufferSet (jpeg_ctrl_t *const p_api_ctrl, void *p_data_buffer, uint32_t data_buffer_size)
 
fsp_err_t R_JPEG_DecodeLinesDecodedGet (jpeg_ctrl_t *p_api_ctrl, uint32_t *p_lines)
 
fsp_err_t R_JPEG_DecodeImageSubsampleSet (jpeg_ctrl_t *const p_api_ctrl, jpeg_decode_subsample_t horizontal_subsample, jpeg_decode_subsample_t vertical_subsample)
 
fsp_err_t R_JPEG_DecodeHorizontalStrideSet (jpeg_ctrl_t *p_api_ctrl, uint32_t horizontal_stride)
 
fsp_err_t R_JPEG_DecodeImageSizeGet (jpeg_ctrl_t *p_api_ctrl, uint16_t *p_horizontal_size, uint16_t *p_vertical_size)
 
fsp_err_t R_JPEG_DecodePixelFormatGet (jpeg_ctrl_t *p_api_ctrl, jpeg_color_space_t *p_color_space)
 
fsp_err_t R_JPEG_EncodeImageSizeSet (jpeg_ctrl_t *const p_api_ctrl, jpeg_encode_image_size_t *p_image_size)
 
fsp_err_t R_JPEG_ModeSet (jpeg_ctrl_t *const p_api_ctrl, jpeg_mode_t mode)
 
fsp_err_t R_JPEG_Close (jpeg_ctrl_t *p_api_ctrl)
 
fsp_err_t R_JPEG_StatusGet (jpeg_ctrl_t *p_api_ctrl, jpeg_status_t *p_status)
 

Detailed Description

Driver for the JPEG peripheral on RA MCUs. This module implements the JPEG Codec Interface.

Overview

The JPEG Codec is a hardware block providing accelerated JPEG image encode and decode functionality independent of the CPU. Images can optionally be partially processed facilitating streaming applications.

Features

The JPEG Codec provides a number of options useful in a variety of applications:

The specifications for the codec are as follows:

Feature Options
Decompression input formats Baseline JPEG Y'CbCr 4:4:4, 4:2:2, 4:2:0 and 4:1:1
Decompression output formats ARGB8888, RGB565
Compression input formats Raw Y'CbCr 4:2:2 only
Compression output formats Baseline JPEG Y'CbCr 4:2:2 only
Byte reordering Byte, halfword and/or word swapping on input and output
Interrupt sources Image size acquired, input/output data pause, decode complete, error
Compatible image sizes See Minimum Coded Unit (MCU) below

Configuration

Build Time Configurations for r_jpeg

The following build time configurations are defined in fsp_cfg/r_jpeg_cfg.h:

ConfigurationOptionsDefaultDescription
Parameter Checking
  • Default (BSP)
  • Enabled
  • Disabled
Default (BSP) If selected, code for parameter checking is included in the build.
Decode Support
  • Enabled
  • Disabled
Enabled If selected, code for decoding JPEG images is included in the build.
Encode Support
  • Enabled
  • Disabled
Disabled If selected, code for encoding JPEG images is included in the build.

Configurations for Graphics > JPEG Codec (r_jpeg)

This module can be added to the Stacks tab via New Stack > Graphics > JPEG Codec (r_jpeg).

ConfigurationOptionsDefaultDescription
General
NameName must be a valid C symbolg_jpeg0 Module name.
Default mode
  • Decode
  • Encode
Decode Set the mode to use when calling R_JPEG_Open. This parameter is only used when both Encode and Decode support are enabled.
Decode
Input byte orderMCU Specific OptionsSelect the byte order of the input data for decoding.
Output byte orderMCU Specific OptionsSelect the byte order of the output data for decoding.
Output color format
  • ARGB8888 (32-bit)
  • RGB565 (16-bit)
RGB565 (16-bit) Select the output pixel format for decode operations.
Output alpha (ARGB8888 only)Value must be an 8-bit integer (0-255)255 Specify the alpha value to apply to each output pixel when ARGB8888 format is chosen.
CallbackName must be a valid C symbolNULL If a callback function is provided it will be called from the interrupt service routine (ISR) each time a related IRQ triggers.
Encode
Horizontal resolutionValue cannot be greater than 65535 and must be a non-negative integer divisible by 16480 Horizontal resolution of the raw image (in pixels). This value can be configured at runtime via R_JPEG_ImageSizeSet.
Vertical resolutionValue cannot be greater than 65535 and must be a non-negative integer divisible by 8272 Vertical resolution of the raw image. This value can be configured at runtime via R_JPEG_ImageSizeSet.
Horizontal strideValue cannot be greater than 65535 and must be a non-negative integer480 Horizontal stride of the raw image buffer (in pixels). This value can be configured at runtime via R_JPEG_ImageSizeSet.
Input byte orderMCU Specific OptionsSelect the byte order of the input data for encoding.
Output byte orderMCU Specific OptionsSelect the byte order of the output data for encoding.
Reset intervalValue cannot be greater than 65535 and must be a non-negative integer512 Set the number of MCUs between RST markers. A value of 0 will disable DRI and RST marker output.
Quality factorValue must be between 1 and 100 and must be an integer50 Set the quality factor for encoding (1-100). Lower values produce smaller images at the cost of image quality.
CallbackName must be a valid C symbolNULL If a callback function is provided it will be called from the interrupt service routine (ISR) each time a related IRQ triggers.
Interrupts
Decode Process Interrupt PriorityMCU Specific OptionsSelect the decompression interrupt priority.
Data Transfer Interrupt PriorityMCU Specific OptionsSelect the data transfer interrupt priority.

Clock Configuration

The peripheral clock for this module is PCLKA. No clocks are provided by this module.

Pin Configuration

This module does not have any input or output pin connections.


Usage Notes

Overview

The JPEG Codec contains both decode and encode hardware. While these two functions are largely independent in configuration only one can be used at a time.

To switch from decode to encode mode (or vice versa) use R_JPEG_ModeSet while the JPEG Codec is idle.

Status

The status value (jpeg_status_t) provided by the callback and by R_JPEG_StatusGet is a bitfield that encompasses all potential status indication conditions. One or more statuses can be set simultaneously.

Decoding Process

JPEG decoding can be performed in several ways depending on the application:

The flowchart below illustrates the steps necessary to handle any decode operation. The statuses given in blue are part of jpeg_status_t with the JPEG_DECODE_STATUS prefix omitted.

decode_flowchart.svg
JPEG Decode Operational Flow

Encoding Process

As compared to decoding, encoding is fairly straightforward. The only option available is to stream input data if desired. The flowchart below details the steps needed to compress an image.

encode_flowchart.svg
JPEG Encode Operational Flow

Handling Failed Operations

If an encode or decode operation fails or times out while the codec is running, the peripheral must be reset before it is used again. To reset the JPEG Codec simply close and re-open the module by calling R_JPEG_Close followed by R_JPEG_Open.

Limitations

Developers should be aware of the following limitations when using the JPEG API.

Minimum Coded Unit (MCU)

The JPEG Codec can only correctly process images that are an even increment of minimum coded units (MCUs). In other words, depending on the format the width and height of an image to be encoded or decoded must be divisible by the following:

Format Horizontal Vertical
Y'CbCr 4:4:4 8 pixels 8 lines
Y'CbCr 4:2:2 16 pixels 8 lines
Y'CbCr 4:1:1 32 pixels 8 lines
Y'CbCr 4:2:0 16 pixels 16 lines
Note
Because encoding is limited to Y'CbCr 4:2:2, raw pixel input data must always be in whole increments of 16x8 pixels.

Encoding Input Format

The encoding unit only supports Y'CbCr 4:2:2 input. Raw RGB888 data can be converted to this format as follows:

y = (0.299000f * r) + (0.587000f * g) + (0.114000f * b);
cb = 128 - (0.168736f * r) - (0.331264f * g) + (0.500000f * b);
cr = 128 + (0.500000f * r) - (0.418688f * g) - (0.081312f * b);

While these equations are mathematically simple they do use the floating-point unit. To speed things up we can multiply the coefficients by 256 and divide the sum by 256...

y = ((76.5440f * r) + (150.272f * g) + (29.1840f * b)) / 256;
cb = 128 - ((43.1964f * r) - (84.8036f * g) + (128.000f * b)) / 256;
cr = 128 + ((128.000f * r) - (107.184f * g) - (20.8159f * b)) / 256;

...which allows the formulas to be calculated entirely with shifts and addition (coefficients rounded to the nearest integer):

y = ( (r << 6) + (r << 3) + (r << 2) + r
+ (g << 7) + (g << 4) + (g << 2) + (g << 1)
+ (b << 4) + (b << 3) + (b << 2) + b
) >> 8;
cb = 128 - ( (r << 5) + (r << 3) + (r << 1) + r
+ (g << 6) + (g << 4) + (g << 2) + g
- (b << 7)
) >> 8;
cr = 128 + ( (r << 7)
- (g << 6) - (g << 5) - (g << 3) - (g << 1) - g
- (b << 4) - (b << 2) - b)
) >> 8;

To compose the final Y'CbCr 4:2:2 data the chroma of every two pixels must be averaged. In addition, the JPEG Codec expects chrominance values to be in the range -127..127 instead of the standard 1..255.

cb = (uint8_t) ((int8_t) ((cb0 + cb1 + 1) >> 1) - 128);
cr = (uint8_t) ((int8_t) ((cr0 + cr1 + 1) >> 1) - 128);

Finally, the below equation composes two 4:2:2 output pixels at a time with standard byte order (JPEG_DATA_ORDER_NORMAL):

out = y0 + (cb << 8) + (y1 << 16) + (cr << 24);
Note
RGB565 pixels must be upscaled to RGB888 before using the above formulas. Refer to the below example on Y'CbCr Conversion for implementation details.

Examples

Basic Decode Example

This is a basic example showing the minimum code required to initialize the JPEG Codec and decode an image.

void jpeg_decode_basic (void)
{
fsp_err_t err;
/* Open JPEG Codec */
err = R_JPEG_Open(&g_jpeg_ctrl, &g_jpeg_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Set input buffer */
err = R_JPEG_InputBufferSet(&g_jpeg_ctrl, JPEG_PTR, JPEG_SIZE_BYTES);
assert(FSP_SUCCESS == err);
/* Set horizontal stride of output buffer */
err = R_JPEG_DecodeHorizontalStrideSet(&g_jpeg_ctrl, JPEG_HSIZE);
assert(FSP_SUCCESS == err);
/* Set output buffer */
err = R_JPEG_OutputBufferSet(&g_jpeg_ctrl, decode_buffer, sizeof(decode_buffer));
assert(FSP_SUCCESS == err);
/* Wait for decode completion */
{
err = R_JPEG_StatusGet(&g_jpeg_ctrl, &status);
assert(FSP_SUCCESS == err);
}
}

Streaming Input/Output Example

In this example JPEG data is read in 512-byte chunks. Decoding is paused when a chunk is read and once the JPEG header is decoded. The image is decoded 16 lines at a time.

Note
Streaming is always bypassed when a given buffer's size encompasses the entire input or output image, respectively. Though this example decodes via smaller chunks the input and output data are still contiguous for ease of demonstration. Refer to the comments for further insight as to how to implement streaming with different JPEG/output buffer size combinations.
#define JPEG_INPUT_SIZE_BYTES 512U
/* JPEG Codec status */
static volatile jpeg_status_t g_jpeg_status = JPEG_STATUS_NONE;
/* JPEG event flag */
static volatile uint8_t jpeg_event = 0;
/* Callback function for JPEG decode interrupts */
void jpeg_decode_callback (jpeg_callback_args_t * p_args)
{
/* Get JPEG Codec status */
g_jpeg_status = p_args->status;
/* Set JPEG flag */
jpeg_event = 1;
}
/* Simple wait that returns 1 if no event happened within the timeout period */
static uint8_t jpeg_event_wait (void)
{
uint32_t timeout_timer = JPEG_EVENT_TIMEOUT;
while (!jpeg_event && --timeout_timer)
{
/* Spin here until an event callback or timeout */
}
jpeg_event = 0;
return timeout_timer ? 0 : 1;
}
/* Decode a JPEG image to a buffer using streaming input and output */
void jpeg_decode_streaming (void)
{
uint8_t * p_jpeg = (uint8_t *) JPEG_PTR;
uint8_t timeout = 0;
fsp_err_t err;
/* Number of input bytes to read at a time */
uint32_t input_bytes = JPEG_INPUT_SIZE_BYTES;
/* Open JPEG unit and start decode */
err = R_JPEG_Open(&g_jpeg_ctrl, &g_jpeg_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
while (!(status & JPEG_STATUS_ERROR) && !timeout)
{
/* Set the input buffer to read `input_bytes` bytes at a time */
err = R_JPEG_InputBufferSet(&g_jpeg_ctrl, p_jpeg, input_bytes);
assert(FSP_SUCCESS == err);
/* This delay is required for streaming input mode to function correctly.
* (Without this delay the JPEG Codec will not correctly locate markers in the file header.) */
/* Wait for a callback */
timeout = jpeg_event_wait();
/* Get the status from the callback */
status = g_jpeg_status;
/* Break if the header has finished decoding */
{
break;
}
/* Move pointer to next block of input data (if needed) */
p_jpeg = (uint8_t *) ((uint32_t) p_jpeg + input_bytes);
}
/* Get image size */
uint16_t horizontal;
uint16_t vertical;
err = R_JPEG_DecodeImageSizeGet(&g_jpeg_ctrl, &horizontal, &vertical);
assert(FSP_SUCCESS == err);
/* Prepare output data buffer here if needed (already allocated in this example) */
uint8_t * p_output = decode_buffer;
/* Set horizontal stride */
err = R_JPEG_DecodeHorizontalStrideSet(&g_jpeg_ctrl, horizontal);
assert(FSP_SUCCESS == err);
/* Calculate the number of bytes that will fit in the buffer (16 lines in this example) */
uint32_t output_size = horizontal * 16U * 4U;
/* Start decoding by setting the output buffer */
err = R_JPEG_OutputBufferSet(&g_jpeg_ctrl, p_output, output_size);
assert(FSP_SUCCESS == err);
while (!(status & JPEG_STATUS_ERROR) && !timeout)
{
/* Wait for a callback */
timeout = jpeg_event_wait();
/* Get the status from the callback */
status = g_jpeg_status;
/* Break if decoding is complete */
{
break;
}
{
/* Draw the JPEG work buffer to the framebuffer here (if needed) */
/* Move pointer to next block of output data (if needed) */
p_output += output_size;
/* Set the output buffer to the next 16-line block */
err = R_JPEG_OutputBufferSet(&g_jpeg_ctrl, p_output, output_size);
assert(FSP_SUCCESS == err);
}
{
/* Get next block of input data */
p_jpeg = (uint8_t *) ((uint32_t) p_jpeg + input_bytes);
/* Set the new input buffer pointer */
err = R_JPEG_InputBufferSet(&g_jpeg_ctrl, p_jpeg, input_bytes);
assert(FSP_SUCCESS == err);
}
}
/* Close driver to allow encode operations if needed */
err = R_JPEG_Close(&g_jpeg_ctrl);
assert(FSP_SUCCESS == err);
}

Encode Example

This is a basic example showing the minimum code required to initialize the JPEG Codec and encode an image.

Note
This example assumes image dimensions are provided in the configuration. If this is not the case, R_JPEG_EncodeImageSizeSet must be used to set the size before calling R_JPEG_InputBufferSet.
void jpeg_encode_basic (void)
{
fsp_err_t err;
/* Open JPEG Codec */
err = R_JPEG_Open(&g_jpeg_ctrl, &g_jpeg_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Set output buffer */
err = R_JPEG_OutputBufferSet(&g_jpeg_ctrl, jpeg_buffer, sizeof(jpeg_buffer));
assert(FSP_SUCCESS == err);
/* Set input buffer */
err = R_JPEG_InputBufferSet(&g_jpeg_ctrl, RAW_YCBCR_IMAGE_PTR, IMAGE_SIZE_BYTES);
assert(FSP_SUCCESS == err);
/* Wait for decode completion */
while (!(status & JPEG_STATUS_OPERATION_COMPLETE))
{
err = R_JPEG_StatusGet(&g_jpeg_ctrl, &status);
assert(FSP_SUCCESS == err);
}
}

Streaming Encode Example

In this example the raw input data is provided in smaller chunks. This can help significantly reduce buffer size and improve throughput when streaming in raw data from an outside source.

/* Callback function for JPEG encode interrupts */
void jpeg_encode_callback (jpeg_callback_args_t * p_args)
{
/* Get JPEG Codec status */
g_jpeg_status = p_args->status;
/* Set JPEG flag */
jpeg_event = 1;
}
void jpeg_encode_streaming (void)
{
uint8_t timeout = 0;
uint8_t * p_chunk = (uint8_t *) RAW_YCBCR_IMAGE_PTR;
fsp_err_t err;
/* Open JPEG Codec */
err = R_JPEG_Open(&g_jpeg_ctrl, &g_jpeg_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Set output buffer */
err = R_JPEG_OutputBufferSet(&g_jpeg_ctrl, jpeg_buffer, sizeof(jpeg_buffer));
assert(FSP_SUCCESS == err);
/* Set the image size */
image_size.horizontal_resolution = X_RESOLUTION;
image_size.vertical_resolution = Y_RESOLUTION;
image_size.horizontal_stride_pixels = H_STRIDE;
err = R_JPEG_EncodeImageSizeSet(&g_jpeg_ctrl, &image_size);
assert(FSP_SUCCESS == err);
/* Calculate the size of the input data chunk (16 lines in this example) */
uint32_t chunk_size = H_STRIDE * 16U * YCBCR_BYTES_PER_PIXEL;
while (!timeout)
{
/* Set the input buffer */
err = R_JPEG_InputBufferSet(&g_jpeg_ctrl, p_chunk, chunk_size);
assert(FSP_SUCCESS == err);
/* Wait for a callback */
timeout = jpeg_event_wait();
if (g_jpeg_status & JPEG_STATUS_OPERATION_COMPLETE)
{
/* Encode complete */
break;
}
if (g_jpeg_status & JPEG_STATUS_INPUT_PAUSE)
{
/* Load next block of input data here (if needed) */
p_chunk += chunk_size;
}
}
}

Y'CbCr Conversion

The below function is provided as a reference for how to convert RGB values to Y'CbCr for use with the JPEG Codec.

Note
This function is only partially optimized for clarity. Further appllication-specific size- or speed-based optimizations should be considered when implementing in an actual project.
#define RGB565_G_MASK 0x07E0
#define RGB565_B_MASK 0x001F
#define C_0 128
typedef enum e_pixel_format
{
PIXEL_FORMAT_ARGB8888,
PIXEL_FORMAT_RGB565
} pixel_format_t;
/* 5-bit to 8-bit LUT */
const uint8_t lut_32[] =
{
0, 8, 16, 25, 33, 41, 49, 58,
66, 74, 82, 90, 99, 107, 115, 123,
132, 140, 148, 156, 165, 173, 181, 189,
197, 206, 214, 222, 230, 239, 247, 255
};
/* 6-bit to 8-bit LUT */
const uint8_t lut_64[] =
{
0, 4, 8, 12, 16, 20, 24, 28,
32, 36, 40, 45, 49, 53, 57, 61,
65, 69, 73, 77, 81, 85, 89, 93,
97, 101, 105, 109, 113, 117, 121, 125,
130, 134, 138, 142, 146, 150, 154, 158,
162, 166, 170, 174, 178, 182, 186, 190,
194, 198, 202, 206, 210, 215, 219, 223,
227, 231, 235, 239, 243, 247, 251, 255
};
void bitmap_rgb2ycbcr(uint32_t * out, uint8_t * in, uint32_t len, pixel_format_t format);
/***********************************************************************************************************************
* Convert an RGB buffer to Y'CbCr 4:2:2.
*
* NOTE: The width (in pixels) of the image to be converted must be divisible by 2.
*
* Parameters:
* out Pointer to output buffer
* in Pointer to input buffer
* len Length of input buffer (in pixels)
* format Input buffer format (ARGB8888 or RGB565)
**********************************************************************************************************************/
void bitmap_rgb2ycbcr (uint32_t * out, uint8_t * in, uint32_t len, pixel_format_t format)
{
uint16_t in0;
uint16_t in1;
uint32_t r0;
uint32_t g0;
uint32_t b0;
uint32_t r1;
uint32_t g1;
uint32_t b1;
uint8_t y0;
uint8_t y1;
uint8_t cb0;
uint8_t cr0;
uint8_t cb1;
uint8_t cr1;
/* Divide length by 2 as we're working with two pixels at a time */
len >>= 1;
/* Perform the conversion */
while (len)
{
/* Get R, G and B channel values */
if (format == PIXEL_FORMAT_RGB565)
{
/* Get next two 16-bit values */
in0 = *((uint16_t *) in);
in += 2;
in1 = *((uint16_t *) in);
in += 2;
/* Decompose into individual channels */
r0 = in0 >> 11;
g0 = (in0 & RGB565_G_MASK) >> 5;
b0 = in0 & RGB565_B_MASK;
r1 = in1 >> 11;
g1 = (in1 & RGB565_G_MASK) >> 5;
b1 = in1 & RGB565_B_MASK;
}
else
{
/* Get each ARGB8888 channel in sequence, skipping alpha */
b0 = *in++;
g0 = *in++;
r0 = *in++;
in++;
b1 = *in++;
g1 = *in++;
r1 = *in++;
in++;
}
/* Convert RGB565 data to RGB888 */
if (PIXEL_FORMAT_RGB565 == format)
{
r0 = lut_32[r0];
g0 = lut_64[g0];
b0 = lut_32[b0];
r1 = lut_32[r1];
g1 = lut_64[g1];
b1 = lut_32[b1];
}
/* Calculate Y'CbCr 4:4:4 values for the two pixels */
/* Algorithm based on method shown here: https://sistenix.com/rgb2ycbcr.html */
/* Original coefficients from https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion */
y0 = (uint8_t) (((r0 << 6) + (r0 << 3) + (r0 << 2) + r0 +
(g0 << 7) + (g0 << 4) + (g0 << 2) + (g0 << 1) +
(b0 << 4) + (b0 << 3) + (b0 << 2) + b0
) >> 8);
cb0 = (uint8_t) (C_0 - (((r0 << 5) + (r0 << 3) + (r0 << 1) + r0 +
(g0 << 6) + (g0 << 4) + (g0 << 2) + g0 -
(b0 << 7)
) >> 8));
cr0 = (uint8_t) (C_0 + (((r0 << 7) -
(g0 << 6) - (g0 << 5) - (g0 << 3) - (g0 << 1) - g0 -
(b0 << 4) - (b0 << 2) - b0
) >> 8));
y1 = (uint8_t) (((r1 << 6) + (r1 << 3) + (r1 << 2) + r1 +
(g1 << 7) + (g1 << 4) + (g1 << 2) + (g1 << 1) +
(b1 << 4) + (b1 << 3) + (b1 << 2) + b1
) >> 8);
cb1 = (uint8_t) (C_0 - (((r1 << 5) + (r1 << 3) + (r1 << 1) + r1 +
(g1 << 6) + (g1 << 4) + (g1 << 2) + g1 -
(b1 << 7)
) >> 8));
cr1 = (uint8_t) (C_0 + (((r1 << 7) -
(g1 << 6) - (g1 << 5) - (g1 << 3) - (g1 << 1) - g1 -
(b1 << 4) - (b1 << 2) - b1
) >> 8));
/* The above code is based on the floating point method shown here: */
// y0 = (uint8_t) ((0.299F * (float) r0) + (0.587F * (float) g0) + (0.114F * (float) b0));
// y1 = (uint8_t) ((0.299F * (float) r1) + (0.587F * (float) g1) + (0.114F * (float) b1));
// cb0 = (uint8_t) (128.0F - (0.168736F * (float) r0) - (0.331264F * (float) g0) + (0.5F * (float) b0));
// cb1 = (uint8_t) (128.0F - (0.168736F * (float) r1) - (0.331264F * (float) g1) + (0.5F * (float) b1));
// cr0 = (uint8_t) (128.0F + (0.5F * (float) r0) - (0.418688F * (float) g0) - (0.081312F * (float) b0));
// cr1 = (uint8_t) (128.0F + (0.5F * (float) r1) - (0.418688F * (float) g1) - (0.081312F * (float) b1));
/* NOTE: The JPEG Codec expects signed instead of unsigned chrominance values. */
/* Convert chrominance to -127..127 instead of 1..255 */
cb0 = (uint8_t) ((int8_t) ((cb0 + cb1 + 1) >> 1) - C_0);
cr0 = (uint8_t) ((int8_t) ((cr0 + cr1 + 1) >> 1) - C_0);
/* Convert the two 4:4:4 values into 4:2:2 by averaging the chroma, then write to output */
*out++ = (uint32_t) (y0 + (cb0 << 8) + (y1 << 16) + (cr0 << 24));
len--;
}
}

Data Structures

struct  jpeg_instance_ctrl_t
 

Data Structure Documentation

◆ jpeg_instance_ctrl_t

struct jpeg_instance_ctrl_t

JPEG Codec module control block. DO NOT INITIALIZE. Initialization occurs when jpep_api_t::open is called.

Data Fields
uint32_t open JPEG Codec driver status.
jpeg_status_t status JPEG Codec operational status.
fsp_err_t error_code JPEG Codec error code (if any).
jpeg_mode_t mode Current mode (decode or encode).
uint32_t horizontal_stride_bytes Horizontal Stride settings.
uint32_t output_buffer_size Output buffer size.
jpeg_cfg_t const * p_cfg JPEG Decode configuration struct.
void const * p_extend JPEG Codec hardware dependent configuration */.
jpeg_decode_pixel_format_t pixel_format Pixel format.
uint16_t total_lines_decoded Track the number of lines decoded so far.
jpeg_decode_subsample_t horizontal_subsample Horizontal sub-sample setting.
uint16_t lines_to_encode Number of lines to encode.
uint16_t vertical_resolution vertical size
uint16_t total_lines_encoded Number of lines encoded.

Function Documentation

◆ R_JPEG_Open()

fsp_err_t R_JPEG_Open ( jpeg_ctrl_t *const  p_api_ctrl,
jpeg_cfg_t const *const  p_cfg 
)

Initialize the JPEG Codec module.

Note
This function configures the JPEG Codec for operation and sets up the registers for data format and pixel format based on user-supplied configuration parameters. Interrupts are enabled to support callbacks.
Return values
FSP_SUCCESSJPEG Codec module is properly configured and is ready to take input data.
FSP_ERR_ALREADY_OPENJPEG Codec is already open.
FSP_ERR_ASSERTIONPointer to the control block or the configuration structure is NULL.
FSP_ERR_IRQ_BSP_DISABLEDJEDI interrupt does not have an IRQ number.
FSP_ERR_INVALID_ARGUMENT(Encode only) Quality factor, horizontal resolution and/or vertical resolution are invalid.
FSP_ERR_INVALID_ALIGNMENT(Encode only) The horizontal resolution (at 16bpp) is not divisible by 8 bytes.

◆ R_JPEG_OutputBufferSet()

fsp_err_t R_JPEG_OutputBufferSet ( jpeg_ctrl_t p_api_ctrl,
void *  p_output_buffer,
uint32_t  output_buffer_size 
)

Assign a buffer to the JPEG Codec for storing output data.

Note
In Decode mode, the number of image lines to be decoded depends on the size of the buffer and the horizontal stride settings. Once the output buffer size is known, the horizontal stride value is known, and the input pixel format is known (the input pixel format is obtained by the JPEG decoder from the JPEG headers), the driver automatically computes the number of lines that can be decoded into the output buffer. After these lines are decoded, the JPEG engine pauses and a callback function is triggered, so the application is able to provide the next buffer for the JPEG module to resume the operation.

The JPEG decoding operation automatically starts after both the input buffer and the output buffer are set and the output buffer is big enough to hold at least eight lines of decoded image data.

Return values
FSP_SUCCESSThe output buffer is properly assigned to JPEG codec device.
FSP_ERR_ASSERTIONPointer to the control block or output_buffer is NULL or output_buffer_size is 0.
FSP_ERR_INVALID_ALIGNMENTBuffer starting address is not 8-byte aligned.
FSP_ERR_NOT_OPENJPEG not opened.
FSP_ERR_JPEG_UNSUPPORTED_IMAGE_SIZEThe number of horizontal pixels exceeds horizontal memory stride.
FSP_ERR_JPEG_BUFFERSIZE_NOT_ENOUGHInvalid buffer size.
FSP_ERR_IN_USEThe output buffer cannot be changed during codec operation.

◆ R_JPEG_InputBufferSet()

fsp_err_t R_JPEG_InputBufferSet ( jpeg_ctrl_t *const  p_api_ctrl,
void *  p_data_buffer,
uint32_t  data_buffer_size 
)

Assign an input data buffer to the JPEG codec for processing.

Note
After the amount of data is processed, the JPEG driver triggers a callback function with the flag JPEG_PRV_OPERATION_INPUT_PAUSE set. The application supplies the next chunk of data to the driver so processing can resume.
The JPEG decoding operation automatically starts after both the input buffer and the output buffer are set, and the output buffer is big enough to hold at least one line of decoded image data.

If zero is provided for the decode data buffer size the JPEG Codec will never pause for more input data and will continue to read until either an image has been fully decoded or an error condition occurs.

Note
When encoding images the minimum data buffer size is 8 lines by 16 Y'CbCr 4:2:2 pixels (256 bytes). This corresponds to one minimum coded unit (MCU) of the resulting JPEG output.
Return values
FSP_SUCCESSThe input data buffer is properly assigned to JPEG Codec device.
FSP_ERR_ASSERTIONPointer to the control block is NULL, or the pointer to the input_buffer is NULL, or the input_buffer_size is 0.
FSP_ERR_INVALID_ALIGNMENTBuffer starting address is not 8-byte aligned.
FSP_ERR_NOT_OPENJPEG not opened.
FSP_ERR_IN_USEThe input buffer cannot be changed while the codec is running.
FSP_ERR_INVALID_CALLIn encode mode the output buffer must be set first.
FSP_ERR_JPEG_IMAGE_SIZE_ERRORThe buffer size is smaller than the minimum coded unit (MCU).

◆ R_JPEG_DecodeLinesDecodedGet()

fsp_err_t R_JPEG_DecodeLinesDecodedGet ( jpeg_ctrl_t p_api_ctrl,
uint32_t *  p_lines 
)

Returns the number of lines decoded into the output buffer.

Note
Use this function to retrieve the number of image lines written to the output buffer after a partial decode operation. Combined with the horizontal stride settings and the output pixel format the application can compute the amount of data to read from the output buffer.
Return values
FSP_SUCCESSLine count successfully returned.
FSP_ERR_ASSERTIONPointer to the control block or p_lines is NULL.
FSP_ERR_NOT_OPENJPEG not opened.

◆ R_JPEG_DecodeImageSubsampleSet()

fsp_err_t R_JPEG_DecodeImageSubsampleSet ( jpeg_ctrl_t *const  p_api_ctrl,
jpeg_decode_subsample_t  horizontal_subsample,
jpeg_decode_subsample_t  vertical_subsample 
)

Configure horizontal and vertical subsampling.

Note
This function can be used to scale the output of decoded image data.
Return values
FSP_SUCCESSHorizontal subsample value is properly configured.
FSP_ERR_ASSERTIONPointer to the control block is NULL.
FSP_ERR_NOT_OPENJPEG not opened.

◆ R_JPEG_DecodeHorizontalStrideSet()

fsp_err_t R_JPEG_DecodeHorizontalStrideSet ( jpeg_ctrl_t p_api_ctrl,
uint32_t  horizontal_stride 
)

Configure horizontal stride setting for decode operations.

Note
If the image size is known prior to the open call and/or the output buffer stride is constant, pass the horizontal stride value in the jpeg_cfg_t structure. Otherwise, after the image size becomes available use this function to set the output buffer horizontal stride value.
Return values
FSP_SUCCESSHorizontal stride value is properly configured.
FSP_ERR_ASSERTIONPointer to the control block is NULL.
FSP_ERR_INVALID_ALIGNMENTHorizontal stride is zero or is not 8-byte aligned.
FSP_ERR_NOT_OPENJPEG not opened.

◆ R_JPEG_DecodeImageSizeGet()

fsp_err_t R_JPEG_DecodeImageSizeGet ( jpeg_ctrl_t p_api_ctrl,
uint16_t *  p_horizontal_size,
uint16_t *  p_vertical_size 
)

Obtain the size of an image being decoded.

Return values
FSP_SUCCESSThe image size is available and the horizontal and vertical values are stored in the memory pointed to by p_horizontal_size and p_vertical_size.
FSP_ERR_ASSERTIONPointer to the control block is NULL and/or size is not ready.
FSP_ERR_NOT_OPENJPEG is not opened.

◆ R_JPEG_DecodePixelFormatGet()

fsp_err_t R_JPEG_DecodePixelFormatGet ( jpeg_ctrl_t p_api_ctrl,
jpeg_color_space_t p_color_space 
)

Get the color format of the JPEG being decoded.

Return values
FSP_SUCCESSThe color format was successfully retrieved.
FSP_ERR_ASSERTIONPointer to the control block is NULL.
FSP_ERR_NOT_OPENJPEG is not opened.

◆ R_JPEG_EncodeImageSizeSet()

fsp_err_t R_JPEG_EncodeImageSizeSet ( jpeg_ctrl_t *const  p_api_ctrl,
jpeg_encode_image_size_t p_image_size 
)

Set the image dimensions for an encode operation.

Note
Image dimensions must be set before setting the input buffer.
Return values
FSP_SUCCESSImage size was successfully written to the JPEG Codec.
FSP_ERR_ASSERTIONPointer to the control block or p_image_size is NULL.
FSP_ERR_INVALID_ALIGNMENTHorizontal stride is not 8-byte aligned.
FSP_ERR_INVALID_ARGUMENTHorizontal or vertical resolution is invalid or zero.
FSP_ERR_NOT_OPENJPEG not opened.
FSP_ERR_IN_USEImage parameters cannot be changed while the codec is running.

◆ R_JPEG_ModeSet()

fsp_err_t R_JPEG_ModeSet ( jpeg_ctrl_t *const  p_api_ctrl,
jpeg_mode_t  mode 
)

Switch between encode and decode mode (or vice-versa).

Note
The codec must not be idle in order to switch modes.
Return values
FSP_SUCCESSMode changed successfully.
FSP_ERR_ASSERTIONp_api_ctrl is NULL.
FSP_ERR_NOT_OPENModule is not open.
FSP_ERR_IN_USEJPEG Codec is currently in use.
FSP_ERR_INVALID_ARGUMENT(Encode only) Quality factor, horizontal resolution and/or vertical resolution are invalid.
FSP_ERR_INVALID_ALIGNMENT(Encode only) The horizontal resolution (at 16bpp) is not divisible by 8 bytes.

◆ R_JPEG_Close()

fsp_err_t R_JPEG_Close ( jpeg_ctrl_t p_api_ctrl)

Cancel an outstanding JPEG codec operation and close the device.

Return values
FSP_SUCCESSThe JPEG unit is stopped and the driver is closed.
FSP_ERR_ASSERTIONPointer to the control block is NULL.
FSP_ERR_NOT_OPENJPEG not opened.

◆ R_JPEG_StatusGet()

fsp_err_t R_JPEG_StatusGet ( jpeg_ctrl_t p_api_ctrl,
jpeg_status_t p_status 
)

Get the status of the JPEG codec. This function can also be used to poll the device.

Return values
FSP_SUCCESSThe status information is successfully retrieved.
FSP_ERR_ASSERTIONPointer to the control block or p_status is NULL.
FSP_ERR_NOT_OPENJPEG is not opened.