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
2625extern " 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
238236ImageBuffer *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//
343348void 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+
385426void 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