7
7
//
8
8
// Copyright(C) 2002-2019 Chris Warren-Smith.
9
9
10
+ #include " common/sberr.h"
10
11
#include " common/sys.h"
11
12
#include " common/messages.h"
12
13
#include " common/pproc.h"
13
14
#include " common/fs_socket_client.h"
15
+ #include " include/var.h"
14
16
#include " lib/maapi.h"
15
17
#include " lib/lodepng/lodepng.h"
16
18
#include " ui/image.h"
17
19
#include " ui/system.h"
18
20
#include " ui/rgb.h"
21
+ #include < cstdint>
19
22
20
23
#define IMG_X " x"
21
24
#define IMG_Y " y"
@@ -211,9 +214,46 @@ ImageBuffer *get_image(unsigned bid) {
211
214
return result;
212
215
}
213
216
217
+ void scaleImage (ImageBuffer* image, var_num_t scaling) {
218
+ if (scaling == 1.0 || scaling <= 0.0 ) {
219
+ return ;
220
+ }
221
+
222
+ uint16_t xx, yy, w, h;
223
+ uint32_t offsetImage, offsetScaledImage;
224
+
225
+ w = round ((var_num_t )image->_width * scaling);
226
+ h = round ((var_num_t )image->_height * scaling);
227
+
228
+ uint8_t * scaledImage = (uint8_t *)malloc (w * h * 4 );
229
+ if (!scaledImage) {
230
+ err_throw (ERR_IMAGE_LOAD, " Failed to allocate RAM" );
231
+ }
232
+
233
+ uint32_t * image32bit = (uint32_t *)image->_image ;
234
+ uint32_t * scaledImage32bit = (uint32_t *)scaledImage;
235
+
236
+ for (yy = 0 ; yy < h; yy++) {
237
+ for (xx = 0 ; xx < w; xx++) {
238
+ offsetScaledImage = yy * w + xx;
239
+ offsetImage = floor ((var_num_t )yy / scaling) * image->_width + floor ((var_num_t )xx / scaling);
240
+ scaledImage32bit[offsetScaledImage] = image32bit[offsetImage];
241
+ }
242
+ }
243
+
244
+ free (image->_image );
245
+ image->_width = w;
246
+ image->_height = h;
247
+ image->_image = scaledImage;
248
+ }
249
+
250
+ //
251
+ // Copy from screen
252
+ //
214
253
ImageBuffer *load_image (var_int_t x) {
215
254
var_int_t y, w, h;
216
- int count = par_massget (" iii" , &y, &w, &h);
255
+ var_num_t scaling = 1.0 ;
256
+ int count = par_massget (" iiif" , &y, &w, &h, &scaling);
217
257
int width = g_system->getOutput ()->getWidth ();
218
258
int height = g_system->getOutput ()->getHeight ();
219
259
ImageBuffer *result = nullptr ;
@@ -238,49 +278,90 @@ ImageBuffer *load_image(var_int_t x) {
238
278
result->_height = h;
239
279
result->_filename = nullptr ;
240
280
result->_image = image;
281
+ scaleImage (result, scaling);
241
282
buffers.add (result);
242
283
}
243
284
}
244
285
return result;
245
286
}
246
287
288
+ //
247
289
// share image buffer from another image variable
290
+ //
248
291
ImageBuffer *load_image (var_t *var) {
249
292
ImageBuffer *result = nullptr ;
293
+ var_num_t scaling = 1.0 ;
294
+
295
+ if (code_peek () == kwTYPE_SEP) {
296
+ code_skipsep ();
297
+ scaling = par_getnum ();
298
+ }
299
+
250
300
if (var->type == V_MAP) {
251
301
int bid = map_get_int (var, IMG_BID, -1 );
252
302
if (bid != -1 ) {
253
- result = get_image ((unsigned )bid);
303
+ if (scaling == 1.0 || scaling <= 0.0 ) {
304
+ result = get_image ((unsigned )bid);
305
+ } else {
306
+ ImageBuffer *inputImage = nullptr ;
307
+ inputImage = get_image ((unsigned )bid);
308
+ uint8_t * imageData = (uint8_t *)malloc (inputImage->_width * inputImage->_height * 4 );
309
+ if (!imageData) {
310
+ err_throw (ERR_IMAGE_LOAD, " Failed to allocate RAM" );
311
+ }
312
+ result = new ImageBuffer;
313
+ result->_bid = ++nextId;
314
+ result->_width = inputImage->_width ;
315
+ result->_height = inputImage->_height ;
316
+ result->_filename = nullptr ;
317
+ memcpy (imageData, inputImage->_image , inputImage->_width * inputImage->_height * 4 );
318
+ result->_image = imageData;
319
+ scaleImage (result, scaling);
320
+ buffers.add (result);
321
+ }
254
322
}
255
323
} else if (var->type == V_ARRAY && v_maxdim (var) == 2 ) {
256
324
int h = ABS (v_ubound (var, 0 ) - v_lbound (var, 0 )) + 1 ;
257
325
int w = ABS (v_ubound (var, 1 ) - v_lbound (var, 1 )) + 1 ;
258
326
int size = w * h * 4 ;
259
- auto image = (uint8_t *)malloc (size);
327
+ auto imageData = (uint8_t *)malloc (size);
328
+ if (!imageData) {
329
+ err_throw (ERR_IMAGE_LOAD, " Failed to allocate RAM" );
330
+ }
260
331
for (int y = 0 ; y < h; y++) {
261
332
int yoffs = (y * w * 4 );
262
333
for (int x = 0 ; x < w; x++) {
263
334
int pos = y * w + x;
264
335
uint8_t a, r, g, b;
265
336
v_get_argb (v_getint (v_elem (var, pos)), a, r, g, b);
266
- SET_IMAGE_ARGB (image , yoffs + (x * 4 ), a, r, g, b);
337
+ SET_IMAGE_ARGB (imageData , yoffs + (x * 4 ), a, r, g, b);
267
338
}
268
339
}
269
340
result = new ImageBuffer ();
270
341
result->_bid = ++nextId;
271
342
result->_width = w;
272
343
result->_height = h;
273
344
result->_filename = nullptr ;
274
- result->_image = image;
345
+ result->_image = imageData;
346
+ scaleImage (result, scaling);
275
347
buffers.add (result);
276
348
}
277
349
return result;
278
350
}
279
351
352
+ //
353
+ // Load from file
354
+ //
280
355
ImageBuffer *load_image (const unsigned char *buffer, int32_t size) {
281
356
ImageBuffer *result = nullptr ;
282
357
unsigned w, h;
283
358
unsigned char *image;
359
+ var_num_t scaling = 1.0 ;
360
+
361
+ if (code_peek () == kwTYPE_SEP) {
362
+ code_skipsep ();
363
+ scaling = par_getnum ();
364
+ }
284
365
285
366
unsigned error = decode_png (&image, &w, &h, buffer, size);
286
367
if (!error) {
@@ -290,26 +371,38 @@ ImageBuffer *load_image(const unsigned char *buffer, int32_t size) {
290
371
result->_height = h;
291
372
result->_filename = nullptr ;
292
373
result->_image = image;
374
+ scaleImage (result, scaling);
293
375
buffers.add (result);
294
376
} else {
295
377
err_throw (ERR_IMAGE_LOAD, lodepng_error_text (error));
296
378
}
297
379
return result;
298
380
}
299
381
382
+ //
383
+ // Load from file
384
+ //
300
385
ImageBuffer *load_image (dev_file_t *filep) {
301
386
ImageBuffer *result = nullptr ;
302
- List_each (ImageBuffer *, it, buffers) {
303
- ImageBuffer *next = (*it);
304
- if (next->_filename != nullptr && strcmp (next->_filename , filep->name ) == 0 ) {
305
- result = next;
306
- break ;
307
- }
387
+ var_num_t scaling = 1.0 ;
388
+
389
+ if (code_peek () == kwTYPE_SEP) {
390
+ code_skipsep ();
391
+ scaling = par_getnum ();
308
392
}
309
393
394
+ if (scaling == 1.0 || scaling <= 0.0 ) {
395
+ List_each (ImageBuffer *, it, buffers) {
396
+ ImageBuffer *next = (*it);
397
+ if (next->_filename != nullptr && strcmp (next->_filename , filep->name ) == 0 ) {
398
+ result = next;
399
+ break ;
400
+ }
401
+ }
402
+ }
310
403
if (result == nullptr ) {
311
404
unsigned w, h;
312
- unsigned char *image ;
405
+ unsigned char *imageData ;
313
406
unsigned error = 0 ;
314
407
unsigned network_error = 0 ;
315
408
var_t *var_p;
@@ -322,13 +415,13 @@ ImageBuffer *load_image(dev_file_t *filep) {
322
415
} else {
323
416
var_p = v_new ();
324
417
http_read (filep, var_p);
325
- error = decode_png (&image , &w, &h, (unsigned char *)var_p->v .p .ptr , var_p->v .p .length );
418
+ error = decode_png (&imageData , &w, &h, (unsigned char *)var_p->v .p .ptr , var_p->v .p .length );
326
419
v_free (var_p);
327
420
v_detach (var_p);
328
421
}
329
422
break ;
330
423
case ft_stream:
331
- error = decode_png_file (&image , &w, &h, filep->name );
424
+ error = decode_png_file (&imageData , &w, &h, filep->name );
332
425
break ;
333
426
default :
334
427
error = 1 ;
@@ -344,25 +437,37 @@ ImageBuffer *load_image(dev_file_t *filep) {
344
437
result->_width = w;
345
438
result->_height = h;
346
439
result->_filename = strdup (filep->name );
347
- result->_image = image;
440
+ result->_image = imageData;
441
+ scaleImage (result, scaling);
348
442
buffers.add (result);
349
443
}
350
444
}
351
445
return result;
352
446
}
353
447
448
+ //
449
+ // Create from XPM data
450
+ //
354
451
ImageBuffer *load_xpm_image (char **data) {
355
452
unsigned w, h;
356
453
unsigned char *image;
357
454
unsigned error = xpm_decode32 (&image, &w, &h, data);
358
455
ImageBuffer *result = nullptr ;
456
+ var_num_t scaling = 1.0 ;
457
+
458
+ if (code_peek () == kwTYPE_SEP) {
459
+ code_skipsep ();
460
+ scaling = par_getnum ();
461
+ }
462
+
359
463
if (!error) {
360
464
result = new ImageBuffer ();
361
465
result->_bid = ++nextId;
362
466
result->_width = w;
363
467
result->_height = h;
364
468
result->_filename = nullptr ;
365
469
result->_image = image;
470
+ scaleImage (result, scaling);
366
471
buffers.add (result);
367
472
} else {
368
473
err_throw (ERR_IMAGE_LOAD, ERR_XPM_IMAGE);
@@ -480,7 +585,7 @@ void cmd_image_save(var_s *self, var_s *) {
480
585
if (!prog_error &&
481
586
!encode_png_file (str.v .p .ptr , image->_image , w, h)) {
482
587
saved = true ;
483
- }
588
+ }
484
589
v_free (&str);
485
590
break ;
486
591
default :
@@ -493,7 +598,7 @@ void cmd_image_save(var_s *self, var_s *) {
493
598
uint32_t offsetTop = map_get_int (self, IMG_OFFSET_TOP, 0 );
494
599
uint32_t wClip = map_get_int (self, IMG_WIDTH, w);
495
600
uint32_t hClip = map_get_int (self, IMG_HEIGHT, h);
496
-
601
+
497
602
if (offsetTop < h && offsetLeft < w) {
498
603
if (offsetTop + hClip > h) {
499
604
hClip = h - offsetTop;
@@ -512,15 +617,15 @@ void cmd_image_save(var_s *self, var_s *) {
512
617
uint8_t a, r, g, b;
513
618
GET_IMAGE_ARGB (image->_image , yoffs + (x * 4 ), a, r, g, b);
514
619
pixel_t px = v_get_argb_px (a, r, g, b);
515
- unsigned pos = (y - offsetTop ) * wClip + (x - offsetLeft);
620
+ unsigned pos = (y - offsetTop ) * wClip + (x - offsetLeft);
516
621
v_setint (v_elem (var, pos), px);
517
622
}
518
623
}
519
624
} else {
520
625
v_tomatrix (var, hClip, wClip);
521
626
}
522
627
saved = true ;
523
- }
628
+ }
524
629
}
525
630
}
526
631
if (!saved) {
@@ -659,22 +764,23 @@ extern "C" void v_create_image(var_p_t var) {
659
764
image = load_image (filep);
660
765
}
661
766
break ;
662
-
663
767
case kwTYPE_LINE:
664
768
case kwTYPE_EOC:
665
769
break ;
666
-
667
770
default :
668
771
v_init (&arg);
669
772
eval (&arg);
773
+
670
774
if (arg.type == V_STR && !prog_error) {
775
+ // Img = Image(FileName)
671
776
dev_file_t file;
672
777
strlcpy (file.name , arg.v .p .ptr , sizeof (file.name ));
673
778
file.type = ft_stream;
674
779
image = load_image (&file);
675
780
} else if (arg.type == V_ARRAY && v_asize (&arg) > 0 && !prog_error) {
676
781
var_p_t elem0 = v_elem (&arg, 0 );
677
782
if (elem0->type == V_STR) {
783
+ // Img = Image(PixmapData)
678
784
char **data = new char *[v_asize (&arg)];
679
785
for (unsigned i = 0 ; i < v_asize (&arg); i++) {
680
786
var_p_t elem = v_elem (&arg, i);
@@ -683,9 +789,10 @@ extern "C" void v_create_image(var_p_t var) {
683
789
image = load_xpm_image (data);
684
790
delete [] data;
685
791
} else if (v_maxdim (&arg) == 2 ) {
686
- // load from 2d array
792
+ // Img = Image(Array2D)
687
793
image = load_image (&arg);
688
794
} else if (elem0->type == V_INT) {
795
+ // Create from buffer?
689
796
auto *data = new unsigned char [v_asize (&arg)];
690
797
for (unsigned i = 0 ; i < v_asize (&arg); i++) {
691
798
var_p_t elem = v_elem (&arg, i);
@@ -695,8 +802,10 @@ extern "C" void v_create_image(var_p_t var) {
695
802
delete [] data;
696
803
}
697
804
} else if (arg.type == V_INT && !prog_error) {
805
+ // Copy from screen
698
806
image = load_image (arg.v .i );
699
807
} else {
808
+ // Img2 = image(Img1) -> Img2 is pointer to existing buffer Img1
700
809
image = load_image (&arg);
701
810
}
702
811
v_free (&arg);
0 commit comments