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); }
void * xcfmalloc(size_t size) { void *ptr = malloc(size); if( !ptr ) FatalUnexpected(_("Out of memory")); return ptr ; }
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 ; }
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++ ; }
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); }
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)"); } }
static void my_error_callback(png_structp png_ptr, png_const_charp errormsg) { FatalUnexpected(_("Libpng error '%s'"),errormsg); }
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 ; }
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 ; }
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 ; }
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 ; }