@@ -302,6 +302,153 @@ static const twin_src_msk_op comp3[2][4][4][3] = {
302
302
#define operand_index (o ) \
303
303
((o)->source_kind == TWIN_SOLID ? 3 : o->u.pixmap->format)
304
304
305
+ #define _twin_add_ARGB (s , d , i , t ) (((t) = (s) + twin_get_8(d, i)))
306
+ #define _twin_add (s , d , t ) (((t) = (s) + (d)))
307
+ #define _twin_div (d , den , i , t ) \
308
+ (((t) = (d) / (den)), (t) = twin_get_8((t), 0), \
309
+ (twin_argb32_t) twin_sat(t) << (i))
310
+ #define _twin_sub_ARGB (s , d , i , t ) (((t) = (s) - twin_get_8(d, i)))
311
+ #define _twin_sub (s , d , t ) (((t) = (s) - (d)))
312
+ #define twin_put_8 (d , i , t ) (((t) = (d) << (i)))
313
+
314
+ #define min (x , y ) \
315
+ ({ \
316
+ typeof(x) _x = (x); \
317
+ typeof(y) _y = (y); \
318
+ (void) (&_x == &_y); \
319
+ _x < _y ? _x : _y; \
320
+ })
321
+ #define max (x , y ) \
322
+ ({ \
323
+ typeof(x) _x = (x); \
324
+ typeof(y) _y = (y); \
325
+ (void) (&_x == &_y); \
326
+ _x > _y ? _x : _y; \
327
+ })
328
+
329
+ void twin_stack (twin_pixmap_t * trg_px ,
330
+ twin_pixmap_t * src_px ,
331
+ int radius ,
332
+ int first_str ,
333
+ int first_end ,
334
+ int second_str ,
335
+ int second_end ,
336
+ bool horiz_span )
337
+ {
338
+ int den = (radius + 1 ) * (radius + 1 );
339
+ twin_pointer_t src_ptr , trg_ptr , old_ptr , new_ptr ;
340
+ twin_argb32_t sumInR , sumOutR , sumR , sumInG , sumOutG , sumG , sumInB , sumOutB ,
341
+ sumB , _cur , _old , _new , _src ;
342
+ uint16_t t1 , t2 , t3 ;
343
+ for (int first = first_str ; first < first_end ; first ++ ) {
344
+ sumInR = sumOutR = sumR = sumInG = sumOutG = sumG = sumInB = sumOutB =
345
+ sumB = 0x00000000 ;
346
+
347
+ /* Initialize SumOut by padding */
348
+ if (horiz_span )
349
+ src_ptr = twin_pixmap_pointer (src_px , second_str , first );
350
+ else
351
+ src_ptr = twin_pixmap_pointer (src_px , first , second_str );
352
+ _src = * src_ptr .argb32 ;
353
+
354
+ for (int i = second_str ; i < second_str + radius ; i ++ ) {
355
+ sumOutR = _twin_add_ARGB (sumOutR , _src , 0 , t1 );
356
+ sumOutG = _twin_add_ARGB (sumOutG , _src , 8 , t2 );
357
+ sumOutB = _twin_add_ARGB (sumOutB , _src , 16 , t3 );
358
+ for (int j = 0 ; j < (i - second_str ) + 1 ; j ++ ) {
359
+ sumR = _twin_add_ARGB (sumR , _src , 0 , t1 );
360
+ sumG = _twin_add_ARGB (sumG , _src , 8 , t2 );
361
+ sumB = _twin_add_ARGB (sumB , _src , 16 , t3 );
362
+ }
363
+ }
364
+
365
+ /* Initialize SumIn */
366
+ for (int i = second_str ; i < second_str + radius ; i ++ ) {
367
+ if (horiz_span )
368
+ src_ptr = twin_pixmap_pointer (src_px , i , first );
369
+ else
370
+ src_ptr = twin_pixmap_pointer (src_px , first , i );
371
+ _src = * src_ptr .argb32 ;
372
+ sumInR = _twin_add_ARGB (sumInR , _src , 0 , t1 );
373
+ sumInG = _twin_add_ARGB (sumInG , _src , 8 , t2 );
374
+ sumInB = _twin_add_ARGB (sumInB , _src , 16 , t3 );
375
+ for (int j = 0 ; j < radius - (i - second_str ); j ++ ) {
376
+ sumR = _twin_add_ARGB (sumR , _src , 0 , t1 );
377
+ sumG = _twin_add_ARGB (sumG , _src , 8 , t2 );
378
+ sumB = _twin_add_ARGB (sumB , _src , 16 , t3 );
379
+ }
380
+ }
381
+
382
+ for (int cur = second_str ; cur < second_end ; cur ++ ) {
383
+ if (horiz_span ) {
384
+ src_ptr = twin_pixmap_pointer (src_px , cur , first );
385
+ trg_ptr = twin_pixmap_pointer (trg_px , cur , first );
386
+ old_ptr = twin_pixmap_pointer (
387
+ src_px , max (cur - radius , second_str ), first );
388
+ new_ptr = twin_pixmap_pointer (
389
+ src_px , min (cur + radius , second_end - 1 ), first );
390
+ } else {
391
+ src_ptr = twin_pixmap_pointer (src_px , first , cur );
392
+ trg_ptr = twin_pixmap_pointer (trg_px , first , cur );
393
+ old_ptr = twin_pixmap_pointer (src_px , first ,
394
+ max (cur - radius , second_str ));
395
+ new_ptr = twin_pixmap_pointer (
396
+ src_px , first , min (cur + radius , second_end - 1 ));
397
+ }
398
+ _cur = * src_ptr .argb32 ;
399
+ _old = * old_ptr .argb32 ;
400
+ _new = * new_ptr .argb32 ;
401
+ /* STEP 1 : sum_out + current */
402
+ sumOutR = _twin_add_ARGB (sumOutR , _cur , 0 , t1 );
403
+ sumOutG = _twin_add_ARGB (sumOutG , _cur , 8 , t2 );
404
+ sumOutB = _twin_add_ARGB (sumOutB , _cur , 16 , t3 );
405
+ /* STEP 2 : sum_in + new */
406
+ sumInR = _twin_add_ARGB (sumInR , _new , 0 , t1 );
407
+ sumInG = _twin_add_ARGB (sumInG , _new , 8 , t2 );
408
+ sumInB = _twin_add_ARGB (sumInB , _new , 16 , t3 );
409
+ /* STEP 3 : sum + sum_in */
410
+ sumR = _twin_add (sumR , sumInR , t1 );
411
+ sumG = _twin_add (sumG , sumInG , t2 );
412
+ sumB = _twin_add (sumB , sumInB , t3 );
413
+ /* STEP 4 : sum / denominator */
414
+ * trg_ptr .argb32 =
415
+ (_twin_div (sumR , den , 0 , t1 ) | _twin_div (sumG , den , 8 , t2 ) |
416
+ _twin_div (sumB , den , 16 , t3 ) | (* src_ptr .argb32 & 0xff000000 ));
417
+ /* STEP 5 : sum - sum_out */
418
+ sumR = _twin_sub (sumR , sumOutR , t1 );
419
+ sumG = _twin_sub (sumG , sumOutG , t2 );
420
+ sumB = _twin_sub (sumB , sumOutB , t3 );
421
+ /* STEP 6 : sum_out - old */
422
+ sumOutR = _twin_sub_ARGB (sumOutR , _old , 0 , t1 );
423
+ sumOutG = _twin_sub_ARGB (sumOutG , _old , 8 , t2 );
424
+ sumOutB = _twin_sub_ARGB (sumOutB , _old , 16 , t3 );
425
+ /* STEP 7 : sum_in - current */
426
+ sumInR = _twin_sub_ARGB (sumInR , _cur , 0 , t1 );
427
+ sumInG = _twin_sub_ARGB (sumInG , _cur , 8 , t2 );
428
+ sumInB = _twin_sub_ARGB (sumInB , _cur , 16 , t3 );
429
+ }
430
+ }
431
+ }
432
+
433
+ void twin_stack_blur (twin_pixmap_t * px ,
434
+ int radius ,
435
+ twin_coord_t left ,
436
+ twin_coord_t right ,
437
+ twin_coord_t top ,
438
+ twin_coord_t bottom )
439
+ {
440
+ if (px -> format != TWIN_ARGB32 )
441
+ return ;
442
+ twin_pixmap_t * tmp_px =
443
+ twin_pixmap_create (px -> format , px -> width , px -> height );
444
+ memcpy (tmp_px -> p .v , px -> p .v ,
445
+ px -> width * px -> height * twin_bytes_per_pixel (px -> format ));
446
+ twin_stack (tmp_px , px , radius , top , bottom , left , right , true);
447
+ twin_stack (px , tmp_px , radius , left , right , top , bottom , false);
448
+ twin_pixmap_destroy (tmp_px );
449
+ return ;
450
+ }
451
+
305
452
/* FIXME: source clipping is busted */
306
453
static void _twin_composite_simple (twin_pixmap_t * dst ,
307
454
twin_coord_t dst_x ,
0 commit comments