@@ -450,17 +450,19 @@ void cmd_image_hide(var_s *self, var_s *) {
450450}
451451
452452//
453- // Output the image to a PNG file
453+ // Output the image to a PNG file or an array
454454//
455455// png.save("horse1.png")
456456// png.save(#1)
457+ // png.save(byref var)
458+ // file = "abc.png" : png.save(file)
457459//
458460void cmd_image_save (var_s *self, var_s *) {
459461 unsigned id = map_get_int (self, IMG_BID, -1 );
460462 ImageBuffer *image = get_image (id);
461463 dev_file_t *file;
462- var_t *array ;
463- var_t var ;
464+ var_t *var ;
465+ var_t str ;
464466 bool saved = false ;
465467 if (!prog_error && image != nullptr ) {
466468 unsigned w = image->_width ;
@@ -473,37 +475,54 @@ void cmd_image_save(var_s *self, var_s *) {
473475 saved = true ;
474476 }
475477 break ;
476- case kwTYPE_VAR:
477- array = par_getvar_ptr ();
478- v_tomatrix (array, h, w);
479- // x0 x1 x2 (w=3,h=2)
480- // y0 rgba rgba rgba ypos=0
481- // y1 rgba rgba rgba ypos=12
482- //
483- for (unsigned y = 0 ; y < h; y++) {
484- unsigned yoffs = (y * w * 4 );
485- for (unsigned x = 0 ; x < w; x++) {
486- uint8_t a, r, g, b;
487- GET_IMAGE_ARGB (image->_image , yoffs + (x * 4 ), a, r, g, b);
488- pixel_t px = v_get_argb_px (a, r, g, b);
489- unsigned pos = y * w + x;
490- v_setint (v_elem (array, pos), px);
491- }
492- }
493- saved = true ;
478+ case kwTYPE_STR:
479+ par_getstr (&str);
480+ if (!prog_error &&
481+ !encode_png_file (str.v .p .ptr , image->_image , w, h)) {
482+ saved = true ;
483+ }
484+ v_free (&str);
494485 break ;
495486 default :
496- v_init (&var);
497- eval (&var);
498- if (var.type == V_STR && !prog_error &&
499- !lodepng_encode32_file (var.v .p .ptr , image->_image , w, h)) {
487+ var = par_getvar_ptr ();
488+ if (var->type == V_STR && !prog_error &&
489+ !encode_png_file (var->v .p .ptr , image->_image , w, h)) {
500490 saved = true ;
501- }
502- v_free (&var);
503- break ;
491+ } else if (!prog_error) {
492+ uint32_t offsetLeft = map_get_int (self, IMG_OFFSET_LEFT, 0 );
493+ uint32_t offsetTop = map_get_int (self, IMG_OFFSET_TOP, 0 );
494+ uint32_t wClip = map_get_int (self, IMG_WIDTH, w);
495+ uint32_t hClip = map_get_int (self, IMG_HEIGHT, h);
496+
497+ if (offsetTop < h && offsetLeft < w) {
498+ if (offsetTop + hClip > h) {
499+ hClip = h - offsetTop;
500+ }
501+ if (offsetLeft + wClip > w) {
502+ wClip = w - offsetLeft;
503+ }
504+ v_tomatrix (var, hClip, wClip);
505+ // x0 x1 x2 (w=3,h=2)
506+ // y0 rgba rgba rgba ypos=0
507+ // y1 rgba rgba rgba ypos=12
508+ //
509+ for (unsigned y = offsetTop; y < offsetTop + hClip; y++) {
510+ unsigned yoffs = (y * w * 4 );
511+ for (unsigned x = offsetLeft; x < offsetLeft + wClip; x++) {
512+ uint8_t a, r, g, b;
513+ GET_IMAGE_ARGB (image->_image , yoffs + (x * 4 ), a, r, g, b);
514+ pixel_t px = v_get_argb_px (a, r, g, b);
515+ unsigned pos = (y - offsetTop ) * wClip + (x - offsetLeft);
516+ v_setint (v_elem (var, pos), px);
517+ }
518+ }
519+ } else {
520+ v_tomatrix (var, hClip, wClip);
521+ }
522+ saved = true ;
523+ }
504524 }
505525 }
506-
507526 if (!saved) {
508527 err_throw (ERR_IMAGE_SAVE);
509528 }
@@ -512,7 +531,7 @@ void cmd_image_save(var_s *self, var_s *) {
512531
513532//
514533// Reduces the size of the image
515- // arguments: left, top, right, bottom
534+ // arguments: left, top, width, height
516535//
517536// png.clip(10, 10, 10, 10)
518537//
@@ -521,12 +540,18 @@ void cmd_image_clip(var_s *self, var_s *) {
521540 int bid = map_get_int (self, IMG_BID, -1 );
522541 if (bid != -1 ) {
523542 ImageBuffer *image = get_image ((unsigned )bid);
524- var_int_t left, top, right, bottom;
525- if (image != nullptr && par_massget (" iiii" , &left, &top, &right, &bottom)) {
543+ var_int_t left, top, width, heigth;
544+ if (image != nullptr && par_massget (" iiii" , &left, &top, &width, &heigth)) {
545+ if (left < 0 ) {
546+ left = 0 ;
547+ }
548+ if (top < 0 ) {
549+ top = 0 ;
550+ }
526551 map_set_int (self, IMG_OFFSET_LEFT, left);
527552 map_set_int (self, IMG_OFFSET_TOP, top);
528- map_set_int (self, IMG_WIDTH, right );
529- map_set_int (self, IMG_HEIGHT, bottom );
553+ map_set_int (self, IMG_WIDTH, width );
554+ map_set_int (self, IMG_HEIGHT, heigth );
530555 }
531556 }
532557 }
0 commit comments