377 lines
14 KiB
C
377 lines
14 KiB
C
/*----------------------------------------------*/
|
|
/* JL HW JEPG CODEC */
|
|
/*----------------------------------------------*/
|
|
#ifndef _JL_HW_JPGDEC
|
|
#define _JL_HW_JPGDEC
|
|
#include "typedef.h"
|
|
#include "generic/rect.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
//#define MCU_BUFF_NUM 1
|
|
#ifndef MCU_BUFF_NUM
|
|
#define MCU_BUFF_NUM 2
|
|
#endif
|
|
/* Allow the number of cached MUC blocks , Default to 2 , 默认双buff乒乓,支持多 buff 模式,最小可以设置为 1 */
|
|
/* 当上层触发解码动作的速度比解码速度快时,适当改大可以提高速度,比如直接设置整幅图片的总 MCU 数量, 即硬件直接解完,效率只受限于解码速度*/
|
|
/* 当上层触发解码动作的速度比解码速度慢时,使用 2 个buff即保证每次来取数据都有已经解码完成的内容,改大没有意义 */
|
|
|
|
//#define BIT_BUFF_NUM 1
|
|
// #ifndef BIT_BUFF_NUM
|
|
// #define BIT_BUFF_NUM 1
|
|
// #endif
|
|
/* Allow the number of cached MUC blocks , Default to 2 , 双buff乒乓或者单buff阻塞使用 */
|
|
/* 大致情况和 MCU 类似,主要考虑到输入bit流需要时32位对齐的地址空间,原始 bit 流需要从 flash 或者 SD 卡之中进行拷贝到RAM中,因此建议乒乓操作, 更多的 buff 没有意义,因为取 bit 流的动作会比解码动作慢 */
|
|
|
|
//#define JDEC_SZBUF 1024 * 8
|
|
#ifndef JDEC_SZBUF
|
|
#define JDEC_SZBUF 512
|
|
#endif
|
|
/* Specifies size of stream input buffer , >= 17 + 256 */
|
|
|
|
#define JDEC_MAGIC "JLHWJPEG"
|
|
|
|
typedef enum {
|
|
JPG_TEM = 0X01, //算术编码中作临时之用
|
|
|
|
//非层次哈夫曼编码
|
|
JPIF_SOF0 = 0XC0, //基线离散余弦变换/*只支持这种编码格式的图片*/
|
|
JPIF_SOF1, //扩展顺序离散余弦变换
|
|
JPIF_SOF2, //递进离散余弦变换
|
|
JPIF_SOF3, //空间顺序无损
|
|
|
|
JPIF_DHT = 0XC4, //哈夫曼表
|
|
|
|
//层次哈夫曼编码
|
|
JPIF_SOF5, //差分离散余弦变换
|
|
JPIF_SOF6, //差分层次离散余弦变换
|
|
JPIF_SOF7, //差分空间无损
|
|
|
|
//非层次算术编码
|
|
JPIF_SOF8, //为JPEG扩展保留
|
|
JPIF_SOF9, //扩展顺序离散余弦变换
|
|
JPIF_SOF10, //递进离散余弦变换
|
|
JPIF_SOF11, //空间顺序无损
|
|
|
|
JPIF_DAC = 0XCC, //算术编码表
|
|
|
|
//层次算术编码
|
|
JPIF_SOF13, //差分离散余弦变换
|
|
JPIF_SOF14, //差分层次离散余弦变换
|
|
JPIF_SOF15, //差分空间无损
|
|
|
|
JPIF_RST0 = 0XD0, //每隔n个MCU 块就有一个RST标记
|
|
JPIF_RST1,
|
|
JPIF_RST2,
|
|
JPIF_RST3,
|
|
JPIF_RST4,
|
|
JPIF_RST5,
|
|
JPIF_RST6,
|
|
JPIF_RST7 = 0XD7,
|
|
|
|
JPIF_SOI = 0XD8, //文件头
|
|
JPIF_EOI = 0XD9, //文件尾
|
|
JPIF_SOS = 0XDA, //扫描行开始
|
|
JPIF_DQT = 0XDB, //量化表
|
|
JPIF_DNL = 0XDC, //线数
|
|
JPIF_DRI = 0XDD, //重新开始间隔
|
|
JPIF_DHP = 0XDE, //层次级数
|
|
JPIF_EXP = 0XDF, //展开参考图像
|
|
|
|
JPIF_APP0 = 0XE0, //交换格式和图像识别信息
|
|
JPIF_APP1,
|
|
JPIF_APP2,
|
|
JPIF_APP3,
|
|
JPIF_APP4,
|
|
JPIF_APP5,
|
|
JPIF_APP6,
|
|
JPIF_APP7,
|
|
JPIF_APP8,
|
|
JPIF_APP9,
|
|
JPIF_APP10,
|
|
JPIF_APP11,
|
|
JPIF_APP12,
|
|
JPIF_APP13,
|
|
JPIF_APP14,
|
|
JPIF_APP15,
|
|
JPIF_COM = 0XFE, //注释
|
|
JPIF_MASK = 0XFF,
|
|
} JPG_TYPE;
|
|
|
|
/* Decode event code */
|
|
typedef enum {
|
|
JDEC_INTER_MCU, /* 0: The specified number of MCU blocks finishes decoding */
|
|
JDEC_INTER_BIT, /* 1: End of bit stream */
|
|
JDEC_INTER_FINISH, /* 2: End of file decoding */
|
|
} jdec_msg;
|
|
|
|
/* Error code */
|
|
typedef enum {
|
|
JDEC_OK = 0, /* 0: Succeeded */
|
|
JDEC_INP, /* 1: Device error or wrong termination of input stream */
|
|
JDEC_MEM1, /* 2: Memory request failed */
|
|
JDEC_MEM2, /* 3: Memory space not requested */
|
|
JDEC_MEM3, /* 4: Exceeds input buffer size : > JDEC_SZBUF */
|
|
JDEC_FMT1, /* 5: Data format error (may be broken data) */
|
|
JDEC_FMT2, /* 6: Right format but not supported */
|
|
JDEC_FMT3, /* 7: Not supported JPEG standard */
|
|
JDEC_FMT4, /* 8: Decoding execution error*/
|
|
JDEC_STA, /* 9: Jpeg work status error*/
|
|
JDEC_TIMEOUT,/*10: DEC_TIMEOUT*/
|
|
JDEC_HD_ERR,/*11:DEC_HD ERR*/
|
|
} jdec_err;
|
|
|
|
/* HW JPEG work state code */
|
|
typedef enum {
|
|
JDEC_WORK_STATE_CLOSE = 0, /* The jpeg decoding module is turned off */
|
|
JDEC_WORK_STATE_INIT, /* The jpeg decoding module is inited*/
|
|
JDEC_WORK_STATE_OPEN, /* The jpeg decoding module is enabled */
|
|
JDEC_WORK_STATE_START, /* jpeg decoding begins */
|
|
JDEC_WORK_STATE_STOP, /* End of jpeg decoding */
|
|
JDEC_WORK_STATE_SUSPEND, /* Pause during jpeg decoding */
|
|
} jdec_work_state;
|
|
|
|
/* MCU/BIT buff state code */
|
|
typedef enum {
|
|
JDEC_BUFF_STATE_INVALID = 0, /* 0: The buff is invalid, and the data is outdated or invalid */
|
|
JDEC_BUFF_STATE_UNDECODED, /* 1: The mcu block or bit stream that has not yet begun decoding */
|
|
JDEC_BUFF_STATE_DECODING, /* 2: Wait for the mcu block or bit stream to decode */
|
|
JDEC_BUFF_STATE_DECODED, /* 3: The decoding of the mcu block or bit stream is completed */
|
|
JDEC_BUFF_STATE_COPY, /* 4: MCU buf copy to line buf */
|
|
} jdec_buff_state;
|
|
|
|
/* Mcu buff information structure */
|
|
typedef struct _jdec_muc_buff {
|
|
jdec_buff_state state; /* mcu block usage status */
|
|
u16 mcuid; /* mcu block ID */
|
|
u8 *buf; /* data buffer */
|
|
} jdec_mcu_buff;
|
|
|
|
/* Bit buff information structure */
|
|
typedef struct _jdec_bit_buff {
|
|
jdec_buff_state state; /* bit stream usage status */
|
|
u32 len; /* data len */
|
|
u8 *buf; /* data buffer */
|
|
} jdec_bit_buff;
|
|
|
|
/* Huffman table structs */
|
|
typedef struct _huff_tab {
|
|
u16 *min;
|
|
u8 *index;
|
|
u8 *pval;
|
|
} huff_tab;
|
|
|
|
/* Decompressor object structure */
|
|
typedef struct _jdec_opj {
|
|
void *magic; /* Decoder magic */
|
|
|
|
jdec_work_state work_state: 4; /* Working state of the jpeg decoder module */
|
|
u8 msx: 4;
|
|
u8 msy: 4; /* MCU size in unit of block (width, height) */
|
|
|
|
u8 ycnt: 2; /* Y in the proportion of MCU components: 0:YUV444;1:YUV422;3:YUV411/YUV420 */
|
|
|
|
u8 isr_flags: 4; /* BIT0:MCU BIT2:BITS BIT3:LINE BIT4:REV */
|
|
u8 ncomp: 2; /* Number of color components 1:grayscale, 3:color */
|
|
u8 format: 1; /*1:565 0:888*/
|
|
u8 line_buf_vaild: 1; /*line buf 有效位*/
|
|
u8 bit_buff_sw: 1; /*bits_buff*/
|
|
u8 dri_enable: 1; /*dri_enable*/
|
|
u8 cur_rst_flag: 3; /*rst_flag:0xff d0~d7*/
|
|
u32 rev: 5; /* 预留拓展*/
|
|
|
|
u16 wmcu_num; /* The number of mcu blocks in the horizontal direction */
|
|
u16 hmcu_num; /* The number of mcu blocks in the vertical direction */
|
|
|
|
u16 all_mcucnt; /* The total number of mcu blocks of the picture */
|
|
u16 curr_mcuid; /* The mcu block ID currently to be decodeid: 0 - (all_mcucnt - 1) */
|
|
u16 start_mcuid; /*单次解码的开始id*/
|
|
u16 end_mcuid; /*单次解码的结束id*/
|
|
u16 mcu_cnt; /*单次解码 MCU 块的数量*/
|
|
u16 mcu_size; /*单个 MCU 块的大小*/
|
|
|
|
u8 qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */
|
|
|
|
u16 width; /* Size of the input image (pixel) */
|
|
u16 height; /* Size of the input image (pixel) */
|
|
|
|
u32(*infunc)(struct _jdec_opj *, u8 *buf, u32 len); /* Pointer to jpeg stream input function */
|
|
void (*decode_msg)(struct _jdec_opj *, jdec_msg); /* Pointer to the jpeg decoding event function */
|
|
void (*decode_wait)(struct _jdec_opj *); /* The decoder event waits for the callback */
|
|
void *device; /* Pointer to I/O device identifiler for the session */
|
|
int curr_offset; /*文件内偏移*/
|
|
|
|
u8 *outbuf; /* YUV422 to RGB buff: 这个 buff 从上层应用传下来装载数据 */
|
|
huff_tab hufftbl[2][2]; /* Huffman tables [id][dcac] */
|
|
u16 *qt_table;
|
|
s16 *qttbl[2]; /* Dequantizer tables [id] */
|
|
u16 *std_huffman_table;
|
|
u32 *huffman;
|
|
jdec_mcu_buff mcu_buff[MCU_BUFF_NUM]; /* MCU_BUFF_NUM mcu block buffers: 这些 buff 负责暂存解码后的 MCU 块数据和 MCU 块信息 */
|
|
jdec_bit_buff *bit_buff; /* BIT_BUFF_NUM bit stream buffers: 这些 buff 负责暂存原始的 JPEG 数据或者 JPEG 段信息 */
|
|
u8 *line_buf; /*mcu解码后数据先暂存到linebuf再统一变换输出,同时缓存部分数据给下一次解码使用,避免重复*/
|
|
struct rect draw_rect; /*jpeg在屏幕的绘制区域*/
|
|
struct rect jpeg_rect; /*在jpeg解码的相对位置*/
|
|
struct rect obuf_rect; /*输出buffer的区域*/
|
|
struct rect cover_rect;
|
|
void *matrix; /* affine matrix: 用于合成这个JPG时做GPU变换 */
|
|
s16 surplus_line; /* line buf 剩余未使用数据*/
|
|
u16 nrst;
|
|
u32 bit_cnt_start; /*位流起始地址*/
|
|
unsigned long bit_usec; /*bit usec*/
|
|
unsigned long mcu_usec; /*mcu_usec*/
|
|
} jdec_opj;
|
|
|
|
extern const char jljpeg_magic[]; //识别解码器的标志字
|
|
|
|
/* JL JPEG DEC API functions */
|
|
void jljpeg_os_init(void);
|
|
void jljpeg_hw_config_stage1(jdec_opj *opj, bool os_flag);
|
|
jdec_err jljpeg_hw_config_stage2(void (*decode_msg)(struct _jdec_opj *, jdec_msg), void (*decode_wait)(struct _jdec_opj *), \
|
|
uint16_t mcu_cnt, uint8_t *mcu_buff);
|
|
jdec_err jljpeg_hw_config_stage3(uint16_t x, uint16_t y, uint8_t *buf);
|
|
void jljpeg_hw_release(void);
|
|
void jljpeg_hw_resource_release(bool os_flag);
|
|
jdec_opj *jpeg_hw_get(void);
|
|
void jpeg_hw_set(jdec_opj *opj);
|
|
|
|
void jljpeg_hw_init(jdec_opj *opj);
|
|
void jljpeg_hw_reset(void);
|
|
void jljpeg_hw_restart(void);
|
|
void jljpeg_hw_mcubuff_reset(jdec_opj *opj, uint16_t mcu_cnt, uint8_t *mcu_buff);
|
|
|
|
void *jpeg_malloc(int size);
|
|
void jpeg_free(void *p);
|
|
#define JPEG_MALLOC(a) jpeg_malloc(a)
|
|
#define JPEG_FREE(a) jpeg_free(a)
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_img_info_get 读取文件头
|
|
*
|
|
* @param opj
|
|
* @param infunc
|
|
* @param dev
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
jdec_err jljpeg_img_info_get(jdec_opj *opj, u32(*infunc)(jdec_opj *opj, u8 *buf, u32 size), void *dev);
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jpeg_decode_module_init jpeg 模块初始化
|
|
*
|
|
* @param malloc 申请
|
|
* @param free 释放
|
|
* @param gpu_blend 绘图
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
|
|
int jpeg_decode_module_init(
|
|
void *(*malloc)(int size, u32 ram_type, u32 module_type),
|
|
void (*free)(void *p, u32 ram_type, u32 module_type),
|
|
int (*gpu_blend)(u8 *dst_buf, struct rect *dst_rect, u8 *src_buf, struct rect *src_rect, struct rect *draw_rect, int src_stride, int format, void *p, int line_surpule, struct rect *cover)
|
|
);
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_decode_init 初始化解码
|
|
*
|
|
* @param opj
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
int jljpeg_decode_init(jdec_opj *opj);
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_decode_set_callback 注册回调
|
|
*
|
|
* @param opj 句柄
|
|
* @param infunc 输入数据流回调
|
|
* @param decode_msg
|
|
* @param decode_wait
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
int jljpeg_decode_set_callback(jdec_opj *opj,
|
|
u32(*infunc)(struct _jdec_opj *opj, u8 *buf, u32 len),
|
|
void (*decode_msg)(struct _jdec_opj *, jdec_msg),
|
|
void (*decode_wait)(struct _jdec_opj *)
|
|
);
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_decode_start 启动jpeg解码
|
|
*
|
|
* @param opj 解码句柄
|
|
* @param draw_rect 图片绘制区域
|
|
* @param jpeg_rect 在jpeg中的解码区域
|
|
* @param cover_rect 图片限制区域
|
|
* @param obuf_rect 输出buf区域
|
|
* @param dec_out_buf 输出buf
|
|
*
|
|
* @return jdec_err
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
jdec_err jljpeg_decode_start(jdec_opj *opj, struct rect *draw_rect, struct rect *jpeg_rect, struct rect *cover_rect, struct rect *obuf_rect, void *dec_out_buf);
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_decode_release
|
|
*
|
|
* @param opj 解码句柄
|
|
* @param global_hd_clr 将全局解码句柄置为NULL,需应用层free句柄
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
int jljpeg_decode_release(jdec_opj *opj, int global_hd_clr);
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_get_decode_hd 将当前解码句柄置为NULL,需应用层free句柄
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
void jljpeg_get_decode_hd_clr();
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_get_decode_hd 获取文件句柄
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
void *jljpeg_get_decode_hd();
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_decode_reset_curr 重新解码当前文件(废)
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
int jljpeg_decode_reset_curr();
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief jljpeg_decode_hdl_reset 重新解码当前文件
|
|
*
|
|
* @param opj
|
|
*
|
|
* @return
|
|
*/
|
|
/* ------------------------------------------------------------------------------------*/
|
|
int jljpeg_decode_hdl_reset(jdec_opj *opj);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _JL_HW_JPGDEC */
|