LVGL7.11使用libjpg库/二维码库

具体分析如下代码
jpg解码

#include "lv_jpg_decode.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include "../include/jpeg/jpeglib.h"
#include <setjmp.h>
#include "../../../include/anyka37d/ak_common_graphics.h"
#include "../../../include/anyka37d/ak_mem.h"
#include "../../../include/anyka37d/ak_tde.h"

struct my_error_mgr
{
	struct jpeg_error_mgr pub; /* "public" fields */

	jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr *my_error_ptr;

static void my_error_exit(j_common_ptr cinfo)
{
	/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
	my_error_ptr myerr = (my_error_ptr)cinfo->err;

	/* Always display the message. */
	/* We could postpone this until after returning, if we chose. */
	(*cinfo->err->output_message)(cinfo);

	/* Return control to the setjmp point */
	longjmp(myerr->setjmp_buffer, 1);
}

/***
**   日期:2022-07-01 13:50:29
**   作者: leo.liu
**   函数作用:获取解码的数据
**   参数说明:
***/
bool lv_jpg_decode_data(const char *file, rom_bin_info *info, int dst_w, int dst_h)
{
	FILE *jpeg_fd = fopen(file, "rb");
	if (jpeg_fd == NULL)
	{
		printf("jpg decode :open %s failed \n", file);
		return false;
	}
	struct jpeg_decompress_struct cinfo;
	struct my_error_mgr jerr;

	/* Step 1: allocate and initialize JPEG decompression object */
	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	if (setjmp(jerr.setjmp_buffer))
	{
		/* If we get here, the JPEG code has signaled an error.
		 * We need to clean up the JPEG object, close the input file, and return.
		 */
		jpeg_destroy_decompress(&cinfo);
		fclose(jpeg_fd);
		return false;
	}
	/* Now we can initialize the JPEG decompression object. */
	jpeg_create_decompress(&cinfo);
	/* Step 2: specify data source (eg, a file) */
	jpeg_stdio_src(&cinfo, jpeg_fd);
	/* Step 3: read file parameters with jpeg_read_header() */
	(void)jpeg_read_header(&cinfo, TRUE);

	/* Step 4: set parameters for decompression */
	cinfo.out_color_space = JCS_RGB;
	if ((dst_w * dst_h) < (cinfo.image_width * cinfo.image_height))
	{
		if (((abs(dst_w - cinfo.image_width)) < (abs(dst_h - cinfo.image_height))) && (dst_h < cinfo.image_height))
		{
			cinfo.scale_num = dst_h;
			cinfo.scale_denom = cinfo.image_height;
		}
		else
		{
			cinfo.scale_num = dst_h;
			cinfo.scale_denom = cinfo.image_width;
		}
	}
	/* Step 5: Start decompressor */
	(void)jpeg_start_decompress(&cinfo);
	printf("image_width = %d out_wdith=%d\n", cinfo.image_width, cinfo.output_width);
	printf("image_height = %d out_hegiht=%d\n", cinfo.image_height, cinfo.output_height);
	printf("num_components = %d\n", cinfo.num_components);

	/* JSAMPLEs per row in output buffer */
	int row_stride = cinfo.output_width * cinfo.output_components;
	/* Make a one-row-high sample array that will go away when done with image */
	unsigned char *jpeg_raw_data = (unsigned char *)ak_mem_dma_alloc(MODULE_ID_GUI, cinfo.output_height * row_stride);
	JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
	while (cinfo.output_scanline < cinfo.output_height)
	{
		/* jpeg_read_scanlines expects an array of pointers to scanlines.
		 * Here the array is only one element long, but you could ask for
		 * more than one scanline at a time if that's more convenient.
		 */
		(void)jpeg_read_scanlines(&cinfo, buffer, 1);
		memcpy(&jpeg_raw_data[cinfo.output_scanline * row_stride], buffer[0], row_stride);
		/* Assume put_scanline_someplace wants a pointer and sample count. */
	}

	struct ak_tde_layer src, dst;
	src.format_param = GP_FORMAT_RGB888;
	src.pos_width = src.width = cinfo.output_width;
	src.pos_height = src.height = cinfo.output_height;
	src.pos_left = src.pos_top = 0;
	ak_mem_dma_vaddr2paddr(jpeg_raw_data, (unsigned long *)&src.phyaddr);

#if LV_COLOR_DEPTH == 32
	dst.format_param = GP_FORMAT_BGR888;
#elif LV_COLOR_DEPTH == 16
	dst.format_param = GP_FORMAT_BGR565;
#endif
	dst.pos_width = dst.width = dst_w;
	dst.pos_height = dst.height = dst_h;
	dst.pos_left = dst.pos_top = 0;

	unsigned char *data = (unsigned char *)info->offset;
	ak_mem_dma_vaddr2paddr(data, (unsigned long *)&dst.phyaddr);

	ak_tde_opt_scale(&src, &dst);

	ak_mem_dma_free(jpeg_raw_data);
#if LV_COLOR_DEPTH == 32
	int len = dst_w * dst_h;
	unsigned char *dst_data = data + dst_w * dst_h * 4 - 1;
	unsigned char *src_data = data + dst_w * dst_h * 3 - 1;
	for (int i = 0; i < len; i++)
	{
		*dst_data = 0xFF;
		dst_data--;
		*dst_data = *src_data;
		dst_data--;
		src_data--;
		*dst_data = *src_data;
		dst_data--;
		src_data--;
		*dst_data = *src_data;
		dst_data--;
		src_data--;
	}
#endif

	/* Step 7: Finish decompression */
	(void)jpeg_finish_decompress(&cinfo);
	/* This is an important step since it will release a good deal of memory. */
	jpeg_destroy_decompress(&cinfo);

	fclose(jpeg_fd);
	return true;
}

二维码使用

/**
 * @file lv_qrcode.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lvgl/drive/lv_qrcode.h"
#include "lvgl/drive/qrcodegen.h"

/*********************
 *      DEFINES
 *********************/
#define QR_SIZE 140

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/**
 * Create an empty QR code (an `lv_canvas`) object.
 * @param parent point to an object where to create the QR code
 * @param size width and height of the QR code
 * @param dark_color dark color of the QR code
 * @param light_color light color of the QR code
 * @return pointer to the created QR code object
 */
lv_obj_t *lv_qrcode_create(lv_obj_t *parent, void *data, lv_coord_t size, lv_color_t dark_color, lv_color_t light_color)
{
	lv_obj_t *canvas = lv_canvas_create(parent, NULL);
	if (canvas == NULL)
		return NULL;
	lv_img_set_src(canvas, data);

	lv_img_dsc_t *imgdsc = lv_canvas_get_img(canvas);
	imgdsc->header.cf = LV_IMG_CF_RAW;
	imgdsc->header.w = size;
	imgdsc->header.h = size;
	rom_bin_info *img = (rom_bin_info *)(data);
	imgdsc->data = ((unsigned char *)img->offset);

	lv_canvas_set_palette(canvas, 0, dark_color);
	lv_canvas_set_palette(canvas, 1, light_color);
	return canvas;
}

/**
 * Set the data of a QR code object
 * @param qrcode pointer to aQ code object
 * @param data data to display
 * @param data_len length of data in bytes
 * @return LV_RES_OK: if no error; LV_RES_INV: on error
 */
lv_res_t lv_qrcode_update(lv_obj_t *qrcode, const void *data, uint32_t data_len)
{
	lv_color_t c;
	c.full = 1;
	lv_canvas_fill_bg(qrcode, c, LV_OPA_COVER);
	if (data_len > qrcodegen_BUFFER_LEN_MAX)
		return LV_RES_INV;
	uint8_t qr0[qrcodegen_BUFFER_LEN_MAX];
	uint8_t data_tmp[qrcodegen_BUFFER_LEN_MAX];
	memcpy(data_tmp, data, data_len);
	bool ok = qrcodegen_encodeBinary(data_tmp, data_len,
					 qr0, qrcodegen_Ecc_MEDIUM,
					 qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX,
					 qrcodegen_Mask_AUTO, true);

	if (!ok)
		return LV_RES_INV;

	lv_img_ext_t *imgdsc = lv_obj_get_ext_attr(qrcode);
	lv_coord_t obj_w = imgdsc->w;
	int qr_size = qrcodegen_getSize(qr0);
	int scale = obj_w / qr_size;
	int scaled = qr_size * scale;
	int margin = (obj_w - scaled) / 2;

	rom_bin_info *img = (rom_bin_info *)(imgdsc->src);
	unsigned char *buf_u8 = ((unsigned char *)img->offset);

	int raw_byte = LV_COLOR_SIZE / 8;
	uint32_t row_byte_cnt = obj_w * raw_byte;

	lv_color32_t d_c32;
	lv_color32_t l_c32;
	_lv_memcpy_small(&d_c32, &buf_u8[0 * sizeof(d_c32)], sizeof(d_c32));
	lv_color_t d_color = lv_color_hex(d_c32.full);

	_lv_memcpy_small(&l_c32, &buf_u8[1 * sizeof(l_c32)], sizeof(l_c32));
	lv_color_t l_color = lv_color_hex(l_c32.full);

	//_lv_memcpy_small(buf_u8, &(d_color.full), raw_byte);
	for (int y = 0; y < obj_w; y++)
	{
		for (int x = 0; x < obj_w; x++)
		{
			bool a = qrcodegen_getModule(qr0, (x - margin) / scale, (y - margin) / scale);
			if (a == false)
			{
				_lv_memcpy_small(&buf_u8[y * row_byte_cnt + x * raw_byte], &(l_color.full), raw_byte);
			}
			else
			{
				_lv_memcpy_small(&buf_u8[y * row_byte_cnt + x * raw_byte], &(d_color.full), raw_byte);
			}
		}
	}
	lv_obj_invalidate(qrcode);
	return LV_RES_OK;
}

/**
 * Delete a QR code object
 * @param qrcode pointer to a QR code obejct
 */
void lv_qrcode_delete(lv_obj_t *qrcode)
{
	lv_img_dsc_t *img = lv_canvas_get_img(qrcode);
	lv_img_cache_invalidate_src(img);
	//	lv_mem_free(img->data);
	lv_obj_del(qrcode);
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值