Merge pull request #79 from kwagyeman/master

Add top level file open function.
This commit is contained in:
Ibrahim Abd Elkader 2016-02-24 05:27:27 +02:00
commit 70ed5c0f81
4 changed files with 221 additions and 29 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);
}