Exemplo n.º 1
0
static void
optimistic_palette_callback(unsigned num,rgba *pixels) {
  unsigned prev_size = paletteSize ;
  if( !palettify_row(pixels,num)  || paletteSize != prev_size )
    FatalUnexpected("Oops! Somehow the precomputed palette does not suffice "
                    "after all...");
  raw_callback(num,pixels);
}
Exemplo n.º 2
0
void *
xcfmalloc(size_t size)
{
    void *ptr = malloc(size);
    if( !ptr )
        FatalUnexpected(_("Out of memory"));
    return ptr ;
}
Exemplo n.º 3
0
FILE *
openout(const char *name)
{
    FILE *newfile ;
    if( strcmp(name,"-") == 0 )
        return stdout ;
    newfile = fopen(name,"wb") ;
    if( newfile == NULL )
        FatalUnexpected(_("!Cannot create file %s"),name);
    return newfile ;
}
Exemplo n.º 4
0
void
add_layer_request(struct FlattenSpec *spec, const char *layer)
{
    spec->layers = realloc(spec->layers,
                           sizeof(struct xcfLayer) * (1+spec->numLayers));
    if( spec->layers == NULL )
        FatalUnexpected(_("Out of memory"));
    spec->layers[spec->numLayers].name = layer ;
    spec->layers[spec->numLayers].mode = (GimpLayerModeEffects)-1 ;
    spec->layers[spec->numLayers].opacity = 9999 ;
    spec->layers[spec->numLayers].hasMask = -1 ;
    spec->numLayers++ ;
}
Exemplo n.º 5
0
void
closeout(FILE *f,const char *name)
{
    if( f == NULL )
        return ;
    if( fflush(f) == 0 ) {
        errno = 0 ;
        if( !ferror(f) ) {
            if( fclose(f) == 0 )
                return ;
        } else if( errno == 0 ) {
            /* Attempt to coax a valid errno out of the standard library,
             * following an idea by Bruno Haible
             * http://lists.gnu.org/archive/html/bug-gnulib/2003-09/msg00157.html
             */
            if( fputc('\0', f) != EOF &&
                    fflush(f) == 0 )
                errno = EIO ; /* Argh, everything succeeds. Just call it an I/O error */
        }
    }
    FatalUnexpected(_("!Error writing file %s"),name);
}
Exemplo n.º 6
0
static void
init_output(void)
{
  int bit_depth ;
  int color_type ;
  int invert_mono = 0 ;
  png_colorp pngpalette = NULL ;
  png_bytep ptrans = NULL ;
  
  outfile = openout(flatspec.output_filename);
  libpng = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                   png_voidp_NULL,
                                   my_error_callback,
                                   png_error_ptr_NULL);
  if( !libpng )
    FatalUnexpected(_("Couldn't initialize libpng library"));
  
  libpng2 = png_create_info_struct(libpng);
  if( !libpng2 )
    FatalUnexpected("Couldn't create PNG info structure");

  png_init_io(libpng,outfile);
  
  bit_depth = 8;
  switch( flatspec.out_color_mode ) {
  case COLOR_GRAY:
    if( flatspec.default_pixel == PERHAPS_ALPHA_CHANNEL ||
        flatspec.default_pixel == FORCE_ALPHA_CHANNEL )
      color_type = PNG_COLOR_TYPE_GRAY_ALPHA ;
    else
      color_type = PNG_COLOR_TYPE_GRAY ;
    break ;
  case COLOR_RGB:
    if( flatspec.default_pixel == PERHAPS_ALPHA_CHANNEL ||
        flatspec.default_pixel == FORCE_ALPHA_CHANNEL )
      color_type = PNG_COLOR_TYPE_RGB_ALPHA ;
    else
      color_type = PNG_COLOR_TYPE_RGB ;
    break ;
  case COLOR_INDEXED:
    if( paletteSize == 2 &&
        palette[0] == NEWALPHA(0,255) &&
        palette[1] == NEWALPHA(-1,255) ) {
      color_type = PNG_COLOR_TYPE_GRAY ;
      bit_depth = 1 ;
    } else if( paletteSize == 2 &&
               palette[0] == NEWALPHA(-1,255) &&
               palette[1] == NEWALPHA(0,255) ) {
      color_type = PNG_COLOR_TYPE_GRAY ;
      bit_depth = 1 ;
      invert_mono = 1 ;
    } else {
      unsigned i ;
      int need_trans = flatspec.default_pixel == FORCE_ALPHA_CHANNEL ;
      color_type = PNG_COLOR_TYPE_PALETTE ;
      pngpalette = xcfmalloc(paletteSize*sizeof(png_color)) ;
      ptrans = xcfmalloc(paletteSize);
      for(i = 0; i<paletteSize; i++ ) {
        pngpalette[i].red = 255 & (palette[i] >> RED_SHIFT);
        pngpalette[i].green = 255 & (palette[i] >> GREEN_SHIFT);
        pngpalette[i].blue = 255 & (palette[i] >> BLUE_SHIFT);
        if( (ptrans[i] = ALPHA(palette[i])) != 255 )
          need_trans = 1 ;
      }
      if( !need_trans ) {
        xcffree(ptrans);
        ptrans = NULL ;
      }
      if( paletteSize <= 2 )
        bit_depth = 1 ;
      else if( paletteSize <= 4 )
        bit_depth = 2 ;
      else if( paletteSize <= 16 )
        bit_depth = 4 ;
      else
        bit_depth = 8;
    }
    break ;
  default:
    FatalUnexpected("This can't happen (unknown out_color_mode)");
  }

  if( verboseFlag ) {
    fprintf(stderr,"Writing PNG: %s%s%s%s, %d bits",
            color_type & PNG_COLOR_MASK_COLOR ? _("color") : _("grayscale"),
            color_type & PNG_COLOR_MASK_PALETTE ? _("+palette") : "",
            color_type & PNG_COLOR_MASK_ALPHA ? _("+alpha") : "",
            ptrans || NULLALPHA(flatspec.default_pixel)
            ? _("+transparency") : "",
            bit_depth);
    if( pngpalette )
      fprintf(stderr,_(" (%d colors)"),paletteSize);
    fprintf(stderr,"\n");
  }
  
  png_set_IHDR(libpng,libpng2,flatspec.dim.width,flatspec.dim.height,
               bit_depth, color_type,
               PNG_INTERLACE_NONE,
               PNG_COMPRESSION_TYPE_DEFAULT,
               PNG_FILTER_TYPE_DEFAULT);

  if( invert_mono )
    png_set_invert_mono(libpng);
  
  if( pngpalette )
    png_set_PLTE(libpng,libpng2,pngpalette,paletteSize);
  if( ptrans )
    png_set_tRNS(libpng,libpng2,ptrans,paletteSize,NULL);
  else if ( !pngpalette &&
            NULLALPHA(flatspec.default_pixel) ) {
    static png_color_16 trans ;
    trans.gray =
      trans.red = 255 & (flatspec.default_pixel >> RED_SHIFT) ;
    trans.green = 255 & (flatspec.default_pixel >> GREEN_SHIFT) ;
    trans.blue = 255 & (flatspec.default_pixel >> BLUE_SHIFT) ;
    png_set_tRNS(libpng,libpng2,NULL,0,&trans);
  }

  /* png_set_text here */

  png_write_info(libpng,libpng2);

  if( bit_depth < 8 )
    png_set_packing(libpng);

  switch( color_type ) {
  case PNG_COLOR_TYPE_RGB:
  case PNG_COLOR_TYPE_RGBA:
#if (BLUE_SHIFT < RED_SHIFT) == !defined(WORDS_BIGENDIAN)
    png_set_bgr(libpng);
#endif
    if( color_type == PNG_COLOR_TYPE_RGB )
#if (ALPHA_SHIFT < RED_SHIFT) == !defined(WORDS_BIGENDIAN)
      png_set_filler(libpng,0,PNG_FILLER_BEFORE);
    else
      png_set_swap_alpha(libpng);
#else
    png_set_filler(libpng,0,PNG_FILLER_AFTER);
#endif
    break ;
  case PNG_COLOR_TYPE_GRAY:
    png_set_filler(libpng,0,PNG_FILLER_AFTER);
    break ;
  case PNG_COLOR_TYPE_GRAY_ALPHA:
  case PNG_COLOR_TYPE_PALETTE:
    break ;
  default:
    FatalUnexpected("This can't happen (unexpected png color_type)");
  }
}
Exemplo n.º 7
0
static void
my_error_callback(png_structp png_ptr, png_const_charp errormsg)
{
  FatalUnexpected(_("Libpng error '%s'"),errormsg);
}
Exemplo n.º 8
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 ;
}
Exemplo n.º 9
0
const char*
xcfString(uint32_t ptr,uint32_t *after)
{
  uint32_t length ;
  unsigned i ;
  ICONV_CONST char *utf8master ;
  
  xcfCheckspace(ptr,4,"(string length)");
  length = xcfL(ptr) ;
  ptr += 4 ;
  xcfCheckspace(ptr,length,"(string)");
  utf8master = (ICONV_CONST char*)(xcf_file+ptr) ;
  if( after ) *after = ptr + length ;
  if( length == 0 || utf8master[length-1] != 0 )
    FatalBadXCF("String at %" PRIX32 " not zero-terminated",ptr-4);
  length-- ;

  if( use_utf8 ) return utf8master ;

  /* We assume that the local character set includes ASCII...
   * Check if conversion is needed at all
   */
  for( i=0 ; ; i++ ) {
    if( i == length )
      return utf8master ; /* Only ASCII after all */
    if( utf8master[i] == 0 )
      FatalBadXCF("String at %" PRIX32 " has embedded zeroes",ptr-4);
    if( (int8_t) utf8master[i] < 0 )
      break ;
  }
#ifdef HAVE_ICONV
  {
    size_t targetsize = length+1 ;
    int sloppy_translation = 0 ;
    iconv_t cd = iconv_open("//TRANSLIT","UTF-8");
    if( cd == (iconv_t) -1 ) {
      cd = iconv_open("","UTF-8");
      sloppy_translation = 1 ;
    }
    if( cd == (iconv_t) -1 )
      iconv_close(cd) ; /* Give up; perhaps iconv doesn't know UTF-8 */
    else
      while(1) {
        char *buffer = xcfmalloc(targetsize) ;
        ICONV_CONST char *inbuf = utf8master ;
        char *outbuf = buffer ;
        size_t incount = length ;
        size_t outcount = targetsize ;
        while(1) { /* Loop for systems without //ICONV support */
          size_t result = iconv(cd,&inbuf,&incount,&outbuf,&outcount) ;
          if( result == (size_t)-1 && errno == EILSEQ &&
              sloppy_translation && outcount > 0 ) {
            *outbuf++ = '?' ;
            outcount-- ;
            while( (int8_t)*inbuf < 0 ) inbuf++, incount-- ;
            continue ;
          }
          if( result != (size_t)-1 ) {
            if( outcount == 0 )
              errno = E2BIG ;
            else {
              *outbuf = 0 ;
              iconv_close(cd) ;
              return buffer ;
            }
          }
          break ;
        }
        if( errno == EILSEQ || errno == EINVAL )
          FatalBadXCF("Bad UTF-8 encoding '%s' at %" PRIXPTR,
                      inbuf,(uintptr_t)((inbuf-utf8master)+ptr));
        if( errno == E2BIG ) {
          targetsize += 1+incount ;
          xcffree(buffer) ;
          continue ;
        }
        FatalUnexpected("!iconv on layer name at %"PRIX32,ptr);
      }
  }
#endif
  {
    static int warned = 0 ;
    if( !warned ) {
      fprintf(stderr,_("Warning: one or more layer names could not be\n"
                       "         translated to the local character set.\n"));
      warned = 1 ;
    }
  }
  return utf8master ;
}
Exemplo n.º 10
0
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 ;
}
Exemplo n.º 11
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) ;
  flatspec.out_color_mode = COLOR_BY_FILENAME ;
  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);
    case '@':
      /* Non-documented option for build-time test */
      suppress_byline = 1 ;
      break ;
    case '#':
      /* Non-documented option for xcfview */
      flatspec.default_pixel = CHECKERED_BACKGROUND ;
      break ;
    default:
      FatalUnexpected("Getopt(_long) unexpectedly returned '%c'",option);
    }
  if( infile == NULL ) {
    usage(stderr);
  }

  if( flatspec.out_color_mode == COLOR_BY_FILENAME &&
      strlen(flatspec.output_filename) > 4 &&
      flatspec.output_filename[strlen(flatspec.output_filename)-4] == '.' )
    flatspec.out_color_mode = guess_color_mode(flatspec.output_filename);

  /* If the output filename was not enough cue, see if we're running
   * through a symlink/hardlink that gives the required output format
   */
  if( flatspec.out_color_mode == COLOR_BY_FILENAME &&
      strlen(progname) > 3 )
    flatspec.out_color_mode = guess_color_mode(progname);
  
  if( flatspec.out_color_mode == COLOR_BY_FILENAME )
    flatspec.out_color_mode = COLOR_BY_CONTENTS ;
  
  read_or_mmap_xcf(infile,unzipper);
  getBasicXcfInfo() ;
  initColormap();
 
  complete_flatspec(&flatspec,NULL);
  if( flatspec.process_in_memory ) {
    rgba **allPixels = flattenAll(&flatspec);
    analyse_colormode(&flatspec,allPixels,NULL);
    shipoutWithCallback(&flatspec,allPixels,selectCallback());
  } else {
    flattenIncrementally(&flatspec,selectCallback());
  }
  closeout(outfile,flatspec.output_filename) ;
  closeout(transfile,flatspec.transmap_filename) ;
  return 0 ;
}