Skip to content

Commit

Permalink
feat(pandagl): update image reader to support reading one row of data
Browse files Browse the repository at this point in the history
  • Loading branch information
lc-soft committed Feb 11, 2024
1 parent 959ccb0 commit 08be521
Show file tree
Hide file tree
Showing 17 changed files with 794 additions and 839 deletions.
1 change: 1 addition & 0 deletions lib/pandagl/include/pandagl.h
Expand Up @@ -20,6 +20,7 @@
#include "pandagl/background.h"
#include "pandagl/border.h"
#include "pandagl/boxshadow.h"
#include "pandagl/file_reader.h"
#include "pandagl/font.h"
#include "pandagl/text.h"
#include "pandagl/image.h"
40 changes: 40 additions & 0 deletions lib/pandagl/include/pandagl/file_reader.h
@@ -0,0 +1,40 @@

#ifndef LIB_PANDAGL_INCLUDE_PANDAGL_FILE_READER_H
#define LIB_PANDAGL_INCLUDE_PANDAGL_FILE_READER_H

#include "common.h"
#include "types.h"

PD_BEGIN_DECLS

typedef struct pd_file_reader_t {
void *stream_data;
void (*fn_close)(void*);
void (*fn_rewind)(void*);
size_t (*fn_read)(void *, void *, size_t);
void (*fn_skip)(void *, long);
} pd_file_reader_t;

PD_INLINE size_t pd_file_reader_read(pd_file_reader_t *reader, void *buffer,
size_t size)
{
return reader->fn_read(reader->stream_data, buffer, size);
}

PD_INLINE void pd_file_reader_rewind(pd_file_reader_t *reader)
{
reader->fn_rewind(reader->stream_data);
}

PD_INLINE void pd_file_reader_skip(pd_file_reader_t *reader, long bytes)
{
reader->fn_skip(reader->stream_data, bytes);
}

PD_PUBLIC pd_file_reader_t *pd_file_reader_create(void);
PD_PUBLIC pd_file_reader_t *pd_file_reader_create_from_file(const char *filename);
PD_PUBLIC void pd_file_reader_destroy(pd_file_reader_t *reader);

PD_END_DECLS

#endif
138 changes: 37 additions & 101 deletions lib/pandagl/include/pandagl/image.h
Expand Up @@ -18,17 +18,12 @@

PD_BEGIN_DECLS

typedef void (*pd_image_progress_func_t)(void *, float);
typedef size_t (*pd_image_read_func_t)(void *, void *, size_t);
typedef void (*pd_image_skip_func_t)(void *, long);
typedef void (*pd_image_func_t)(void *);

/** 图像读取器的类型 */
typedef enum pd_image_reader_type_t {
PD_UNKNOWN_READER,
PD_PNG_READER,
PD_JPEG_READER,
PD_BMP_READER
PD_UNKNOWN_READER,
PD_PNG_READER,
PD_JPEG_READER,
PD_BMP_READER,
PD_READER_COUNT
} pd_image_reader_type_t;

#define PD_UNKNOWN_IMAGE PD_UNKNOWN_READER
Expand All @@ -37,106 +32,47 @@ typedef enum pd_image_reader_type_t {
#define PD_BMP_IMAGE PD_BMP_READER

#define pd_image_reader_set_jump(READER) \
(READER)->env &&setjmp(*((READER)->env))
(READER)->env &&setjmp(*((READER)->env))

typedef struct pd_image_header_t {
int type;
int bit_depth;
int color_type;
unsigned int width, height;
int type;
int bit_depth;
pd_color_type_t color_type;
unsigned int width, height;
} pd_image_header_t;

/** 图像读取器 */
typedef struct pd_image_reader_t {
/** 自定义的输入流数据 */
void *stream_data;

/** 是否有错误 */
unsigned char has_error;

/** 图像头部信息 */
pd_image_header_t header;

/** 在开始读取前调用的函数 */
pd_image_func_t fn_begin;

/** 在结束读取时调用的函数 */
pd_image_func_t fn_end;

/** 游标重置函数,用于重置当前读取位置到数据流的开头处 */
pd_image_func_t fn_rewind;

/** 数据读取函数,用于从数据流中读取数据 */
pd_image_read_func_t fn_read;

/** 游标移动函数,用于跳过一段数据 */
pd_image_skip_func_t fn_skip;

/** 用于接收图像读取进度的函数 */
pd_image_progress_func_t fn_prog;

/** 接收图像读取进度时的附加参数 */
void *prog_arg;

/** 图片读取器类型 */
int type;

/** 私有数据 */
void *data;

/** 私有数据的析构函数 */
void (*destructor)(void *);

/** 堆栈环境缓存的指针,用于 setjump() */
jmp_buf *env;

/** 默认堆栈环境缓存 */
jmp_buf env_src;
char error_message[256];
pd_image_reader_type_t type;
pd_file_reader_t *file_reader;
pd_image_header_t header;
unsigned read_row_index;
unsigned pass;
unsigned passes;
void *reader_data;
} pd_image_reader_t;

/** 初始化适用于 PNG 图像的读取器 */
PD_PUBLIC int pd_png_reader_init(pd_image_reader_t *reader);
PD_PUBLIC pd_image_reader_t *pd_image_reader_create(void);
PD_PUBLIC pd_image_reader_t *pd_image_reader_create_from_file(
const char *filename);

/** 初始化适用于 JPEG 图像的读取器 */
PD_PUBLIC int pd_jpeg_reader_init(pd_image_reader_t *reader);

/** 初始化适用于 BMP 图像的读取器 */
PD_PUBLIC int pd_bmp_reader_init(pd_image_reader_t *reader);

PD_PUBLIC void pd_image_reader_set_file(pd_image_reader_t *reader, FILE *fp);

/** 创建图像读取器 */
PD_PUBLIC int pd_image_reader_init(pd_image_reader_t *reader);

/** 销毁图像读取器 */
PD_PUBLIC void pd_image_reader_destroy(pd_image_reader_t *reader);

PD_PUBLIC int pd_png_reader_read_header(pd_image_reader_t *reader);

PD_PUBLIC int pd_jpeg_reader_read_header(pd_image_reader_t *reader);

PD_PUBLIC int pd_bmp_reader_read_header(pd_image_reader_t *reader);

PD_PUBLIC int pd_image_reader_read_header(pd_image_reader_t *reader);

PD_PUBLIC int pd_png_reader_read_data(pd_image_reader_t *reader,
pd_canvas_t *graph);

PD_PUBLIC int pd_bmp_reader_read_data(pd_image_reader_t *reader,
pd_canvas_t *graph);

PD_PUBLIC int pd_image_reader_read_data(pd_image_reader_t *reader,
pd_canvas_t *graph);

/** 将图像数据写入至png文件 */
PD_PUBLIC int pd_write_png_file(const char *file_name, const pd_canvas_t *graph);

/** 载入指定图片文件的图像数据 */
PD_PUBLIC int pd_read_image_from_file(const char *filepath, pd_canvas_t *out);

/** 从文件中获取图像尺寸 */
PD_PUBLIC int pd_read_image_size_from_file(const char *filepath, int *width,
int *height);
PD_PUBLIC jmp_buf *pd_image_reader_jmpbuf(pd_image_reader_t *reader);
PD_PUBLIC pd_error_t pd_image_reader_read_header(pd_image_reader_t *reader);
PD_PUBLIC void pd_image_reader_start(pd_image_reader_t *reader);
PD_PUBLIC pd_error_t pd_image_reader_create_buffer(pd_image_reader_t *reader,
pd_canvas_t *out);
PD_PUBLIC void pd_image_reader_read_row(pd_image_reader_t *reader,
pd_canvas_t *data);
PD_PUBLIC void pd_image_reader_finish(pd_image_reader_t *reader);
PD_PUBLIC pd_error_t pd_image_reader_read_data(pd_image_reader_t *reader,
pd_canvas_t *out);

PD_PUBLIC pd_error_t pd_read_image_from_file(const char *filepath,
pd_canvas_t *out);

PD_PUBLIC int pd_write_png_file(const char *file_name,
const pd_canvas_t *graph);

PD_END_DECLS

Expand Down
13 changes: 12 additions & 1 deletion lib/pandagl/include/pandagl/types.h
Expand Up @@ -21,14 +21,15 @@ typedef unsigned char pd_bool_t;
#define PD_TRUE 1

typedef enum pd_color_type_t {
PD_COLOR_TYPE_UNSUPPORTED,
PD_COLOR_TYPE_INDEX8, /**< 8位索引 */
PD_COLOR_TYPE_GRAY8, /**< 8位灰度 */
PD_COLOR_TYPE_RGB323, /**< RGB323 */
PD_COLOR_TYPE_ARGB2222, /**< ARGB2222 */
PD_COLOR_TYPE_RGB555, /**< RGB555 */
PD_COLOR_TYPE_RGB565, /**< RGB565 */
PD_COLOR_TYPE_RGB888, /**< RGB888 */
PD_COLOR_TYPE_ARGB8888 /**< RGB8888 */
PD_COLOR_TYPE_ARGB8888, /**< RGB8888 */
} pd_color_type_t;

#define PD_COLOR_TYPE_RGB PD_COLOR_TYPE_RGB888
Expand Down Expand Up @@ -126,4 +127,14 @@ typedef struct pd_border_t {
unsigned int bottom_right_radius;
} pd_border_t;

typedef enum pd_error_t {
PD_OK = 0,
PD_ERROR_NOT_FOUND,
PD_ERROR_NOT_IMPLEMENTED,
PD_ERROR_IMAGE_HEADER_INVALID,
PD_ERROR_IMAGE_TYPE_INCORRECT,
PD_ERROR_IMAGE_DATA_NOT_SUPPORTED,
PD_ERROR_IMAGE_READING
} pd_error_t;

#endif
52 changes: 52 additions & 0 deletions lib/pandagl/src/file_reader.c
@@ -0,0 +1,52 @@
#include <stdio.h>
#include <stdlib.h>
#include <pandagl/file_reader.h>

static size_t pd_file_stream_on_read(void *data, void *buffer, size_t size)
{
return fread(buffer, 1, size, data);
}

static void pd_file_stream_on_skip(void *data, long offset)
{
fseek(data, offset, SEEK_CUR);
}

static void pd_file_stream_on_rewind(void *data)
{
rewind(data);
}

static void pd_file_stream_on_close(void *data)
{
fclose(data);
}

pd_file_reader_t *pd_file_reader_create(void)
{
return calloc(1, sizeof(pd_file_reader_t));
}

pd_file_reader_t *pd_file_reader_create_from_file(const char *filename)
{
FILE *fp;
pd_file_reader_t *reader;

fp = fopen(filename, "rb");
if (fp == NULL) {
return NULL;
}
reader = pd_file_reader_create();
reader->stream_data = fp;
reader->fn_skip = pd_file_stream_on_skip;
reader->fn_read = pd_file_stream_on_read;
reader->fn_rewind = pd_file_stream_on_rewind;
reader->fn_close = pd_file_stream_on_close;
return reader;
}

void pd_file_reader_destroy(pd_file_reader_t *reader)
{
reader->fn_close(reader->stream_data);
free(reader);
}

0 comments on commit 08be521

Please sign in to comment.