Skip to content

Commit 2d2716a

Browse files
committed
CONSOLE: added support for IMAGE command
1 parent edc0e7f commit 2d2716a

File tree

1 file changed

+111
-67
lines changed

1 file changed

+111
-67
lines changed

src/platform/console/image.cpp

Lines changed: 111 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "common/pproc.h"
2121
#include "common/fs_socket_client.h"
2222
#include "ui/strlib.h"
23-
#include "ui/utils.h"
2423
#include "ui/rgb.h"
2524

2625
extern "C" {
@@ -35,7 +34,7 @@ struct ImageBuffer {
3534

3635
unsigned _bid;
3736
char *_filename;
38-
unsigned char *_image;
37+
uint8_t *_image;
3938
int _width;
4039
int _height;
4140
};
@@ -70,13 +69,13 @@ ImageBuffer::~ImageBuffer() {
7069
_image = NULL;
7170
}
7271

73-
void create_func(var_p_t map, const char *name, method cb) {
72+
void create_function(var_p_t map, const char *name, method cb) {
7473
var_p_t v_func = map_add_var(map, name, 0);
7574
v_func->type = V_FUNC;
7675
v_func->v.fn.cb = cb;
7776
}
7877

79-
dev_file_t *eval_filep() {
78+
dev_file_t *get_file() {
8079
dev_file_t *result = NULL;
8180
code_skipnext();
8281
if (code_getnext() == '#') {
@@ -98,7 +97,7 @@ ImageBuffer *load_image(int w) {
9897
err_throw(ERR_PARAM);
9998
} else {
10099
int size = w * h * 4;
101-
unsigned char *image = (unsigned char *)calloc(size, 1);
100+
uint8_t *image = (uint8_t *)calloc(size, 1);
102101
result = new ImageBuffer();
103102
result->_bid = ++nextId;
104103
result->_width = w;
@@ -129,7 +128,7 @@ ImageBuffer *load_image(var_t *var) {
129128
int w = ABS(v_lbound(var, 0) - v_ubound(var, 0)) + 1;
130129
int h = ABS(v_lbound(var, 1) - v_ubound(var, 1)) + 1;
131130
int size = w * h * 4;
132-
unsigned char *image = (unsigned char *)malloc(size);
131+
uint8_t *image = (uint8_t *)malloc(size);
133132
for (int y = 0; y < h; y++) {
134133
int yoffs = (4 * y * w);
135134
for (int x = 0; x < w; x++) {
@@ -156,10 +155,10 @@ ImageBuffer *load_image(var_t *var) {
156155
return result;
157156
}
158157

159-
ImageBuffer *load_image(const unsigned char* buffer, int32_t size) {
158+
ImageBuffer *load_image(const uint8_t* buffer, int32_t size) {
160159
ImageBuffer *result = NULL;
161160
unsigned w, h;
162-
unsigned char *image;
161+
uint8_t *image;
163162
unsigned error = 0;
164163

165164
error = lodepng_decode32(&image, &w, &h, buffer, size);
@@ -192,7 +191,7 @@ ImageBuffer *load_image(dev_file_t *filep) {
192191

193192
if (result == NULL) {
194193
unsigned w, h;
195-
unsigned char *image;
194+
uint8_t *image;
196195
unsigned error = 0;
197196
unsigned network_error = 0;
198197
var_t *var_p;
@@ -205,8 +204,7 @@ ImageBuffer *load_image(dev_file_t *filep) {
205204
} else {
206205
var_p = v_new();
207206
http_read(filep, var_p);
208-
error = lodepng_decode32(&image, &w, &h, (unsigned char *)var_p->v.p.ptr,
209-
var_p->v.p.length);
207+
error = lodepng_decode32(&image, &w, &h, (uint8_t *)var_p->v.p.ptr, var_p->v.p.length);
210208
v_free(var_p);
211209
v_detach(var_p);
212210
}
@@ -237,7 +235,7 @@ ImageBuffer *load_image(dev_file_t *filep) {
237235

238236
ImageBuffer *load_xpm_image(char **data) {
239237
unsigned w, h;
240-
unsigned char *image;
238+
uint8_t *image;
241239
unsigned error = xpm_decode32(&image, &w, &h, data);
242240
ImageBuffer *result = NULL;
243241
if (!error) {
@@ -255,45 +253,50 @@ ImageBuffer *load_xpm_image(char **data) {
255253
}
256254

257255
//
258-
// png.save("horse1.png")
259-
// png.save(#1)
256+
// Reduces the size of the image
257+
// arguments: left, top, right, bottom
260258
//
261-
void cmd_image_save(var_s *self) {
259+
// png.clip(10, 10, 10, 10)
260+
//
261+
void cmd_image_clip(var_s *self) {
262+
var_int_t left, top, right, bottom;
262263
ImageBuffer *image = load_image(self);
263-
dev_file_t *filep = NULL;
264-
byte code = code_peek();
265-
int error = -1;
266-
int w = image->_width;
267-
int h = image->_height;
268-
var_t var;
269-
270-
if (!prog_error && image != NULL) {
271-
switch (code) {
272-
case kwTYPE_SEP:
273-
filep = eval_filep();
274-
if (filep != NULL && filep->open_flags == DEV_FILE_OUTPUT) {
275-
error = lodepng_encode32_file(filep->name, image->_image, w, h);
276-
}
277-
break;
278-
default:
279-
v_init(&var);
280-
eval(&var);
281-
if (var.type == V_STR && !prog_error) {
282-
error = lodepng_encode32_file(var.v.p.ptr, image->_image, w, h);
264+
if (par_massget("iiii", &left, &top, &right, &bottom) == 4) {
265+
int w = image->_width - (right + left);
266+
int h = image->_height - (bottom + top);
267+
int size = w * h * 4;
268+
int oldSize = image->_width * image->_height * 4;
269+
if (size > oldSize) {
270+
err_throw(ERR_PARAM);
271+
} else if (size != oldSize) {
272+
uint8_t *dst = (uint8_t *)calloc(size, 1);
273+
uint8_t *src = image->_image;
274+
for (int y = 0; y < h; y++) {
275+
int syoffs = (4 * (y + top) * image->_width);
276+
int dyoffs = (4 * y * w);
277+
for (int x = 0; x < w; x++) {
278+
int spos = syoffs + (4 * (x + left));
279+
int dpos = dyoffs + (4 * x);
280+
dst[dpos + 0] = src[spos + 0];
281+
dst[dpos + 1] = src[spos + 1];
282+
dst[dpos + 2] = src[spos + 2];
283+
dst[dpos + 3] = src[spos + 3];
284+
}
283285
}
284-
v_free(&var);
285-
break;
286+
free(image->_image);
287+
image->_image = dst;
288+
image->_width = w;
289+
image->_height = h;
290+
map_set_int(self, IMG_WIDTH, w);
291+
map_set_int(self, IMG_HEIGHT, h);
286292
}
287-
}
288-
if (error == -1) {
293+
} else {
289294
err_throw(ERR_PARAM);
290-
} else if (error != 0) {
291-
err_throw(ERR_IMAGE_SAVE_ERR, lodepng_error_text(error));
292295
}
293296
}
294297

295298
//
296-
// calls the supplied callback function on each pixel
299+
// Calls the supplied callback function on each pixel
297300
//
298301
// func colorToAlpha(x)
299302
// return x
@@ -308,7 +311,7 @@ void cmd_image_filter(var_s *self) {
308311
bcip_t exit_ip = code_getaddr();
309312
int w = image_buffer->_width;
310313
int h = image_buffer->_height;
311-
unsigned char *image = image_buffer->_image;
314+
uint8_t *image = image_buffer->_image;
312315
var_t var;
313316
v_init(&var);
314317
for (int y = 0; y < h; y++) {
@@ -336,16 +339,18 @@ void cmd_image_filter(var_s *self) {
336339
}
337340
}
338341

342+
//
343+
// Paste the given image into this image at the given x, y location
339344
//
340345
// png2 = image(w, h)
341-
// png2.paste(png1, 0, 0, w, h)
346+
// png2.paste(png1, 0, 0)
342347
//
343348
void cmd_image_paste(var_s *self) {
344-
var_int_t x, y, w, h;
349+
var_int_t x, y;
345350
var_t *var;
346351
ImageBuffer *image = load_image(self);
347-
int count = par_massget("Piiii", &var, &x, &y, &w, &h);
348-
if (image != NULL && (count == 1 || count == 3 || count == 5)) {
352+
int count = par_massget("Piiii", &var, &x, &y);
353+
if (image != NULL && (count == 1 || count == 3)) {
349354
ImageBuffer *srcImage = load_image(var);
350355
if (srcImage == NULL) {
351356
err_throw(ERR_PARAM);
@@ -354,26 +359,22 @@ void cmd_image_paste(var_s *self) {
354359
x = 0;
355360
y = 0;
356361
}
357-
if (count < 5) {
358-
w = image->_width;
359-
h = image->_height;
360-
}
361362
int dw = image->_width;
362363
int dh = image->_height;
363-
int sw = MIN(w, srcImage->_width);
364-
int sh = MIN(h, srcImage->_height);
365-
unsigned char *src = srcImage->_image;
366-
unsigned char *dst = image->_image;
364+
int sw = srcImage->_width;
365+
int sh = srcImage->_height;
366+
uint8_t *src = srcImage->_image;
367+
uint8_t *dst = image->_image;
367368
for (int sy = 0, dy = y; sy < sh && dy < dh; sy++, dy++) {
368369
int syoffs = (4 * sy * srcImage->_width);
369370
int dyoffs = (4 * dy * dw);
370371
for (int sx = 0, dx = x; sx < sw && dx < dw; sx++, dx++) {
371-
int soffs = syoffs + (4 * sx);
372-
int doffs = dyoffs + (4 * dx);
373-
dst[doffs + 0] = src[soffs + 0];
374-
dst[doffs + 1] = src[soffs + 1];
375-
dst[doffs + 2] = src[soffs + 2];
376-
dst[doffs + 3] = src[soffs + 3];
372+
int spos = syoffs + (4 * sx);
373+
int dpos = dyoffs + (4 * dx);
374+
dst[dpos + 0] = src[spos + 0];
375+
dst[dpos + 1] = src[spos + 1];
376+
dst[dpos + 2] = src[spos + 2];
377+
dst[dpos + 3] = src[spos + 3];
377378
}
378379
}
379380
}
@@ -382,17 +383,60 @@ void cmd_image_paste(var_s *self) {
382383
}
383384
}
384385

386+
//
387+
// Output the image to a PNG file
388+
//
389+
// png.save("horse1.png")
390+
// png.save(#1)
391+
//
392+
void cmd_image_save(var_s *self) {
393+
ImageBuffer *image = load_image(self);
394+
dev_file_t *filep = NULL;
395+
byte code = code_peek();
396+
int error = -1;
397+
int w = image->_width;
398+
int h = image->_height;
399+
var_t var;
400+
401+
if (!prog_error && image != NULL) {
402+
switch (code) {
403+
case kwTYPE_SEP:
404+
filep = get_file();
405+
if (filep != NULL && filep->open_flags == DEV_FILE_OUTPUT) {
406+
error = lodepng_encode32_file(filep->name, image->_image, w, h);
407+
}
408+
break;
409+
default:
410+
v_init(&var);
411+
eval(&var);
412+
if (var.type == V_STR && !prog_error) {
413+
error = lodepng_encode32_file(var.v.p.ptr, image->_image, w, h);
414+
}
415+
v_free(&var);
416+
break;
417+
}
418+
}
419+
if (error == -1) {
420+
err_throw(ERR_PARAM);
421+
} else if (error != 0) {
422+
err_throw(ERR_IMAGE_SAVE_ERR, lodepng_error_text(error));
423+
}
424+
}
425+
385426
void create_image(var_p_t var, ImageBuffer *image) {
386427
map_init(var);
387428
map_add_var(var, IMG_ID, ++nextId);
388429
map_add_var(var, IMG_WIDTH, image->_width);
389430
map_add_var(var, IMG_HEIGHT, image->_height);
390431
map_add_var(var, IMG_BID, image->_bid);
391-
create_func(var, "filter", cmd_image_filter);
392-
create_func(var, "paste", cmd_image_paste);
393-
create_func(var, "save", cmd_image_save);
432+
create_function(var, "clip", cmd_image_clip);
433+
create_function(var, "filter", cmd_image_filter);
434+
create_function(var, "paste", cmd_image_paste);
435+
create_function(var, "save", cmd_image_save);
394436
}
395437

438+
//
439+
// Creates an image object
396440
//
397441
// png = image(#1)
398442
// png = image("file.png")
@@ -408,7 +452,7 @@ extern "C" void v_create_image(var_p_t var) {
408452
byte code = code_peek();
409453
switch (code) {
410454
case kwTYPE_SEP:
411-
filep = eval_filep();
455+
filep = get_file();
412456
if (filep != NULL) {
413457
image = load_image(filep);
414458
}
@@ -440,10 +484,10 @@ extern "C" void v_create_image(var_p_t var) {
440484
// load from 2d array
441485
image = load_image(&arg);
442486
} else if (elem0->type == V_INT) {
443-
unsigned char *data = new unsigned char[v_asize(&arg)];
487+
uint8_t *data = new uint8_t[v_asize(&arg)];
444488
for (unsigned i = 0; i < v_asize(&arg); i++) {
445489
var_p_t elem = v_elem(&arg, i);
446-
data[i] = (unsigned char)elem->v.i;
490+
data[i] = (uint8_t)elem->v.i;
447491
}
448492
image = load_image(data, v_asize(&arg));
449493
delete [] data;

0 commit comments

Comments
 (0)