@@ -384,66 +384,114 @@ ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::scaled(float sx, float sy) const
384
384
auto new_width = new_bitmap->physical_width ();
385
385
auto new_height = new_bitmap->physical_height ();
386
386
387
- // The interpolation goes out of bounds on the bottom- and right-most edges.
388
- // We handle those in two specialized loops not only to make them faster, but
389
- // also to avoid four branch checks for every pixel.
387
+ if (old_width == 1 && old_height == 1 ) {
388
+ new_bitmap->fill (get_pixel (0 , 0 ));
389
+ return new_bitmap;
390
+ }
391
+
392
+ if (old_width > 1 && old_height > 1 ) {
393
+ // The interpolation goes out of bounds on the bottom- and right-most edges.
394
+ // We handle those in two specialized loops not only to make them faster, but
395
+ // also to avoid four branch checks for every pixel.
396
+ for (int y = 0 ; y < new_height - 1 ; y++) {
397
+ for (int x = 0 ; x < new_width - 1 ; x++) {
398
+ auto p = static_cast <float >(x) * static_cast <float >(old_width - 1 ) / static_cast <float >(new_width - 1 );
399
+ auto q = static_cast <float >(y) * static_cast <float >(old_height - 1 ) / static_cast <float >(new_height - 1 );
400
+
401
+ int i = floorf (p);
402
+ int j = floorf (q);
403
+ float u = p - static_cast <float >(i);
404
+ float v = q - static_cast <float >(j);
405
+
406
+ auto a = get_pixel (i, j);
407
+ auto b = get_pixel (i + 1 , j);
408
+ auto c = get_pixel (i, j + 1 );
409
+ auto d = get_pixel (i + 1 , j + 1 );
410
+
411
+ auto e = a.mixed_with (b, u);
412
+ auto f = c.mixed_with (d, u);
413
+ auto color = e.mixed_with (f, v);
414
+ new_bitmap->set_pixel (x, y, color);
415
+ }
416
+ }
390
417
391
- for (int y = 0 ; y < new_height - 1 ; y++) {
418
+ // Bottom strip (excluding last pixel)
419
+ auto old_bottom_y = old_height - 1 ;
420
+ auto new_bottom_y = new_height - 1 ;
392
421
for (int x = 0 ; x < new_width - 1 ; x++) {
393
422
auto p = static_cast <float >(x) * static_cast <float >(old_width - 1 ) / static_cast <float >(new_width - 1 );
394
- auto q = static_cast <float >(y) * static_cast <float >(old_height - 1 ) / static_cast <float >(new_height - 1 );
395
423
396
424
int i = floorf (p);
397
- int j = floorf (q);
398
425
float u = p - static_cast <float >(i);
399
- float v = q - static_cast <float >(j);
400
-
401
- auto a = get_pixel (i, j);
402
- auto b = get_pixel (i + 1 , j);
403
- auto c = get_pixel (i, j + 1 );
404
- auto d = get_pixel (i + 1 , j + 1 );
405
426
406
- auto e = a. mixed_with (b, u );
407
- auto f = c. mixed_with (d, u );
408
- auto color = e .mixed_with (f, v );
409
- new_bitmap->set_pixel (x, y , color);
427
+ auto a = get_pixel (i, old_bottom_y );
428
+ auto b = get_pixel (i + 1 , old_bottom_y );
429
+ auto color = a .mixed_with (b, u );
430
+ new_bitmap->set_pixel (x, new_bottom_y , color);
410
431
}
411
- }
412
-
413
- // Bottom strip (excluding last pixel)
414
- auto old_bottom_y = old_height - 1 ;
415
- auto new_bottom_y = new_height - 1 ;
416
- for (int x = 0 ; x < new_width - 1 ; x++) {
417
- auto p = static_cast <float >(x) * static_cast <float >(old_width - 1 ) / static_cast <float >(new_width - 1 );
418
432
419
- int i = floorf (p);
420
- float u = p - static_cast <float >(i);
433
+ // Right strip (excluding last pixel)
434
+ auto old_right_x = old_width - 1 ;
435
+ auto new_right_x = new_width - 1 ;
436
+ for (int y = 0 ; y < new_height - 1 ; y++) {
437
+ auto q = static_cast <float >(y) * static_cast <float >(old_height - 1 ) / static_cast <float >(new_height - 1 );
421
438
422
- auto a = get_pixel (i, old_bottom_y);
423
- auto b = get_pixel (i + 1 , old_bottom_y);
424
- auto color = a.mixed_with (b, u);
425
- new_bitmap->set_pixel (x, new_bottom_y, color);
426
- }
439
+ int j = floorf (q);
440
+ float v = q - static_cast <float >(j);
427
441
428
- // Right strip (excluding last pixel)
429
- auto old_right_x = old_width - 1 ;
430
- auto new_right_x = new_width - 1 ;
431
- for (int y = 0 ; y < new_height - 1 ; y++) {
432
- auto q = static_cast <float >(y) * static_cast <float >(old_height - 1 ) / static_cast <float >(new_height - 1 );
442
+ auto c = get_pixel (old_right_x, j);
443
+ auto d = get_pixel (old_right_x, j + 1 );
433
444
434
- int j = floorf (q);
435
- float v = q - static_cast <float >(j);
445
+ auto color = c.mixed_with (d, v);
446
+ new_bitmap->set_pixel (new_right_x, y, color);
447
+ }
436
448
437
- auto c = get_pixel (old_right_x, j);
438
- auto d = get_pixel (old_right_x, j + 1 );
449
+ // Bottom-right pixel
450
+ new_bitmap->set_pixel (new_width - 1 , new_height - 1 , get_pixel (physical_width () - 1 , physical_height () - 1 ));
451
+ return new_bitmap;
452
+ } else if (old_height == 1 ) {
453
+ // Copy horizontal strip multiple times (excluding last pixel to out of bounds).
454
+ auto old_bottom_y = old_height - 1 ;
455
+ for (int x = 0 ; x < new_width - 1 ; x++) {
456
+ auto p = static_cast <float >(x) * static_cast <float >(old_width - 1 ) / static_cast <float >(new_width - 1 );
457
+ int i = floorf (p);
458
+ float u = p - static_cast <float >(i);
439
459
440
- auto color = c.mixed_with (d, v);
441
- new_bitmap->set_pixel (new_right_x, y, color);
442
- }
460
+ auto a = get_pixel (i, old_bottom_y);
461
+ auto b = get_pixel (i + 1 , old_bottom_y);
462
+ auto color = a.mixed_with (b, u);
463
+ for (int new_bottom_y = 0 ; new_bottom_y < new_height; new_bottom_y++) {
464
+ // Interpolate color only once and then copy into all columns.
465
+ new_bitmap->set_pixel (x, new_bottom_y, color);
466
+ }
467
+ }
468
+ for (int new_bottom_y = 0 ; new_bottom_y < new_height; new_bottom_y++) {
469
+ // Copy last pixel of horizontal strip
470
+ new_bitmap->set_pixel (new_width - 1 , new_bottom_y, get_pixel (physical_width () - 1 , old_bottom_y));
471
+ }
472
+ return new_bitmap;
473
+ } else if (old_width == 1 ) {
474
+ // Copy vertical strip multiple times (excluding last pixel to avoid out of bounds).
475
+ auto old_right_x = old_width - 1 ;
476
+ for (int y = 0 ; y < new_height - 1 ; y++) {
477
+ auto q = static_cast <float >(y) * static_cast <float >(old_height - 1 ) / static_cast <float >(new_height - 1 );
478
+ int j = floorf (q);
479
+ float v = q - static_cast <float >(j);
443
480
444
- // Bottom-right pixel
445
- new_bitmap-> set_pixel (new_width - 1 , new_height - 1 , get_pixel ( physical_width () - 1 , physical_height () - 1 ) );
481
+ auto c = get_pixel (old_right_x, j);
482
+ auto d = get_pixel (old_right_x, j + 1 );
446
483
484
+ auto color = c.mixed_with (d, v);
485
+ for (int new_right_x = 0 ; new_right_x < new_width; new_right_x++) {
486
+ // Interpolate color only once and copy into all rows.
487
+ new_bitmap->set_pixel (new_right_x, y, color);
488
+ }
489
+ }
490
+ for (int new_right_x = 0 ; new_right_x < new_width; new_right_x++) {
491
+ // Copy last pixel of vertical strip
492
+ new_bitmap->set_pixel (new_right_x, new_height - 1 , get_pixel (old_right_x, physical_height () - 1 ));
493
+ }
494
+ }
447
495
return new_bitmap;
448
496
}
449
497
0 commit comments