Krita Source Code Documentation
Loading...
Searching...
No Matches
flatten.c File Reference
#include "xcftools.h"
#include "flatten.h"
#include "pixels.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>

Go to the source code of this file.

Classes

struct  HSV
 

Macros

#define exotic_combinator   static inline unsigned __ATTRIBUTE__((const))
 
#define HEXTANT(b, m, t)
 
#define HEXTANT(b, m, t)
 
#define UNIFORM(mode)
 

Functions

static struct Tile__ATTRIBUTE__ ((noinline))
 
static rgba __ATTRIBUTE__ ((noinline, const))
 
static int addBackground (struct FlattenSpec *spec, struct Tile *tile, unsigned ncols)
 
static void collector (unsigned num, rgba *row)
 
static void dissolveTile (struct Tile *tile)
 
rgba ** flattenAll (struct FlattenSpec *spec)
 
int flattenIncrementally (struct FlattenSpec *spec, lineCallback callback)
 
static struct TileflattenTopdown (struct FlattenSpec *spec, struct Tile *top, unsigned nlayers, const struct rect *where)
 
static void RGBtoHSV (rgba rgb, struct HSV *hsv)
 
static void roundAlpha (struct Tile *tile)
 
void shipoutWithCallback (struct FlattenSpec *spec, rgba **pixels, lineCallback callback)
 
exotic_combinator ucombine_ADDITION (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_BURN (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_DARKEN_ONLY (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_DIFFERENCE (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_DIVIDE (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_DODGE (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_GRAIN_EXTRACT (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_GRAIN_MERGE (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_HARDLIGHT (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_LIGHTEN_ONLY (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_MULTIPLY (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_OVERLAY (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_SCREEN (uint8_t bot, uint8_t top)
 
exotic_combinator ucombine_SUBTRACT (uint8_t bot, uint8_t top)
 

Variables

static rgba ** collectPointer
 

Macro Definition Documentation

◆ exotic_combinator

#define exotic_combinator   static inline unsigned __ATTRIBUTE__((const))

Definition at line 122 of file flatten.c.

◆ HEXTANT [1/2]

#define HEXTANT ( b,
m,
t )
Value:
hsv->ch1 = b, hsv->ch2 = m, hsv->ch3 = t, \
hsv->hue = HUE_ ## b ## _ ## m ## _ ## t
#define _(s)
Definition xcftools.h:32

◆ HEXTANT [2/2]

#define HEXTANT ( b,
m,
t )
Value:
case HUE_ ## b ## _ ## m ## _ ## t : \
b = hsvBot.ch1; m = hsvBot.ch2; t = hsvBot.ch3; break;

◆ UNIFORM

#define UNIFORM ( mode)
Value:
case GIMP_ ## mode ## _MODE: \
RED = ucombine_ ## mode (bot->pixels[i]>>RED_SHIFT , \
top->pixels[i]>>RED_SHIFT ); \
GREEN = ucombine_ ## mode (bot->pixels[i]>>GREEN_SHIFT, \
top->pixels[i]>>GREEN_SHIFT); \
BLUE = ucombine_ ## mode (bot->pixels[i]>>BLUE_SHIFT , \
top->pixels[i]>>BLUE_SHIFT ); \
break ;
#define RED_SHIFT
Definition pixels.h:47
#define BLUE_SHIFT
Definition pixels.h:49
#define GREEN_SHIFT
Definition pixels.h:48

Function Documentation

◆ __ATTRIBUTE__() [1/2]

static int __ATTRIBUTE__ ( (noinline) )
static

Definition at line 76 of file flatten.c.

78{
79 unsigned i ;
81
82 /* See if there is an easy winner */
83 if( (bot->summary & TILESUMMARY_ALLNULL) ||
84 (top->summary & TILESUMMARY_ALLFULL) ) {
85 freeTile(bot);
86 return top ;
87 }
88 if( top->summary & TILESUMMARY_ALLNULL ) {
89 freeTile(top);
90 return bot ;
91 }
92
93 /* Try hard to make top win */
94 for( i=0; ; i++ ) {
95 if( i == top->count ) {
96 freeTile(bot);
97 return top ;
98 }
99 if( !(NULLALPHA(bot->pixels[i]) || FULLALPHA(top->pixels[i])) )
100 break ;
101 }
102
103 INIT_SCALETABLE_IF( !(top->summary & TILESUMMARY_CRISP) );
104
105 /* Otherwise bot wins, but is forever changed ... */
106 if( (top->summary & TILESUMMARY_ALLNULL) == 0 ) {
107 unsigned i ;
108 invalidateSummary(bot,0);
109 for( i=0 ; i < top->count ; i++ ) {
110 if( !NULLALPHA(top->pixels[i]) ) {
111 if( FULLALPHA(top->pixels[i]) || NULLALPHA(bot->pixels[i]) )
112 bot->pixels[i] = top->pixels[i] ;
113 else
114 bot->pixels[i] = composite_one(bot->pixels[i],top->pixels[i]);
115 }
116 }
117 }
118 freeTile(top);
119 return bot ;
120}
void freeTile(struct Tile *tile)
Definition pixels.c:255
#define TILESUMMARY_ALLNULL
Definition pixels.h:94
#define FULLALPHA(rgba)
Definition pixels.h:52
#define TILESUMMARY_CRISP
Definition pixels.h:96
#define TILESUMMARY_ALLFULL
Definition pixels.h:95
#define NULLALPHA(rgba)
Definition pixels.h:53
#define assertTileCompatibility(t1, t2)
Definition pixels.h:110
#define invalidateSummary(tile, mask)
Definition pixels.h:115
#define INIT_SCALETABLE_IF(foo)
Definition pixels.h:63

References assertTileCompatibility, Tile::count, freeTile(), FULLALPHA, INIT_SCALETABLE_IF, invalidateSummary, NULLALPHA, Tile::pixels, Tile::summary, TILESUMMARY_ALLFULL, TILESUMMARY_ALLNULL, and TILESUMMARY_CRISP.

◆ __ATTRIBUTE__() [2/2]

static rgba __ATTRIBUTE__ ( (noinline, const) )
static

Definition at line 26 of file flatten.c.

28{
29 unsigned tfrac, alpha ;
30
31 tfrac = ALPHA(top) ;
32 alpha = 255 ;
33 if( !FULLALPHA(bot) ) {
34 alpha = 255 ^ scaletable[255-ALPHA(bot)][255-ALPHA(top)] ;
35 /* This peculiar combination of ^ and - makes the GCC code
36 * generator for i386 particularly happy.
37 */
38 tfrac = (256*ALPHA(top) - 1) / alpha ;
39 /* Tfrac is the fraction of the coposited pixel's covered area
40 * that comes from the top pixel.
41 * For mathematical accuracy we ought to scale by 255 and
42 * subtract alpha/2, but this is faster, and never misses the
43 * true value by more than one 1/255. This effect is completely
44 * overshadowed by the linear interpolation in the first place.
45 * (I.e. gamma is ignored when combining intensities).
46 * [In any case, complete fairness is not possible: if the
47 * bottom pixel had alpha=170 and the top has alpha=102,
48 * each should contribute equally to the color of the
49 * resulting alpha=204 pixel, which is not possible in general]
50 * Subtracting one helps the topfrac never be 256, which would
51 * be bad.
52 * On the other hand it means that we would get tfrac=-1 if the
53 * top pixel is completely transparent, and we get a division
54 * by zero if _both_ pixels are fully transparent. These cases
55 * must be handled by all callers.
56 * More snooping in the Gimp sources reveal that it uses
57 * floating-point for its equivalent of tfrac when the
58 * bottom layer has an alpha channel. (alphify() macro
59 * in paint-funcs.c). What gives?
60 */
61 }
62 return (alpha << ALPHA_SHIFT)
63 + ((uint32_t)scaletable[ tfrac ][255&(top>>RED_SHIFT )] << RED_SHIFT )
64 + ((uint32_t)scaletable[ tfrac ][255&(top>>GREEN_SHIFT)] << GREEN_SHIFT )
65 + ((uint32_t)scaletable[ tfrac ][255&(top>>BLUE_SHIFT )] << BLUE_SHIFT )
66 + ((uint32_t)scaletable[255^tfrac][255&(bot>>RED_SHIFT )] << RED_SHIFT )
67 + ((uint32_t)scaletable[255^tfrac][255&(bot>>GREEN_SHIFT)] << GREEN_SHIFT )
68 + ((uint32_t)scaletable[255^tfrac][255&(bot>>BLUE_SHIFT )] << BLUE_SHIFT )
69 ;
70}
#define ALPHA_SHIFT
Definition pixels.h:46
#define ALPHA(rgba)
Definition pixels.h:51
uint8_t scaletable[256][256]
Definition scaletab.c:22

References ALPHA, ALPHA_SHIFT, BLUE_SHIFT, FULLALPHA, GREEN_SHIFT, RED_SHIFT, and scaletable.

◆ addBackground()

static int addBackground ( struct FlattenSpec * spec,
struct Tile * tile,
unsigned ncols )
static

Definition at line 589 of file flatten.c.

590{
591 unsigned i ;
592
593 if( tileSummary(tile) & TILESUMMARY_ALLFULL )
594 return XCF_OK;
595
596 switch( spec->partial_transparency_mode ) {
597 case FORBID_PARTIAL_TRANSPARENCY:
598 if( !(tileSummary(tile) & TILESUMMARY_CRISP) ) {
599 FatalGeneric(102,_("Flattened image has partially transparent pixels"));
600 return XCF_ERROR;
601 }
602 break ;
603 case DISSOLVE_PARTIAL_TRANSPARENCY:
604 dissolveTile(tile);
605 break ;
606 case ALLOW_PARTIAL_TRANSPARENCY:
607 case PARTIAL_TRANSPARENCY_IMPOSSIBLE:
608 break ;
609 }
610
611 if( spec->default_pixel == CHECKERED_BACKGROUND ) {
613 for( i=0; i<tile->count; i++ )
614 if( !FULLALPHA(tile->pixels[i]) ) {
615 rgba fillwith = ((i/ncols)^(i%ncols))&8 ? 0x66 : 0x99 ;
616 fillwith = graytable[fillwith] + (255 << ALPHA_SHIFT) ;
617 if( NULLALPHA(tile->pixels[i]) )
618 tile->pixels[i] = fillwith ;
619 else
620 tile->pixels[i] = composite_one(fillwith,tile->pixels[i]);
621 }
624 return XCF_OK;
625 }
626 if( !FULLALPHA(spec->default_pixel) ) return XCF_OK;
627 if( tileSummary(tile) & TILESUMMARY_ALLNULL ) {
628 fillTile(tile,spec->default_pixel);
629 } else {
631 for( i=0; i<tile->count; i++ )
632 if( NULLALPHA(tile->pixels[i]) )
633 tile->pixels[i] = spec->default_pixel ;
634 else if( FULLALPHA(tile->pixels[i]) )
635 ;
636 else
637 tile->pixels[i] = composite_one(spec->default_pixel,tile->pixels[i]);
638
641 }
642 return XCF_OK;
643}
static void dissolveTile(struct Tile *tile)
Definition flatten.c:433
#define CHECKERED_BACKGROUND
Definition flatten.h:27
summary_t tileSummary(struct Tile *tile)
Definition pixels.c:262
void fillTile(struct Tile *tile, rgba data)
Definition pixels.c:283
#define TILESUMMARY_UPTODATE
Definition pixels.h:93
uint32_t rgba
Definition pixels.h:44
const rgba graytable[256]
Definition table.c:6
rgba default_pixel
Definition flatten.h:30
enum FlattenSpec::@14 partial_transparency_mode
rgba pixels[TILE_WIDTH *TILE_HEIGHT]
Definition pixels.h:101
summary_t summary
Definition pixels.h:99
unsigned count
Definition pixels.h:100
void FatalGeneric(int status, const char *format,...)
Definition utils.c:46
#define XCF_OK
Definition xcftools.h:106
#define XCF_ERROR
Definition xcftools.h:105

References _, ALPHA_SHIFT, CHECKERED_BACKGROUND, Tile::count, FlattenSpec::default_pixel, dissolveTile(), FatalGeneric(), fillTile(), FULLALPHA, graytable, INIT_SCALETABLE_IF, NULLALPHA, FlattenSpec::partial_transparency_mode, Tile::pixels, Tile::summary, tileSummary(), TILESUMMARY_ALLFULL, TILESUMMARY_ALLNULL, TILESUMMARY_CRISP, TILESUMMARY_UPTODATE, XCF_ERROR, and XCF_OK.

◆ collector()

static void collector ( unsigned num,
rgba * row )
static

Definition at line 704 of file flatten.c.

705{
706 (void)num;
707 *collectPointer++ = row ;
708}
static rgba ** collectPointer
Definition flatten.c:701
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)

References collectPointer, and void().

◆ dissolveTile()

static void dissolveTile ( struct Tile * tile)
static

Definition at line 433 of file flatten.c.

434{
435 unsigned i ;
436 summary_t summary ;
437 assert( tile->refcount == 1 );
438 if( (tile->summary & TILESUMMARY_CRISP) )
439 return ;
442 for( i = 0 ; i < tile->count ; i++ ) {
443 if( FULLALPHA(tile->pixels[i]) )
444 summary &= ~TILESUMMARY_ALLNULL ;
445 else if ( NULLALPHA(tile->pixels[i]) )
446 summary &= ~TILESUMMARY_ALLFULL ;
447 else if( ALPHA(tile->pixels[i]) > rand() % 0xFF ) {
448 tile->pixels[i] |= 255 << ALPHA_SHIFT ;
449 summary &= ~TILESUMMARY_ALLNULL ;
450 } else {
451 tile->pixels[i] = 0 ;
452 summary &= ~TILESUMMARY_ALLFULL ;
453 }
454 }
455 tile->summary = summary ;
456}
int summary_t
Definition pixels.h:89
refcount_t refcount
Definition pixels.h:98

References ALPHA, ALPHA_SHIFT, Tile::count, FULLALPHA, NULLALPHA, Tile::pixels, Tile::refcount, Tile::summary, TILESUMMARY_ALLFULL, TILESUMMARY_ALLNULL, TILESUMMARY_CRISP, and TILESUMMARY_UPTODATE.

◆ flattenAll()

rgba ** flattenAll ( struct FlattenSpec * spec)

Definition at line 711 of file flatten.c.

712{
713 rgba **rows = xcfmalloc(spec->dim.height * sizeof(rgba*));
714 if( verboseFlag )
715 fprintf(stderr,_("Flattening image ..."));
716 collectPointer = rows ;
718 xcffree(rows);
720 return XCF_PTR_EMPTY;
721 }
722 if( verboseFlag )
723 fprintf(stderr,"\n");
724 return rows ;
725}
int flattenIncrementally(struct FlattenSpec *spec, lineCallback callback)
Definition flatten.c:646
static void collector(unsigned num, rgba *row)
Definition flatten.c:704
struct tileDimensions dim
Definition flatten.h:29
unsigned height
Definition xcftools.h:167
void * xcfmalloc(size_t size)
Definition utils.c:114
void xcffree(void *block)
Definition utils.c:125
int verboseFlag
Definition utils.c:26
#define XCF_PTR_EMPTY
Definition xcftools.h:107

References _, collector(), collectPointer, FlattenSpec::dim, flattenIncrementally(), tileDimensions::height, verboseFlag, XCF_OK, XCF_PTR_EMPTY, xcffree(), and xcfmalloc().

◆ flattenIncrementally()

int flattenIncrementally ( struct FlattenSpec * spec,
lineCallback callback )

Definition at line 646 of file flatten.c.

647{
648 rgba *rows[TILE_HEIGHT] ;
649 unsigned i, y, nrows, ncols ;
650 struct rect where ;
651 struct Tile *tile ;
652 static struct Tile toptile ;
653
654 toptile.count = TILE_HEIGHT * TILE_WIDTH ;
655 fillTile(&toptile,0);
656
657 for( where.t = spec->dim.c.t; where.t < spec->dim.c.b; where.t=where.b ) {
658 where.b = TILE_TOP(where.t)+TILE_HEIGHT ;
659 if( where.b > spec->dim.c.b ) where.b = spec->dim.c.b ;
660 nrows = where.b - where.t ;
661 for( y = 0; y < nrows ; y++ )
662 rows[y] = xcfmalloc(4*(spec->dim.c.r-spec->dim.c.l));
663
664 for( where.l = spec->dim.c.l; where.l < spec->dim.c.r; where.l=where.r ) {
665 where.r = TILE_LEFT(where.l)+TILE_WIDTH ;
666 if( where.r > spec->dim.c.r ) where.r = spec->dim.c.r ;
667 ncols = where.r - where.l ;
668
669 toptile.count = ncols * nrows ;
670 toptile.refcount = 2 ; /* For bug checking */
671 assert( toptile.summary == TILESUMMARY_UPTODATE +
673 tile = flattenTopdown(spec,&toptile,spec->numLayers,&where) ;
674 if (tile == XCF_PTR_EMPTY) {
675 return XCF_ERROR;
676 }
677 toptile.refcount-- ; /* addBackground may change destructively */
678 if (addBackground(spec,tile,ncols) != XCF_OK) {
679 return XCF_ERROR;
680 }
681
682 for( i = 0 ; i < tile->count ; i++ )
683 if( NULLALPHA(tile->pixels[i]) )
684 tile->pixels[i] = 0 ;
685 for( y = 0 ; y < nrows ; y++ )
686 memcpy(rows[y] + (where.l - spec->dim.c.l),
687 tile->pixels + y * ncols, ncols*4);
688
689 if( tile == &toptile ) {
690 fillTile(&toptile,0);
691 } else {
692 freeTile(tile);
693 }
694 }
695 for( y = 0 ; y < nrows ; y++ )
696 callback(spec->dim.width,rows[y]);
697 }
698 return XCF_OK;
699}
static struct Tile * flattenTopdown(struct FlattenSpec *spec, struct Tile *top, unsigned nlayers, const struct rect *where)
Definition flatten.c:484
static int addBackground(struct FlattenSpec *spec, struct Tile *tile, unsigned ncols)
Definition flatten.c:589
int numLayers
Definition flatten.h:31
Definition pixels.h:97
int l
Definition xcftools.h:130
int r
Definition xcftools.h:130
int t
Definition xcftools.h:130
int b
Definition xcftools.h:130
struct rect c
Definition xcftools.h:166
unsigned width
Definition xcftools.h:167
#define TILE_LEFT(x)
Definition xcftools.h:161
#define TILE_TOP(y)
Definition xcftools.h:162
#define TILE_HEIGHT
Definition xcftools.h:155
#define TILE_WIDTH
Definition xcftools.h:154

References addBackground(), rect::b, tileDimensions::c, Tile::count, FlattenSpec::dim, fillTile(), flattenTopdown(), freeTile(), rect::l, NULLALPHA, FlattenSpec::numLayers, Tile::pixels, rect::r, Tile::refcount, Tile::summary, rect::t, TILE_HEIGHT, TILE_LEFT, TILE_TOP, TILE_WIDTH, TILESUMMARY_ALLNULL, TILESUMMARY_CRISP, TILESUMMARY_UPTODATE, tileDimensions::width, XCF_ERROR, XCF_OK, XCF_PTR_EMPTY, and xcfmalloc().

◆ flattenTopdown()

static struct Tile * flattenTopdown ( struct FlattenSpec * spec,
struct Tile * top,
unsigned nlayers,
const struct rect * where )
static

Definition at line 484 of file flatten.c.

486{
487 struct Tile *tile = 0;
488
489 while( nlayers-- ) {
490 if( tileSummary(top) & TILESUMMARY_ALLFULL ) {
491 if (tile) {
492 /* it should always be not null here though */
493 freeTile(tile);
494 }
495 return top ;
496 }
497 if( !spec->layers[nlayers].isVisible )
498 continue ;
499
500 freeTile(tile);
501 tile = getLayerTile(&spec->layers[nlayers],where);
502 if (tile == XCF_PTR_EMPTY) {
503 return XCF_PTR_EMPTY;
504 }
505
506 if( tile->summary & TILESUMMARY_ALLNULL )
507 continue ; /* Simulate a tail call */
508
509 switch( spec->layers[nlayers].mode ) {
511 roundAlpha(tile) ;
512 /* Falls through */
514 dissolveTile(tile);
515 /* Falls through */
516 case GIMP_NORMAL_MODE:
517 top = merge_normal(tile,top);
518 break ;
519 default:
520 {
521 struct Tile *below, *above ;
522 unsigned i ;
523 if( !(top->summary & TILESUMMARY_ALLNULL) ) {
524 rgba tile_or = 0 ;
525 invalidateSummary(tile,0);
526 for( i=0; i<top->count; i++ )
527 if( FULLALPHA(top->pixels[i]) )
528 tile->pixels[i] = 0 ;
529 else
530 tile_or |= tile->pixels[i] ;
531 /* If the tile only has pixels that will be covered by 'top' anyway,
532 * forget it anyway.
533 */
534 if( ALPHA(tile_or) == 0 ) {
535 freeTile(tile);
536 break ; /* from the switch, which will continue the while */
537 }
538 }
539 /* Create a dummy top for the layers below this */
540 if( top->summary & TILESUMMARY_CRISP ) {
541 above = forkTile(top);
542 if(above == XCF_PTR_EMPTY) {
543 freeTile(tile);
544 return XCF_PTR_EMPTY;
545 }
546 } else {
548 above = newTile(*where);
549 for( i=0; i<top->count; i++ )
550 if( FULLALPHA(top->pixels[i]) ) {
551 above->pixels[i] = -1 ;
552 summary = 0 ;
553 } else
554 above->pixels[i] = 0 ;
556 }
557 below = flattenTopdown(spec, above, nlayers, where);
558 if (below == XCF_PTR_EMPTY) {
559 freeTile(tile);
560 return XCF_PTR_EMPTY;
561 }
562 if( below->refcount > 1 ) {
563 if (below != top) {
564 freeTile(tile);
565 return XCF_PTR_EMPTY;
566 }
567 /* This can only happen if 'below' is a copy of 'top'
568 * THROUGH 'above', which in turn means that none of all
569 * this is visible after all. So just free it and return 'top'.
570 */
571 freeTile(below);
572 freeTile(tile);
573 return top ;
574 }
575 if (merge_exotic(below,tile,spec->layers[nlayers].mode) != XCF_OK) {
576 return XCF_PTR_EMPTY;
577 }
578 freeTile(tile);
579 top = merge_normal(below,top);
580 return top ;
581 }
582 }
583 }
584 freeTile(tile);
585 return top ;
586}
@ GIMP_NORMAL_MODE
Definition enums.h:9
@ GIMP_DISSOLVE_MODE
Definition enums.h:10
@ GIMP_NORMAL_NOPARTIAL_MODE
Definition enums.h:35
static void roundAlpha(struct Tile *tile)
Definition flatten.c:459
struct Tile * getLayerTile(struct xcfLayer *layer, const struct rect *where)
Definition pixels.c:546
struct Tile * newTile(struct rect r)
Definition pixels.c:231
struct Tile * forkTile(struct Tile *tile)
Definition pixels.c:244
struct xcfLayer * layers
Definition flatten.h:32
int isVisible
Definition xcftools.h:186
GimpLayerModeEffects mode
Definition xcftools.h:183

References ALPHA, Tile::count, dissolveTile(), flattenTopdown(), forkTile(), freeTile(), FULLALPHA, getLayerTile(), GIMP_DISSOLVE_MODE, GIMP_NORMAL_MODE, GIMP_NORMAL_NOPARTIAL_MODE, invalidateSummary, xcfLayer::isVisible, FlattenSpec::layers, xcfLayer::mode, newTile(), Tile::pixels, Tile::refcount, roundAlpha(), Tile::summary, tileSummary(), TILESUMMARY_ALLFULL, TILESUMMARY_ALLNULL, TILESUMMARY_CRISP, TILESUMMARY_UPTODATE, XCF_OK, and XCF_PTR_EMPTY.

◆ RGBtoHSV()

static void RGBtoHSV ( rgba rgb,
struct HSV * hsv )
static

Definition at line 236 of file flatten.c.

237{
238 unsigned RED = (uint8_t)(rgb >> RED_SHIFT);
239 unsigned GREEN = (uint8_t)(rgb >> GREEN_SHIFT);
240 unsigned BLUE = (uint8_t)(rgb >> BLUE_SHIFT) ;
241#define HEXTANT(b,m,t) hsv->ch1 = b, hsv->ch2 = m, hsv->ch3 = t, \
242 hsv->hue = HUE_ ## b ## _ ## m ## _ ## t
243 if( GREEN <= RED )
244 if( BLUE <= RED )
245 if( GREEN <= BLUE )
246 HEXTANT(GREEN,BLUE,RED);
247 else
248 HEXTANT(BLUE,GREEN,RED);
249 else
250 HEXTANT(GREEN,RED,BLUE);
251 else if( BLUE <= RED )
252 HEXTANT(BLUE,RED,GREEN);
253 else if( BLUE <= GREEN )
254 HEXTANT(RED,BLUE,GREEN);
255 else
256 HEXTANT(RED,GREEN,BLUE);
257#undef HEXTANT
258}
#define HEXTANT(b, m, t)

References BLUE_SHIFT, GREEN_SHIFT, HEXTANT, and RED_SHIFT.

◆ roundAlpha()

static void roundAlpha ( struct Tile * tile)
static

Definition at line 459 of file flatten.c.

460{
461 unsigned i ;
462 summary_t summary ;
463 assert( tile->refcount == 1 );
464 if( (tile->summary & TILESUMMARY_CRISP) )
465 return ;
468 for( i = 0 ; i < tile->count ; i++ ) {
469 if( ALPHA(tile->pixels[i]) >= 128 ) {
470 tile->pixels[i] |= 255 << ALPHA_SHIFT ;
471 summary &= ~TILESUMMARY_ALLNULL ;
472 } else {
473 tile->pixels[i] = 0 ;
474 summary &= ~TILESUMMARY_ALLFULL ;
475 }
476 }
477 tile->summary = summary ;
478}

References ALPHA, ALPHA_SHIFT, Tile::count, Tile::pixels, Tile::refcount, Tile::summary, TILESUMMARY_ALLFULL, TILESUMMARY_ALLNULL, TILESUMMARY_CRISP, and TILESUMMARY_UPTODATE.

◆ shipoutWithCallback()

void shipoutWithCallback ( struct FlattenSpec * spec,
rgba ** pixels,
lineCallback callback )

Definition at line 728 of file flatten.c.

730{
731 unsigned i ;
732 for( i = 0; i < spec->dim.height; i++ ) {
733 callback(spec->dim.width,pixels[i]);
734 }
735 xcffree(pixels);
736}

References FlattenSpec::dim, tileDimensions::height, Tile::pixels, tileDimensions::width, and xcffree().

◆ ucombine_ADDITION()

exotic_combinator ucombine_ADDITION ( uint8_t bot,
uint8_t top )

Definition at line 127 of file flatten.c.

128{
129 return bot+top > 255 ? 255 : bot+top ;
130}

◆ ucombine_BURN()

exotic_combinator ucombine_BURN ( uint8_t bot,
uint8_t top )

Definition at line 198 of file flatten.c.

199{
200 return 255 - ucombine_DIVIDE(255-bot,top);
201}
exotic_combinator ucombine_DIVIDE(uint8_t bot, uint8_t top)
Definition flatten.c:163

References ucombine_DIVIDE().

◆ ucombine_DARKEN_ONLY()

exotic_combinator ucombine_DARKEN_ONLY ( uint8_t bot,
uint8_t top )

Definition at line 145 of file flatten.c.

146{
147 return top < bot ? top : bot ;
148}

◆ ucombine_DIFFERENCE()

exotic_combinator ucombine_DIFFERENCE ( uint8_t bot,
uint8_t top )

Definition at line 151 of file flatten.c.

152{
153 return top > bot ? top-bot : bot-top ;
154}

◆ ucombine_DIVIDE()

exotic_combinator ucombine_DIVIDE ( uint8_t bot,
uint8_t top )

Definition at line 163 of file flatten.c.

164{
165 int result = (int)bot*256 / (1+top) ;
166 return result >= 256 ? 255 : result ;
167}

◆ ucombine_DODGE()

exotic_combinator ucombine_DODGE ( uint8_t bot,
uint8_t top )

Definition at line 192 of file flatten.c.

193{
194 return ucombine_DIVIDE(bot,255-top);
195}

References ucombine_DIVIDE().

◆ ucombine_GRAIN_EXTRACT()

exotic_combinator ucombine_GRAIN_EXTRACT ( uint8_t bot,
uint8_t top )

Definition at line 216 of file flatten.c.

217{
218 int temp = (int)bot - (int)top + 128 ;
219 return temp < 0 ? 0 : temp >= 256 ? 255 : temp ;
220}

◆ ucombine_GRAIN_MERGE()

exotic_combinator ucombine_GRAIN_MERGE ( uint8_t bot,
uint8_t top )

Definition at line 223 of file flatten.c.

224{
225 int temp = (int)bot + (int)top - 128 ;
226 return temp < 0 ? 0 : temp >= 256 ? 255 : temp ;
227}

◆ ucombine_HARDLIGHT()

exotic_combinator ucombine_HARDLIGHT ( uint8_t bot,
uint8_t top )

Definition at line 204 of file flatten.c.

205{
206 if( top >= 128 )
207 return 255 ^ scaletable[255-bot][2*(255-top)] ;
208 else
209 return scaletable[bot][2*top];
210 /* The code that implements "hardlight" in Gimp 2.2.10 has some
211 * rounding errors, but this is undoubtedly what is meant.
212 */
213}

References scaletable.

◆ ucombine_LIGHTEN_ONLY()

exotic_combinator ucombine_LIGHTEN_ONLY ( uint8_t bot,
uint8_t top )

Definition at line 139 of file flatten.c.

140{
141 return top > bot ? top : bot ;
142}

◆ ucombine_MULTIPLY()

exotic_combinator ucombine_MULTIPLY ( uint8_t bot,
uint8_t top )

Definition at line 157 of file flatten.c.

158{
159 return scaletable[bot][top] ;
160}

References scaletable.

◆ ucombine_OVERLAY()

exotic_combinator ucombine_OVERLAY ( uint8_t bot,
uint8_t top )

Definition at line 177 of file flatten.c.

178{
179 return scaletable[bot][bot] +
180 2*scaletable[top][scaletable[bot][255-bot]] ;
181 /* This strange formula is equivalent to
182 * (1-top)*(bot^2) + top*(1-(1-top)^2)
183 * that is, the top value is used to interpolate between
184 * the self-multiply and the self-screen of the bottom.
185 */
186 /* Note: This is exactly what the "Soft light" effect also
187 * does, though with different code in the Gimp.
188 */
189}

References scaletable.

◆ ucombine_SCREEN()

exotic_combinator ucombine_SCREEN ( uint8_t bot,
uint8_t top )

Definition at line 170 of file flatten.c.

171{
172 /* An inverted version of "multiply" */
173 return 255 ^ scaletable[255-bot][255-top] ;
174}

References scaletable.

◆ ucombine_SUBTRACT()

exotic_combinator ucombine_SUBTRACT ( uint8_t bot,
uint8_t top )

Definition at line 133 of file flatten.c.

134{
135 return top>bot ? 0 : bot-top ;
136}

Variable Documentation

◆ collectPointer

rgba** collectPointer
static

Definition at line 701 of file flatten.c.