Beispiel #1
0
static void
callback_common(unsigned num,rgba *pixels)
{
  if( flatspec.transmap_filename ) {
    if( flatspec.partial_transparency_mode == ALLOW_PARTIAL_TRANSPARENCY ) {
      unsigned i ;
      if( transfile == NULL ) start_writing(&transfile,5);
      for( i=0; i < num; i++ )
        putc( ALPHA(pixels[i]), transfile );
    } else {
      if( transfile == NULL ) {
        start_writing(&transfile,4);
      }
      /* Partial transparency should have been caught in the flattener,
       * so just extract a single byte.
       */
      put_pbm_row(transfile,num,pixels,(rgba)1 << ALPHA_SHIFT);
    }
  } else if( ALPHA(flatspec.default_pixel) < 128 ) {
    unsigned i ;
    for( i=0; i < num; i++ )
      if( !FULLALPHA(pixels[i]) )
        FatalGeneric(100,_("Transparency found, but -a option not given"));
  }
  xcffree(pixels) ;
}
Beispiel #2
0
static enum out_color_mode
guessIndexed(struct FlattenSpec *spec,rgba *allPixels[])
{
  if( allPixels == NULL ) {
    if (spec->gimpish_indexed && colormapLength ) {
      unsigned i ;
      init_palette_hash();
      for( i=0; i<colormapLength; i++ )
        lookup_or_intern(NEWALPHA(colormap[i],255));
      if( lookup_or_intern( FULLALPHA(spec->default_pixel) ?
                            spec->default_pixel : 0 ) >= 0 )
        return COLOR_INDEXED ;
    }
  } else {
    init_palette_hash() ;
    if( palettify_rows(allPixels,spec->dim.width,spec->dim.height) ) {
      /* Might grayscale sometimes be preferred? No, that is what
       * -g is for! */
      return COLOR_INDEXED ;
    }
  }
  return COLOR_BY_CONTENTS ;
}
Beispiel #3
0
int
main(int argc,char **argv)
{
  int option ;
  const char *unzipper = NULL ;
  const char *infile = NULL ;

  setlocale(LC_ALL,"");
  progname = argv[0] ;
  nls_init();

  if( argc <= 1 ) gpl_blurb() ;
  
  init_flatspec(&flatspec) ;
  while( (option=getopt_long(argc,argv,"-"OPTSTRING,longopts,NULL)) >= 0 )
    switch(option) {
      #define OPTION(char,long,desc,man) case char:
      #include "options.i"
    case 1:
      if( infile ) 
        add_layer_request(&flatspec,optarg);
      else
        infile = optarg ;
      break ;
    case '?':
      usage(stderr);
    default:
      FatalUnexpected("Getopt(_long) unexpectedly returned '%c'",option);
    }
  if( infile == NULL ) {
    usage(stderr);
  }
  
  read_or_mmap_xcf(infile,unzipper);
  getBasicXcfInfo() ;
  initColormap();
 
  complete_flatspec(&flatspec,guessIndexed);
  if( flatspec.process_in_memory ) {
    rgba **allPixels = flattenAll(&flatspec);
     
    analyse_colormode(&flatspec,allPixels,guessIndexed);

    /* See if we can do alpha compaction.
     */
    if( flatspec.partial_transparency_mode != ALLOW_PARTIAL_TRANSPARENCY &&
        !FULLALPHA(flatspec.default_pixel) &&
        flatspec.out_color_mode != COLOR_INDEXED ) {
      rgba unused = findUnusedColor(allPixels,
                                    flatspec.dim.width,
                                    flatspec.dim.height);
      if( unused && (flatspec.out_color_mode == COLOR_RGB ||
                     degrayPixel(unused) >= 0) ) {
        unsigned x,y ;
        unused = NEWALPHA(unused,0) ;
        for( y=0; y<flatspec.dim.height; y++)
          for( x=0; x<flatspec.dim.width; x++)
            if( allPixels[y][x] == 0 )
              allPixels[y][x] = unused ;
        flatspec.default_pixel = unused ;
      }
    }
    shipoutWithCallback(&flatspec,allPixels,selectCallback());
  } else {
    flattenIncrementally(&flatspec,selectCallback());
  }
  if( libpng ) {
    png_write_end(libpng,libpng2);
    png_destroy_write_struct(&libpng,&libpng2);
  }
  if( outfile ) {
    closeout(outfile,flatspec.output_filename);
  }
  return 0 ;
}
void
analyse_colormode(struct FlattenSpec *spec,rgba **allPixels,
                  guesser guess_callback)
{
    unsigned x,y ;
    int status ;
    /* 8 - looking for any transparency
     * 4 - looking for partially transparent pixels
     * 2 - looking for pixels other than black and white
     * 1 - looking for colored pixels
     */
    int known_absent = 0 ;
    int assume_present = 0 ;

    if( spec->out_color_mode == COLOR_BY_CONTENTS && guess_callback )
        spec->out_color_mode = guess_callback(spec,allPixels) ;

    if( spec->out_color_mode == COLOR_RGB     ) assume_present |= 3 ;
    if( spec->out_color_mode == COLOR_INDEXED ) assume_present |= 3 ;
    if( spec->out_color_mode == COLOR_GRAY    ) assume_present |= 2 ;
    switch( color_by_layers(spec) ) {
    case COLOR_GRAY:
        known_absent |= 1 ;
        break ;
    case COLOR_MONO:
        known_absent |= 3 ;
        break ;
    default:
        break ;
    }
    if( spec->partial_transparency_mode == DISSOLVE_PARTIAL_TRANSPARENCY ||
            spec->partial_transparency_mode == PARTIAL_TRANSPARENCY_IMPOSSIBLE )
        known_absent |= 4 ;
    if( ALPHA(spec->default_pixel) >= 128 )               known_absent |= 12 ;
    else if( spec->default_pixel == FORCE_ALPHA_CHANNEL ) assume_present |= 8 ;

    status = 15 - (known_absent | assume_present) ;

    for( y=0; status && y<spec->dim.height; y++ ) {
        rgba *row = allPixels[y] ;
        if( (status & 3) != 0 ) {
            /* We're still interested in color */
            for( x=0; status && x<spec->dim.width; x++ ) {
                if( NULLALPHA(row[x]) )
                    status &= ~8 ;
                else {
                    rgba full = row[x] | (255 << ALPHA_SHIFT) ;
                    if( !FULLALPHA(row[x]) ) status &= ~12 ;
                    if( full == NEWALPHA(0,255) || full == NEWALPHA(-1,255) )
                        /* Black or white */ ;
                    else if( degrayPixel(row[x]) != -1 )
                        status &= ~2 ; /* gray */
                    else
                        status &= ~3 ; /* color */
                }
            }
        } else {
            /* Not interested in color */
            for( x=0; status && x<spec->dim.width; x++ ) {
                if( NULLALPHA(row[x]) )
                    status &= ~8 ;
                else if( !FULLALPHA(row[x]) )
                    status &= ~12 ;
            }
        }
    }

    status |= known_absent ;

    switch( spec->out_color_mode ) {
    case COLOR_INDEXED: /* The caller takes responsibility */
    case COLOR_RGB: /* Everything is fine. */
        break ;
    case COLOR_GRAY:
        if( (status & 1) == 0 )
            FatalGeneric(103,
                         _("Grayscale output selected, but colored pixel(s) found"));
        break ;
    case COLOR_MONO:
        if( (status & 2) == 0 )
            FatalGeneric(103,_("Monochrome output selected, but not all pixels "
                               "are black or white"));
        break ;
    case COLOR_BY_FILENAME: /* Should not happen ... */
    case COLOR_BY_CONTENTS:
        if( (status & 1) == 0 )
            spec->out_color_mode = COLOR_RGB ;
        else if( (status & 2) == 0 )
            spec->out_color_mode = COLOR_GRAY ;
        else
            spec->out_color_mode = COLOR_MONO ;
        break ;
    }

    if( (status & 12) == 12 ) /* No transparency found */
        spec->default_pixel = NEWALPHA(colormap[0],255);
    else if( (status & 12) == 4 )
        spec->partial_transparency_mode = PARTIAL_TRANSPARENCY_IMPOSSIBLE ;
}