コード例 #1
0
ファイル: xcf2pnm.c プロジェクト: LocutusOfBorg/xcftools
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) ;
}
コード例 #2
0
struct xcfLayer *
lastlayerspec(struct FlattenSpec *spec,const char *option)
{
    if( spec->numLayers == 0 )
        FatalGeneric(20,_("The %s option must follow a layer name on the "
                          "command line"),option);
    return spec->layers + (spec->numLayers-1) ;
}
コード例 #3
0
ファイル: xcf2pnm.c プロジェクト: LocutusOfBorg/xcftools
static void
pbm_callback(unsigned num,rgba *pixels)
{
  if( outfile == NULL ) start_writing(&outfile,4);
  if( !put_pbm_row(outfile,num,pixels,
                   ((rgba)255 << RED_SHIFT) +
                   ((rgba)255 << GREEN_SHIFT) +
                   ((rgba)255 << BLUE_SHIFT)) )
    FatalGeneric(103,_("Monochrome output selected, but not all pixels "
                       "are black or white"));
  callback_common(num,pixels);
}
コード例 #4
0
ファイル: xcf2pnm.c プロジェクト: LocutusOfBorg/xcftools
static lineCallback
selectCallback(void)
{
  if( flatspec.transmap_filename && ALPHA(flatspec.default_pixel) >= 128 )
    FatalGeneric(101,_("The -a option was given, "
                       "but the image has no transparency"));
  
  switch( flatspec.out_color_mode ) {
  default:
  case COLOR_RGB: return &ppm_callback ;
  case COLOR_GRAY: return &pgm_callback ;
  case COLOR_MONO: return &pbm_callback ;
  }
}
コード例 #5
0
ファイル: xcf2pnm.c プロジェクト: LocutusOfBorg/xcftools
static void
pgm_callback(unsigned num,rgba *pixels)
{
  unsigned i ;
  if( outfile == NULL ) start_writing(&outfile,5);
  for( i=0; i < num; i++ ) {
    int gray = degrayPixel(pixels[i]) ;
    if( gray == -1 )
      FatalGeneric(103,
                   _("Grayscale output selected, but colored pixel(s) found"));
    putc( gray, outfile );
  }
  callback_common(num,pixels);
}
コード例 #6
0
ファイル: xcf2png.c プロジェクト: psineur/xcftools4mac
static void
graying_callback(unsigned num, rgba *pixels) {
  png_bytep fillptr = (uint8_t *)pixels ;
  unsigned i ;
  for( i = 0 ; i < num ; i++ ) {
    rgba pixel = pixels[i] ;
    int g = degrayPixel(pixel) ;
    if( g == -1 )
      FatalGeneric(103,
                   _("Grayscale output selected, but colored pixel(s) found"));
    *fillptr++ = g ;
    *fillptr++ = ALPHA(pixel) ;
  }
  raw_callback(num,pixels);
}
コード例 #7
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 ;
}
コード例 #8
0
void
complete_flatspec(struct FlattenSpec *spec, guesser guess_callback)
{
    unsigned i ;
    int anyPartial ;

    /* Find the layers to convert.
     */
    if( spec->numLayers == 0 ) {
        spec->layers = XCF.layers ;
        spec->numLayers = XCF.numLayers ;
    } else {
        for( i=0; i<spec->numLayers; i++ ) {
            GimpLayerModeEffects mode ;
            int opacity, hasMask ;
            unsigned j ;

            for( j=0; ; j++ ) {
                if( j == XCF.numLayers )
                    FatalGeneric(22,_("The image has no layer called '%s'"),
                                 spec->layers[i].name);
                if( strcmp(spec->layers[i].name,XCF.layers[j].name) == 0 )
                    break ;
            }
            mode = spec->layers[i].mode == (GimpLayerModeEffects)-1 ?
                   XCF.layers[j].mode : spec->layers[i].mode ;
            opacity = spec->layers[i].opacity == 9999 ?
                      XCF.layers[j].opacity : spec->layers[i].opacity ;
            hasMask = spec->layers[i].hasMask == -1 ?
                      XCF.layers[j].hasMask : spec->layers[i].hasMask ;
            if( hasMask && !XCF.layers[j].hasMask &&
                    XCF.layers[j].mask.hierarchy == 0 )
                FatalGeneric(22,_("Layer '%s' has no layer mask to enable"),
                             spec->layers[i].name);
            spec->layers[i] = XCF.layers[j] ;
            spec->layers[i].mode = mode ;
            spec->layers[i].opacity = opacity ;
            spec->layers[i].hasMask = hasMask ;
            spec->layers[i].isVisible = 1 ;
        }
    }

    /* Force the mode of the lowest visible layer to be Normal or Dissolve.
     * That may not be logical, but the Gimp does it
     */
    for( i=0; i < spec->numLayers; i++ ) {
        if( spec->layers[i].isVisible ) {
            if( spec->layers[i].mode != GIMP_DISSOLVE_MODE )
                spec->layers[i].mode = GIMP_NORMAL_MODE ;
            break ;
        }
    }

    /* Mimic the Gimp's behavior on indexed layers */
    if( XCF.type == GIMP_INDEXED && spec->gimpish_indexed ) {
        for( i=0; i<spec->numLayers; i++ )
            if( spec->layers[i].mode != GIMP_DISSOLVE_MODE )
                spec->layers[i].mode = GIMP_NORMAL_NOPARTIAL_MODE ;
    } else
        spec->gimpish_indexed = 0 ;

    /* compute dimensions of the window */
    if( spec->window_mode == AUTOCROP ) {
        int first = 1 ;
        for( i=0; i<spec->numLayers; i++ )
            if( spec->layers[i].isVisible ) {
                computeDimensions(&spec->layers[i].dim) ;
                if( first ) {
                    spec->dim = spec->layers[i].dim ;
                    first = 0 ;
                } else {
                    if( spec->dim.c.l < spec->layers[i].dim.c.l )
                        spec->dim.c.l = spec->layers[i].dim.c.l ;
                    if( spec->dim.c.r > spec->layers[i].dim.c.r )
                        spec->dim.c.r = spec->layers[i].dim.c.r ;
                    if( spec->dim.c.t < spec->layers[i].dim.c.t )
                        spec->dim.c.t = spec->layers[i].dim.c.t ;
                    if( spec->dim.c.b > spec->layers[i].dim.c.b )
                        spec->dim.c.b = spec->layers[i].dim.c.b ;
                }
            }
        if( first ) {
            spec->window_mode = USE_CANVAS ;
        } else {
            spec->dim.width = spec->dim.c.r - spec->dim.c.l ;
            spec->dim.height = spec->dim.c.b - spec->dim.c.t ;
        }
    }
    if( spec->window_mode != AUTOCROP ) {
        if( (spec->window_mode & MANUAL_OFFSET) == 0 )
            spec->dim.c.t = spec->dim.c.l = 0 ;
        if( (spec->window_mode & MANUAL_CROP) == 0 ) {
            spec->dim.height = XCF.height ;
            spec->dim.width = XCF.width ;
        }
    }
    computeDimensions(&spec->dim);

    /* We can't handle negative coordinates properly, so abort rather than
     * crash chaotically. See CVE-2009-217; Debian bug #533361.
     */
    if( spec->dim.c.t < 0 || spec->dim.c.l < 0 ) {
        FatalUnsupportedXCF("This version cannot extract pixels above or to the "
                            "left of the canvas");
    }

    /* Turn off layers that we don't hit at all */
    for( i=0; i<spec->numLayers; i++ )
        if( spec->layers[i].isVisible &&
                disjointRects(spec->dim.c,spec->layers[i].dim.c) )
            spec->layers[i].isVisible = 0 ;

    /* See if there is a completely covering layer somewhere in the stack */
    /* Also check if partial transparency is possible */
    anyPartial = 0 ;
    for( i=spec->numLayers; i-- ; ) {
        if( !spec->layers[i].isVisible )
            continue ;
        if( typeHasTransparency(spec->layers[i].type) ) {
            if( spec->layers[i].mode == GIMP_NORMAL_MODE )
                anyPartial = 1;
        } else if( isSubrect(spec->dim.c,spec->layers[i].dim.c) &&
                   (spec->layers[i].mode == GIMP_NORMAL_MODE ||
                    spec->layers[i].mode == GIMP_NORMAL_NOPARTIAL_MODE ||
                    spec->layers[i].mode == GIMP_DISSOLVE_MODE) ) {
            /* This layer fills out the entire image.
             * Turn off anly lower layers, and note that we cannot have
             * transparency at all.
             */
            while(i) spec->layers[--i].isVisible = 0 ;
            if( spec->default_pixel != FORCE_ALPHA_CHANNEL )
                spec->default_pixel = NEWALPHA(colormap[0],255);
            anyPartial = 0 ;
            break ;
        }
    }
    if( spec->partial_transparency_mode == ALLOW_PARTIAL_TRANSPARENCY &&
            (!anyPartial || ALPHA(spec->default_pixel) >= 128) )
        spec->partial_transparency_mode = PARTIAL_TRANSPARENCY_IMPOSSIBLE ;

    /* Initialize layers and print overview if we're verbose */
    for( i=spec->numLayers; i--; )
        if( spec->layers[i].isVisible ) {
            initLayer(&spec->layers[i]) ;
            if( verboseFlag ) {
                fprintf(stderr,"%dx%d%+d%+d %s %s",
                        spec->layers[i].dim.width, spec->layers[i].dim.height,
                        spec->layers[i].dim.c.l - spec->dim.c.l,
                        spec->layers[i].dim.c.t - spec->dim.c.t,
                        _(showGimpImageType(spec->layers[i].type)),
                        _(showGimpLayerModeEffects(spec->layers[i].mode)));
                if( spec->layers[i].opacity < 255 )
                    fprintf(stderr,"/%02d%%",spec->layers[i].opacity * 100 / 255);
                if( XCF.layers[i].hasMask )
                    fprintf(stderr,_("/mask"));
                fprintf(stderr," %s\n",spec->layers[i].name);
            }
        }

    /* Resolve color mode unless we wait until we have the entire image */
    if( spec->out_color_mode == COLOR_BY_CONTENTS &&
            !spec->process_in_memory ) {
        if( guess_callback )
            spec->out_color_mode = guess_callback(spec,NULL);
        if( spec->out_color_mode == COLOR_BY_CONTENTS )
            spec->out_color_mode = color_by_layers(spec) ;
    }
}
コード例 #9
0
ファイル: xcfinfo.c プロジェクト: LocutusOfBorg/xcftools
int
main(int argc,char **argv)
{
  int i ;
  int option ;
  const char *unzipper = NULL ;
  const char *infile = NULL ;
  const char *pathSeparator = "|";

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

  if( argc <= 1 ) gpl_blurb() ;

  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 ) {
        FatalGeneric
          (20,_("Only one XCF file per command line, please"));
      } 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() ;
  printf(_("Version %d, %dx%d %s, %d layers, compressed %s\n"),
         XCF.version,XCF.width,XCF.height,
         _(showGimpImageBaseType(XCF.type)),
         XCF.numLayers,
         _(showXcfCompressionType(XCF.compression)));
  for( i = XCF.numLayers ; i-- ; ) {
    printf("%c %dx%d%+d%+d %s %s",
           XCF.layers[i].isVisible ? '+' : '-',
           XCF.layers[i].dim.width, XCF.layers[i].dim.height,
           XCF.layers[i].dim.c.l, XCF.layers[i].dim.c.t,
           _(showGimpImageType(XCF.layers[i].type)),
           _(showGimpLayerModeEffects(XCF.layers[i].mode)));
    if( XCF.layers[i].opacity < 255 )
      printf("/%02d%%",XCF.layers[i].opacity * 100 / 255);
    if( XCF.layers[i].hasMask )
      printf(_("/mask"));
    if( XCF.layers[i].isGroup )
      printf(_("/group"));

    printf( " " );

    if ( XCF.version > 2 ) {
      printLayerPath( i, pathSeparator );
      printf( "%s", pathSeparator );
    }

    printf("%s\n",XCF.layers[i].name);
  }
      
  return 0 ;
}