Merge pull request #85 from kwagyeman/master

Add line op function.
This commit is contained in:
Ibrahim Abd Elkader 2016-02-27 17:52:36 +02:00
commit e28d2445b1
6 changed files with 88 additions and 10 deletions

View File

@ -47,13 +47,15 @@ NORETURN void ff_file_corrupted(FIL *fp)
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "File corrupted!"));
}
NORETURN void ff_not_equal()
NORETURN void ff_not_equal(FIL *fp)
{
if (fp) f_close(fp);
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Images not equal!"));
}
NORETURN void ff_no_intersection()
NORETURN void ff_no_intersection(FIL *fp)
{
if (fp) f_close(fp);
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "No intersection!"));
}

View File

@ -12,8 +12,8 @@
#include <ff.h>
void ff_unsupported_format(FIL *fp);
void ff_file_corrupted(FIL *fp);
void ff_not_equal();
void ff_no_intersection();
void ff_not_equal(FIL *fp);
void ff_no_intersection(FIL *fp);
void file_read_open(FIL *fp, const char *path);
void file_write_open(FIL *fp, const char *path);
void file_close(FIL *fp);

View File

@ -86,7 +86,7 @@ void bmp_read_pixels(FIL *fp, image_t *img, int line_start, int line_end, bmp_re
if ((rs->bmp_h < 0) && (rs->bmp_w >= 0) && (img->w == rs->bmp_row_bytes)) {
read_data(fp, // Super Fast - Zoom, Zoom!
img->pixels + (line_start * img->w),
(line_end - line_start + 1) * img->w);
(line_end - line_start) * img->w);
} else {
for (int i = line_start; i < line_end; i++) {
for (int j = 0; j < rs->bmp_row_bytes; j++) {
@ -177,7 +177,7 @@ void bmp_read(image_t *img, const char *path)
void bmp_write_subimg(image_t *img, const char *path, rectangle_t *r)
{
rectangle_t rect;
if (!rectangle_subimg(img, r, &rect)) ff_no_intersection();
if (!rectangle_subimg(img, r, &rect)) ff_no_intersection(NULL);
FIL fp;
file_write_open(&fp, path);

View File

@ -87,7 +87,7 @@ static save_image_format_t imblib_parse_extension(image_t *img, const char *path
return FORMAT_DONT_CARE;
}
bool imlib_read_geometry(FIL *fp, image_t *img, const char *path, img_read_settings_t *rs)
static bool imlib_read_geometry(FIL *fp, image_t *img, const char *path, img_read_settings_t *rs)
{
file_read_open(fp, path);
char magic[2];
@ -110,7 +110,7 @@ bool imlib_read_geometry(FIL *fp, image_t *img, const char *path, img_read_setti
return vflipped;
}
void imlib_read_pixels(FIL *fp, image_t *img, int line_start, int line_end, img_read_settings_t *rs)
static void imlib_read_pixels(FIL *fp, image_t *img, int line_start, int line_end, img_read_settings_t *rs)
{
switch (rs->format) {
case FORMAT_DONT_CARE: // won't happen
@ -126,6 +126,79 @@ void imlib_read_pixels(FIL *fp, image_t *img, int line_start, int line_end, img_
}
}
// Main Ram = 196,608 bytes
// -
// struct framebuffer = 20 bytes
// FB_JPEG_OFFS_SIZE = 1,024 bytes
// GRAYSCALE 320x240x1 image = 76,800 bytes
// fb_alloc = 4 bytes
// flash cache = 16,384 bytes
// =
// 102,376 bytes
// /
// GRAYSCALE 320x1 lines
// =
// 319 GRAYSCALE 320x1 lines
#define GS_LINE_BUFFER_SIZE (64) // double rgb565
// Main Ram = 196,608 bytes
// -
// struct framebuffer = 20 bytes
// FB_JPEG_OFFS_SIZE = 1,024 bytes
// RGB565 320x240x2 image = 153,600 bytes
// fb_alloc = 4 bytes
// flash cache = 16,384 bytes
// =
// 25,576 bytes
// /
// RGB565 320x2 lines
// =
// 39 RGB565 320x2 lines
#define RGB565_LINE_BUFFER_SIZE (32)
void imlib_image_operation(image_t *img, const char *path, image_t *other, line_op_t op)
{
if (path) {
FIL fp;
image_t temp;
img_read_settings_t rs;
bool vflipped = imlib_read_geometry(&fp, &temp, path, &rs);
if (!IM_EQUAL(img, &temp)) {
ff_not_equal(&fp);
}
// This code reads a window of an image in at a time and then executes
// the line operation on each line in that window before moving to the
// next window. The vflipped part is here because BMP files can be saved
// vertically flipped resulting in us reading the image backwards.
temp.h = IM_IS_GS(img) ? GS_LINE_BUFFER_SIZE : RGB565_LINE_BUFFER_SIZE;
// When processing vertically flipped images the read function will fill
// the window up from the bottom. The read function assumes that the
// window is equal to an image in size. However, since this is not the
// case we shrink the window size to how many lines we're buffering.
temp.pixels = fb_alloc(temp.w * temp.h * temp.bpp);
for (int i=0; i<img->h; i+=temp.h) { // goes past end
int can_do = IM_MIN(temp.h, img->h-i);
imlib_read_pixels(&fp, &temp, 0, can_do, &rs);
for (int j=0; j<can_do; j++) {
if (!vflipped) {
op(img, i+j, temp.pixels+(temp.w*temp.bpp*j));
} else {
op(img, (img->h-i-can_do)+j, temp.pixels+(temp.w*temp.bpp*j));
}
}
}
fb_free();
file_close(&fp);
} else {
if (!IM_EQUAL(img, other)) {
ff_not_equal(NULL);
}
for (int i=0; i<img->h; i++) {
op(img, i, other->pixels + (img->w * img->bpp * i));
}
}
}
void imlib_load_image(image_t *img, const char *path)
{
FIL fp;

View File

@ -311,6 +311,8 @@ typedef struct img_read_settings {
save_image_format_t format;
} img_read_settings_t;
typedef void (*line_op_t)(image_t*, int, uint8_t*);
/* Image file functions */
void ppm_read_geometry(FIL *fp, image_t *img, const char *path, ppm_read_settings_t *rs);
void ppm_read_pixels(FIL *fp, image_t *img, int line_start, int line_end, ppm_read_settings_t *rs);
@ -324,6 +326,7 @@ void jpeg_read_geometry(FIL *fp, image_t *img, const char *path);
void jpeg_read_pixels(FIL *fp, image_t *img);
void jpeg_read(image_t *img, const char *path);
void jpeg_write(image_t *img, const char *path);
void imlib_image_operation(image_t *img, const char *path, image_t *other, line_op_t op);
void imlib_load_image(image_t *img, const char *path);
void imlib_save_image(image_t *img, const char *path, rectangle_t *roi);

View File

@ -93,7 +93,7 @@ void ppm_read_pixels(FIL *fp, image_t *img, int line_start, int line_end, ppm_re
} else if (rs->ppm_fmt == '5') {
read_data(fp, // Super Fast - Zoom, Zoom!
img->pixels + (line_start * img->w),
(line_end - line_start + 1) * img->w);
(line_end - line_start) * img->w);
} else if (rs->ppm_fmt == '6') {
for (int i = line_start; i < line_end; i++) {
for (int j = 0; j < img->w; j++) {
@ -122,7 +122,7 @@ void ppm_read(image_t *img, const char *path)
void ppm_write_subimg(image_t *img, const char *path, rectangle_t *r)
{
rectangle_t rect;
if (!rectangle_subimg(img, r, &rect)) ff_no_intersection();
if (!rectangle_subimg(img, r, &rect)) ff_no_intersection(NULL);
FIL fp;
file_write_open(&fp, path);