29 unsigned tfrac, alpha ;
38 tfrac = (256*
ALPHA(top) - 1) / alpha ;
77merge_normal(
struct Tile *bot,
struct Tile *top)
95 if( i == top->
count ) {
109 for( i=0 ; i < top->
count ; i++ ) {
122#define exotic_combinator static inline unsigned __ATTRIBUTE__((const))
129 return bot+top > 255 ? 255 : bot+top ;
135 return top>bot ? 0 : bot-top ;
141 return top > bot ? top : bot ;
147 return top < bot ? top : bot ;
153 return top > bot ? top-bot : bot-top ;
165 int result = (int)bot*256 / (1+top) ;
166 return result >= 256 ? 255 : result ;
207 return 255 ^
scaletable[255-bot][2*(255-top)] ;
218 int temp = (int)bot - (
int)top + 128 ;
219 return temp < 0 ? 0 : temp >= 256 ? 255 : temp ;
225 int temp = (int)bot + (
int)top - 128 ;
226 return temp < 0 ? 0 : temp >= 256 ? 255 : temp ;
238 unsigned RED = (uint8_t)(rgb >>
RED_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
251 else if( BLUE <= RED )
253 else if( BLUE <= GREEN )
264merge_exotic(
struct Tile *bot,
const struct Tile *top,
276 for( i=0; i < top->
count ; i++ ) {
277 uint32_t RED, GREEN, BLUE ;
280#define UNIFORM(mode) case GIMP_ ## mode ## _MODE: \
281 RED = ucombine_ ## mode (bot->pixels[i]>>RED_SHIFT , \
282 top->pixels[i]>>RED_SHIFT ); \
283 GREEN = ucombine_ ## mode (bot->pixels[i]>>GREEN_SHIFT, \
284 top->pixels[i]>>GREEN_SHIFT); \
285 BLUE = ucombine_ ## mode (bot->pixels[i]>>BLUE_SHIFT , \
286 top->pixels[i]>>BLUE_SHIFT ); \
315 static struct HSV hsvTop, hsvBot ;
322 hsvBot.ch1 = (hsvBot.ch1*hsvTop.ch3 + hsvBot.ch3/2) / hsvBot.ch3;
323 hsvBot.ch2 = (hsvBot.ch2*hsvTop.ch3 + hsvBot.ch3/2) / hsvBot.ch3;
324 hsvBot.ch3 = hsvTop.ch3 ;
326 hsvBot.ch1 = hsvBot.ch2 = hsvBot.ch3 = hsvTop.ch3 ;
329 unsigned mfNum, mfDenom ;
331 mfNum = hsvTop.ch2-hsvTop.ch1 ;
332 mfDenom = hsvTop.ch3-hsvTop.ch1 ;
333 hsvBot.hue = hsvTop.hue ;
335 mfNum = hsvBot.ch2-hsvBot.ch1 ;
336 mfDenom = hsvBot.ch3-hsvBot.ch1 ;
339 if( hsvTop.ch3 == 0 )
340 hsvBot.ch1 = hsvBot.ch3 ;
342 hsvBot.ch1 = (hsvTop.ch1*hsvBot.ch3 + hsvTop.ch3/2) / hsvTop.ch3;
348 unsigned L = hsvTop.ch1 + hsvTop.ch3 ;
349 unsigned sNum = hsvTop.ch3 - hsvTop.ch1 ;
350 unsigned sDenom = L < 256 ? L : 510-L ;
351 if( sDenom == 0 ) sDenom = 1 ;
352 L = hsvBot.ch1 + hsvBot.ch3 ;
359 hsvBot.ch1 = (L*(sDenom-sNum)+sDenom-1)/(2*sDenom);
360 hsvBot.ch3 = L - hsvBot.ch1 ;
363 hsvBot.ch3 = 255 - ((510-L)*(sDenom-sNum)+sDenom-1)/(2*sDenom);
364 hsvBot.ch1 = L - hsvBot.ch3 ;
366 assert(hsvBot.ch3 <= 255);
367 assert(hsvBot.ch3 >= hsvBot.ch1);
370 hsvBot.ch2 = hsvBot.ch1 ;
372 hsvBot.ch2 = hsvBot.ch1 +
373 (mfNum*(hsvBot.ch3-hsvBot.ch1) + mfDenom/2) / mfDenom ;
375 switch( hsvBot.hue ) {
376#define HEXTANT(b,m,t) case HUE_ ## b ## _ ## m ## _ ## t : \
377 b = hsvBot.ch1; m = hsvBot.ch2; t = hsvBot.ch3; break;
416 unsigned pseudotop = (tfrac <
ALPHA(bp) ? tfrac :
ALPHA(bp));
418 tfrac = (256*pseudotop - 1) / alpha ;
442 for( i = 0 ; i < tile->
count ; i++ ) {
444 summary &= ~TILESUMMARY_ALLNULL ;
446 summary &= ~TILESUMMARY_ALLFULL ;
447 else if(
ALPHA(tile->
pixels[i]) > rand() % 0xFF ) {
449 summary &= ~TILESUMMARY_ALLNULL ;
452 summary &= ~TILESUMMARY_ALLFULL ;
468 for( i = 0 ; i < tile->
count ; i++ ) {
471 summary &= ~TILESUMMARY_ALLNULL ;
474 summary &= ~TILESUMMARY_ALLFULL ;
485 unsigned nlayers,
const struct rect *where)
487 struct Tile *tile = 0;
517 top = merge_normal(tile,top);
521 struct Tile *below, *above ;
526 for( i=0; i<top->
count; i++ )
530 tile_or |= tile->
pixels[i] ;
534 if(
ALPHA(tile_or) == 0 ) {
549 for( i=0; i<top->
count; i++ )
579 top = merge_normal(below,top);
597 case FORBID_PARTIAL_TRANSPARENCY:
599 FatalGeneric(102,
_(
"Flattened image has partially transparent pixels"));
603 case DISSOLVE_PARTIAL_TRANSPARENCY:
606 case ALLOW_PARTIAL_TRANSPARENCY:
607 case PARTIAL_TRANSPARENCY_IMPOSSIBLE:
613 for( i=0; i<tile->
count; i++ )
615 rgba fillwith = ((i/ncols)^(i%ncols))&8 ? 0x66 : 0x99 ;
618 tile->
pixels[i] = fillwith ;
620 tile->
pixels[i] = composite_one(fillwith,tile->
pixels[i]);
631 for( i=0; i<tile->
count; i++ )
649 unsigned i, y, nrows, ncols ;
652 static struct Tile toptile ;
657 for( where.
t = spec->
dim.
c.
t; where.
t < spec->
dim.
c.
b; where.
t=where.
b ) {
660 nrows = where.
b - where.
t ;
661 for( y = 0; y < nrows ; y++ )
664 for( where.
l = spec->
dim.
c.
l; where.
l < spec->
dim.
c.
r; where.
l=where.
r ) {
667 ncols = where.
r - where.
l ;
669 toptile.
count = ncols * nrows ;
682 for( i = 0 ; i < tile->
count ; i++ )
685 for( y = 0 ; y < nrows ; y++ )
686 memcpy(rows[y] + (where.
l - spec->
dim.
c.
l),
687 tile->
pixels + y * ncols, ncols*4);
689 if( tile == &toptile ) {
695 for( y = 0 ; y < nrows ; y++ )
715 fprintf(stderr,
_(
"Flattening image ..."));
723 fprintf(stderr,
"\n");
732 for( i = 0; i < spec->
dim.
height; i++ ) {
const char * showGimpLayerModeEffects(GimpLayerModeEffects x)
@ GIMP_NORMAL_NOPARTIAL_MODE
exotic_combinator ucombine_SCREEN(uint8_t bot, uint8_t top)
rgba ** flattenAll(struct FlattenSpec *spec)
static struct Tile * flattenTopdown(struct FlattenSpec *spec, struct Tile *top, unsigned nlayers, const struct rect *where)
exotic_combinator ucombine_DARKEN_ONLY(uint8_t bot, uint8_t top)
exotic_combinator ucombine_GRAIN_EXTRACT(uint8_t bot, uint8_t top)
exotic_combinator ucombine_DIFFERENCE(uint8_t bot, uint8_t top)
exotic_combinator ucombine_BURN(uint8_t bot, uint8_t top)
exotic_combinator ucombine_DODGE(uint8_t bot, uint8_t top)
exotic_combinator ucombine_ADDITION(uint8_t bot, uint8_t top)
exotic_combinator ucombine_HARDLIGHT(uint8_t bot, uint8_t top)
exotic_combinator ucombine_SUBTRACT(uint8_t bot, uint8_t top)
int flattenIncrementally(struct FlattenSpec *spec, lineCallback callback)
static void dissolveTile(struct Tile *tile)
exotic_combinator ucombine_OVERLAY(uint8_t bot, uint8_t top)
static void roundAlpha(struct Tile *tile)
static rgba ** collectPointer
void shipoutWithCallback(struct FlattenSpec *spec, rgba **pixels, lineCallback callback)
exotic_combinator ucombine_LIGHTEN_ONLY(uint8_t bot, uint8_t top)
exotic_combinator ucombine_GRAIN_MERGE(uint8_t bot, uint8_t top)
exotic_combinator ucombine_DIVIDE(uint8_t bot, uint8_t top)
static void RGBtoHSV(rgba rgb, struct HSV *hsv)
static int addBackground(struct FlattenSpec *spec, struct Tile *tile, unsigned ncols)
static void collector(unsigned num, rgba *row)
#define exotic_combinator
exotic_combinator ucombine_MULTIPLY(uint8_t bot, uint8_t top)
void(* lineCallback)(unsigned num, rgba *pixels)
#define CHECKERED_BACKGROUND
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
summary_t tileSummary(struct Tile *tile)
struct Tile * getLayerTile(struct xcfLayer *layer, const struct rect *where)
void freeTile(struct Tile *tile)
void fillTile(struct Tile *tile, rgba data)
struct Tile * newTile(struct rect r)
struct Tile * forkTile(struct Tile *tile)
#define TILESUMMARY_UPTODATE
#define TILESUMMARY_ALLNULL
#define TILESUMMARY_CRISP
#define TILESUMMARY_ALLFULL
const rgba graytable[256]
#define assertTileCompatibility(t1, t2)
uint8_t scaletable[256][256]
#define invalidateSummary(tile, mask)
#define INIT_SCALETABLE_IF(foo)
struct tileDimensions dim
enum FlattenSpec::@14 partial_transparency_mode
rgba pixels[TILE_WIDTH *TILE_HEIGHT]
GimpLayerModeEffects mode
void FatalUnsupportedXCF(const char *format,...)
void * xcfmalloc(size_t size)
void xcffree(void *block)
void FatalGeneric(int status, const char *format,...)
void FatalUnexpected(const char *format,...)