mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #79 from kwagyeman/master
Add top level file open function.
This commit is contained in:
commit
70ed5c0f81
@ -21,7 +21,8 @@ static uint32_t bmp_fmt;
|
||||
static uint32_t bmp_row_bytes;
|
||||
|
||||
// This function inits the geometry values of an image.
|
||||
int bmp_read_geometry(FIL *fp, image_t *img, const char *path)
|
||||
int bmp_read_geometry(FIL *fp, image_t *img, const char *path,
|
||||
bool *w_flipped, bool *h_flipped)
|
||||
{
|
||||
FRESULT res = f_open(fp, path, FA_READ|FA_OPEN_EXISTING);
|
||||
if (res != FR_OK) {
|
||||
@ -112,6 +113,13 @@ int bmp_read_geometry(FIL *fp, image_t *img, const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (w_flipped) {
|
||||
*w_flipped = (bmp_w < 0); // Raster scan perspective
|
||||
}
|
||||
if (h_flipped) {
|
||||
*h_flipped = (bmp_h >= 0); // Raster scan perspective
|
||||
}
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
@ -129,8 +137,8 @@ int bmp_read_pixels(FIL *fp, image_t *img, int line_start, int line_end)
|
||||
uint8_t pixel;
|
||||
READ_BYTE(fp, &pixel);
|
||||
if (j < img->w) {
|
||||
if (bmp_h < 0) { // vertical flip
|
||||
if (bmp_w < 0) { // horizontal flip
|
||||
if (bmp_h < 0) { // vertical flip (BMP file perspective)
|
||||
if (bmp_w < 0) { // horizontal flip (BMP file perspective)
|
||||
IM_SET_GS_PIXEL(img, (img->w-j-1), i, pixel);
|
||||
} else {
|
||||
IM_SET_GS_PIXEL(img, j, i, pixel);
|
||||
@ -153,8 +161,8 @@ int bmp_read_pixels(FIL *fp, image_t *img, int line_start, int line_end)
|
||||
READ_WORD(fp, &pixel);
|
||||
IM_SWAP16(pixel);
|
||||
if (j < img->w) {
|
||||
if (bmp_h < 0) { // vertical flip
|
||||
if (bmp_w < 0) { // horizontal flip
|
||||
if (bmp_h < 0) { // vertical flip (BMP file perspective)
|
||||
if (bmp_w < 0) { // horizontal flip (BMP file perspective)
|
||||
IM_SET_RGB565_PIXEL(img, (img->w-j-1), i, pixel);
|
||||
} else {
|
||||
IM_SET_RGB565_PIXEL(img, j, i, pixel);
|
||||
@ -206,7 +214,7 @@ static int bmp_read_int(image_t *img, const char *path)
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
int res = bmp_read_geometry(&fp, img, path);
|
||||
int res = bmp_read_geometry(&fp, img, path, NULL, NULL);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -10,9 +10,11 @@
|
||||
#include <string.h>
|
||||
#include <arm_math.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <mp.h>
|
||||
#include "array.h"
|
||||
#include "imlib.h"
|
||||
#include "ff.h"
|
||||
#include "ff_wrapper.h"
|
||||
#include "mdefs.h"
|
||||
#include "font.h"
|
||||
#include "fb_alloc.h"
|
||||
@ -24,6 +26,76 @@ extern const int8_t lab_table[196608];
|
||||
/* Grayscale [0..255] to rainbox lookup */
|
||||
extern const uint16_t rainbow_table[256];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define IMLIB_READ_FUNCTION_LINE_BUFFER (32)
|
||||
|
||||
static enum { PPM_IMAGE, BMP_IMAGE, JPEG_IMAGE } imlib_image_type;
|
||||
|
||||
int imlib_read_geometry(FIL *fp, image_t *image, const char *path,
|
||||
bool *w_flipped, bool *h_flipped, bool disable_jpeg)
|
||||
{
|
||||
FRESULT res = f_open(fp, path, FA_READ|FA_OPEN_EXISTING);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
char magic[2];
|
||||
READ_DATA(fp, &magic, 2);
|
||||
|
||||
res = f_close(fp);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if ((magic[0]=='P')
|
||||
&& ((magic[1]=='2') || (magic[1]=='3')
|
||||
|| (magic[1]=='5') || (magic[1]=='6'))) { // PPM
|
||||
imlib_image_type = PPM_IMAGE;
|
||||
*w_flipped = false;
|
||||
*h_flipped = false;
|
||||
return ppm_read_geometry(fp, image, path);
|
||||
} else if ((magic[0]=='B') && (magic[1]=='M')) { // BMP
|
||||
imlib_image_type = BMP_IMAGE;
|
||||
return bmp_read_geometry(fp, image, path, w_flipped, h_flipped);
|
||||
} else if ((magic[0]==0xFF) && (magic[1]==0xD8)) { // JPEG
|
||||
if (disable_jpeg) {
|
||||
nlr_jump(mp_obj_new_exception_msg(
|
||||
&mp_type_OSError,
|
||||
"Operation not supported on JPEG"));
|
||||
}
|
||||
imlib_image_type = JPEG_IMAGE;
|
||||
*w_flipped = false;
|
||||
*h_flipped = false;
|
||||
return jpeg_read_geometry(fp, image, path);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int imlib_read_pixels(FIL *fp, image_t *img, int line_start, int line_end)
|
||||
{
|
||||
switch (imlib_image_type) {
|
||||
case PPM_IMAGE: return ppm_read_pixels(fp, img, line_start, line_end);
|
||||
case BMP_IMAGE: return bmp_read_pixels(fp, img, line_start, line_end);
|
||||
default: return jpeg_read_pixels(fp, img);
|
||||
}
|
||||
}
|
||||
|
||||
/* those just call ppm for now */
|
||||
int imlib_load_image(image_t *image, const char *path)
|
||||
{
|
||||
// needs to be redone still
|
||||
return ppm_read(image, path);
|
||||
}
|
||||
|
||||
int imlib_save_image(image_t *image, const char *path, rectangle_t *roi)
|
||||
{
|
||||
return ppm_write_subimg(image, path, roi);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get pixel (handles boundary check and image type check).
|
||||
int imlib_get_pixel(image_t *img, int x, int y)
|
||||
{
|
||||
@ -46,16 +118,7 @@ void imlib_set_pixel(image_t *img, int x, int y, int p)
|
||||
}
|
||||
}
|
||||
|
||||
/* those just call ppm for now */
|
||||
int imlib_load_image(image_t *image, const char *path)
|
||||
{
|
||||
return ppm_read(image, path);
|
||||
}
|
||||
|
||||
int imlib_save_image(image_t *image, const char *path, rectangle_t *roi)
|
||||
{
|
||||
return ppm_write_subimg(image, path, roi);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void imlib_draw_line(image_t *img, int x0, int y0, int x1, int y1, int c)
|
||||
{
|
||||
@ -138,6 +201,8 @@ void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void imlib_binary(image_t *img, int num_thresholds, simple_color_t *l_thresholds, simple_color_t *h_thresholds, bool invert)
|
||||
{
|
||||
if (IM_IS_GS(img)) {
|
||||
@ -443,6 +508,8 @@ float imlib_orientation_degrees(image_t *img, int *sum, int *x_center, int *y_ce
|
||||
return (imlib_orientation_radians(img, sum, x_center, y_center, r) * 180.0) / M_PI;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void imlib_negate(image_t *img)
|
||||
{
|
||||
if (IM_IS_GS(img)) {
|
||||
@ -491,6 +558,8 @@ void imlib_difference(image_t *img, const char *file, image_t *other)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint32_t imlib_lab_distance(struct color *c0, struct color *c1)
|
||||
{
|
||||
uint32_t sum=0;
|
||||
|
||||
@ -280,6 +280,27 @@ typedef enum interp {
|
||||
INTERP_BICUBIC
|
||||
} interp_t;
|
||||
|
||||
/* Image file functions */
|
||||
int ppm_read_geometry(FIL *fp, image_t *img, const char *path);
|
||||
int ppm_read_pixels(FIL *fp, image_t *img, int line_start, int line_end);
|
||||
int ppm_read(image_t *img, const char *path);
|
||||
int ppm_write_subimg(image_t *img, const char *path, rectangle_t *r);
|
||||
int bmp_read_geometry(FIL *fp, image_t *img, const char *path,
|
||||
bool *w_flipped, bool *h_flipped);
|
||||
int bmp_read_pixels(FIL *fp, image_t *img, int line_start, int line_end);
|
||||
int bmp_read(image_t *img, const char *path);
|
||||
int bmp_write_subimg(image_t *img, const char *path, rectangle_t *r);
|
||||
int jpeg_read_geometry(FIL *fp, image_t *img, const char *path);
|
||||
int jpeg_read_pixels(FIL *fp, image_t *img);
|
||||
int jpeg_read(image_t *img, const char *path);
|
||||
int jpeg_write(image_t *img, const char *path);
|
||||
int imlib_read_geometry(FIL *fp, image_t *img, const char *path,
|
||||
bool *w_flipped, bool *h_flipped, bool disable_jpeg);
|
||||
int imlib_read_pixels(FIL *fp, image_t *img, int line_start, int line_end);
|
||||
int imlib_load_image(image_t *image, const char *path);
|
||||
int imlib_save_image(image_t *image, const char *path, rectangle_t *roi);
|
||||
|
||||
/* Basic image functions */
|
||||
int imlib_get_pixel(image_t *img, int x, int y);
|
||||
void imlib_set_pixel(image_t *img, int x, int y, int p);
|
||||
|
||||
@ -288,18 +309,6 @@ point_t *point_alloc(int16_t x, int16_t y);
|
||||
bool point_equal(point_t *p1, point_t *p2);
|
||||
float point_distance(point_t *p1, point_t *p2);
|
||||
|
||||
/* Image file functions */
|
||||
int ppm_read_geometry(FIL *fp, image_t *img, const char *path);
|
||||
int ppm_read_pixels(FIL *fp, image_t *img, int line_start, int line_end);
|
||||
int ppm_read(image_t *img, const char *path);
|
||||
int ppm_write_subimg(image_t *img, const char *path, rectangle_t *r);
|
||||
int bmp_read_geometry(FIL *fp, image_t *img, const char *path);
|
||||
int bmp_read_pixels(FIL *fp, image_t *img, int line_start, int line_end);
|
||||
int bmp_read(image_t *img, const char *path);
|
||||
int bmp_write_subimg(image_t *img, const char *path, rectangle_t *r);
|
||||
int imlib_load_image(image_t *image, const char *path);
|
||||
int imlib_save_image(image_t *image, const char *path, rectangle_t *roi);
|
||||
|
||||
/* Rectangle functions */
|
||||
rectangle_t *rectangle_alloc(int16_t x, int16_t y, int16_t w, int16_t h);
|
||||
bool rectangle_equal(rectangle_t *r1, rectangle_t *r2);
|
||||
@ -349,7 +358,6 @@ void imlib_histeq(struct image *src);
|
||||
void imlib_median_filter(image_t *src, int r);
|
||||
void imlib_erode(image_t *src, int ksize);
|
||||
void imlib_dilate(image_t *src, int ksize);
|
||||
void imlib_invert(image_t *src);
|
||||
void imlib_threshold(image_t *src, image_t *dst, color_t *color, int color_size, int threshold);
|
||||
void imlib_rainbow(image_t *src, struct image *dst);
|
||||
array_t *imlib_count_blobs(struct image *image);
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <arm_math.h>
|
||||
|
||||
#include "ff.h"
|
||||
#include "ff_wrapper.h"
|
||||
#include "xalloc.h"
|
||||
#include "imlib.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
@ -632,3 +633,109 @@ void jpeg_compress(image_t *src, image_t *dst, int quality)
|
||||
printf("time: %lums\n", HAL_GetTick() - start);
|
||||
#endif
|
||||
}
|
||||
|
||||
// This function inits the geometry values of an image.
|
||||
int jpeg_read_geometry(FIL *fp, image_t *img, const char *path)
|
||||
{
|
||||
FRESULT res = f_open(fp, path, FA_READ|FA_OPEN_EXISTING);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uint16_t header;
|
||||
READ_WORD(fp, &header);
|
||||
IM_SWAP16(header);
|
||||
if ((0xFFD0 <= header) && (header <= 0xFFD9)) {
|
||||
continue;
|
||||
} else if (((0xFFC0 <= header) && (header <= 0xFFCF))
|
||||
|| ((0xFFDA <= header) && (header <= 0xFFDF))
|
||||
|| ((0xFFE0 <= header) && (header <= 0xFFEF))
|
||||
|| ((0xFFF0 <= header) && (header <= 0xFFFE)))
|
||||
{
|
||||
uint16_t size;
|
||||
READ_WORD(fp, &size);
|
||||
IM_SWAP16(size);
|
||||
if (((0xFFC0 <= header) && (header <= 0xFFC3))
|
||||
|| ((0xFFC5 <= header) && (header <= 0xFFC7))
|
||||
|| ((0xFFC9 <= header) && (header <= 0xFFCB))
|
||||
|| ((0xFFCD <= header) && (header <= 0xFFCF)))
|
||||
{
|
||||
READ_BYTE_IGNORE(fp);
|
||||
uint16_t width;
|
||||
READ_WORD(fp, &width);
|
||||
IM_SWAP16(width);
|
||||
uint16_t height;
|
||||
READ_WORD(fp, &height);
|
||||
IM_SWAP16(height);
|
||||
img->w = width;
|
||||
img->h = height;
|
||||
img->bpp = f_size(fp);
|
||||
return FR_OK;
|
||||
}
|
||||
FRESULT res = f_lseek(fp, f_tell(fp) + size - 2);
|
||||
if (res != FR_OK) {
|
||||
f_close(fp);
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
f_close(fp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function reads the pixel values of an image.
|
||||
int jpeg_read_pixels(FIL *fp, image_t *img)
|
||||
{
|
||||
FRESULT res = f_lseek(fp, 0);
|
||||
if (res != FR_OK) {
|
||||
f_close(fp);
|
||||
return res;
|
||||
}
|
||||
READ_DATA(fp, img->pixels, img->bpp);
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
static int jpeg_read_int(image_t *img, const char *path)
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
int res = jpeg_read_geometry(&fp, img, path);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!img->pixels) { // don't allocate if already allocated...
|
||||
img->pixels = xalloc(img->bpp);
|
||||
}
|
||||
|
||||
res = jpeg_read_pixels(&fp, img);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return f_close(&fp);
|
||||
}
|
||||
|
||||
int jpeg_read(image_t *img, const char *path)
|
||||
{
|
||||
const uint8_t *backup = img->pixels;
|
||||
const int res = jpeg_read_int(img, path);
|
||||
// free image if I didn't start with one...
|
||||
if ((res != FR_OK) && (!backup) && (img->pixels)) {
|
||||
xfree(img->pixels);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int jpeg_write(image_t *img, const char *path)
|
||||
{
|
||||
FIL fp;
|
||||
FRESULT res = f_open(&fp, path, FA_WRITE|FA_CREATE_ALWAYS);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
WRITE_DATA(&fp, img->pixels, img->bpp);
|
||||
return f_close(&fp);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user