Skip to content

Instantly share code, notes, and snippets.

@psineur
Created March 24, 2011 23:27
Show Gist options
  • Save psineur/886100 to your computer and use it in GitHub Desktop.
Save psineur/886100 to your computer and use it in GitHub Desktop.
xcfinfo modification that i used to create sprites/tiles plist files for iTraceur
/* A program that extracts metadata from an XCF file
*
* This file was written by Henning Makholm <henning@makholm.net>
* It is hereby in the public domain.
*
* In jurisdictions that do not recognise grants of copyright to the
* public domain: I, the author and (presumably, in those jurisdictions)
* copyright holder, hereby permit anyone to distribute and use this code,
* in source code or binary form, with or without modifications. This
* permission is world-wide and irrevocable.
*
* Of course, I will not be liable for any errors or shortcomings in the
* code, since I give it away without asking any compenstations.
*
* If you use or distribute this code, I would appreciate receiving
* credit for writing it, in whichever way you find proper and customary.
*/
#include "xcftools.h"
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#if HAVE_GETOPT_H
#include <getopt.h>
#else
#include <unistd.h>
#endif
#ifndef HAVE_GETOPT_LONG
#define getopt_long(argc,argv,optstring,l1,l2) getopt(argc,argv,optstring)
#endif
#include "xcfinfo.oi"
int rectIntersects(int r1X, int r1Y, int r1W, int r1H,
int r2X, int r2Y, int r2W, int r2H );
static void
usage(FILE *where)
{
fprintf(where,_("Usage: %s [options] filename.xcf[.gz]\n"),progname) ;
fprintf(where,_("Options:\n"));
opt_usage(where) ;
if( where == stderr ) {
exit(1);
}
}
/*
int newZCalculation
{
pureZ[i] = 0;
int curLowerMaxZ = -1;
for ( j=0; j < i; ++j )
{
if ( rectIntersects( XCF.layers[i].dim.c.l, XCF.layers[i].dim.c.t, //нужно
XCF.layers[i].dim.width, XCF.layers[i].dim.height, //нужно
XCF.layers[j].dim.c.l, XCF.layers[j].dim.c.t, //нужно
XCF.layers[j].dim.width, XCF.layers[j].dim.height) ) //нужно
{
// diag info
//printf("INTERSECTION: %d+%d\n ZZZ = %d+%d\n",i, j, pureZ[i], pureZ[j]);
if ( pureZ[j] > curLowerMaxZ )
curLowerMaxZ = pureZ[j];
}
}
pureZ[i] = curLowerMaxZ + 1;
if (pureZ[i] > maxZ)
{
maxZ = pureZ[i];
}
}
int oldZCalculation
{
for ( j=0; j < i; ++j )
{
if ( rectIntersects( XCF.layers[i].dim.c.l, XCF.layers[i].dim.c.t, //нужно
XCF.layers[i].dim.width, XCF.layers[i].dim.height, //нужно
XCF.layers[j].dim.c.l, XCF.layers[j].dim.c.t, //нужно
XCF.layers[j].dim.width, XCF.layers[j].dim.height) ) //нужно
{
// diag info
//printf("INTERSECTION: %d+%d\n ZZZ = %d+%d\n",i, j, pureZ[i], pureZ[j]);
pureZ[i]++;
if ( pureZ[j] > pureZ[i] )
{
pureZ[i] = pureZ[j] + 1;
}
if ( pureZ[i] > maxZ )
maxZ = pureZ[i];
}
}
}*/
int getScaleXFromLayerName (const char *layerName)
{
if ( strstr(layerName, "scaleX=-1") )
{
return -1;
}
return 1; // only -1 paramater supported now
}
int getZFromLayerName(const char *layerName)
{
//char *foo = "-123mazafaka";
// int bar=-512;
// sscanf(foo,"%d", &bar);
//
// printf("bar = %d\n",bar);
//< дает -123 если не найдено - не изменяет bar
int z = -1;
char *zOptionString = strstr(layerName, "z=");
if (zOptionString)
{
zOptionString++;
zOptionString++;
sscanf(zOptionString, "%d", &z );
}
return z;
}
int getObjectTypeFromLayerName (const char *layerName)
{
int t = -1;
char *typeString = strstr(layerName, "object=");
if (typeString)
{
typeString++;
typeString++;
typeString++;
typeString++;
typeString++;
typeString++;
typeString++;
sscanf(typeString, "%d", &t );
}
return t;
}
int getBonusTypeFromLayerName (const char *layerName)
{
int b = -1;
char *typeString = strstr(layerName, "bonus=");
if (typeString)
{
typeString++;
typeString++;
typeString++;
typeString++;
typeString++;
typeString++;
sscanf(typeString, "%d", &b );
}
return b;
}
inline char *getImageNameFromLayerName( const char *layerName)
{
char *result;
int resultLength=0;
const char *curLayerName = layerName;
if ( strstr(curLayerName, ".png") )
{
result = strstr(curLayerName, ".png");
// go back to find the name of file
while ( ( *result != ' ') && ( result != layerName) )
{
result--;
resultLength++;
}
if ( *result == ' ' )
{
result++;
resultLength--;
}
}
else
{
return (char *)0;
}
char *imageName = malloc((resultLength+5)*sizeof(char));
memcpy(imageName, result, (resultLength +5) *sizeof(char));
imageName[resultLength+4] = 0;
return imageName;
}
int rectIntersects(int r1X, int r1Y, int r1W, int r1H,
int r2X, int r2Y, int r2W, int r2H )
{
int r1CenterX = r1X + r1W / 2;
int r1CenterY = r1Y + r1H / 2;
int r2CenterX = r2X + r2W / 2;
int r2CenterY = r2Y + r2H / 2;
if ( ( abs(r1CenterX - r2CenterX) <= ( r1W + r2W ) / 2.0f )
&& (abs(r1CenterY - r2CenterY) <= ( r1H + r2H ) / 2.0f) )
{
return 1;
}
return 0;
}
int
main(int argc,char **argv)
{
// printf("testing code compile update\n 1\n2\n");
int i;
char *imageName; //< current image name for cycle
int option ;
const char *unzipper = NULL ;
const char *infile = NULL ;
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() ;
// now we have all info in XCF shit
//XCF.layers[i].dim.width, XCF.layers[i].dim.height, //нужно
//XCF.layers[i].dim.c.l, XCF.layers[i].dim.c.t, //нужно
//,XCF.layers[i].name
//printf(_("Version %d, %dx%d %s, %d layers, compressed %s\n"),
// XCF.version,XCF.width,XCF.height,
// _(showGimpImageBaseType(XCF.type)),
// XCF.numLayers, // numbers of layers
// _(showXcfCompressionType(XCF.compression)));
printf(" \
<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\
<plist version=\"1.0\">\
<array>\
");
int maxZ = 0; //int curZ=0;
int j = 0;
int *pureZ = malloc( XCF.numLayers * sizeof(int));
for( i = 0 ; i < XCF.numLayers ; ++i )
{
imageName = getImageNameFromLayerName( XCF.layers[i].name );
if ( !imageName )
continue;
pureZ[i] = 0;
int curLowerMaxZ = -1;
for ( j=0; j < i; ++j )
{
if ( rectIntersects( XCF.layers[i].dim.c.l, XCF.layers[i].dim.c.t, //нужно
XCF.layers[i].dim.width, XCF.layers[i].dim.height, //нужно
XCF.layers[j].dim.c.l, XCF.layers[j].dim.c.t, //нужно
XCF.layers[j].dim.width, XCF.layers[j].dim.height) ) //нужно
{
// diag info
//printf("INTERSECTION: %d+%d\n ZZZ = %d+%d\n",i, j, pureZ[i], pureZ[j]);
if ( pureZ[j] > curLowerMaxZ )
curLowerMaxZ = pureZ[j];
}
}
pureZ[i] = curLowerMaxZ + 1;
int forcedZ = getZFromLayerName( XCF.layers[i].name );
if ( forcedZ >= 0)
{
pureZ[i] = forcedZ;
}
if (pureZ[i] > maxZ)
{
maxZ = pureZ[i];
}
if ( ( -1 == getBonusTypeFromLayerName(XCF.layers[i].name ) ) && ( -1 == getObjectTypeFromLayerName(XCF.layers[i].name ) ) )
printf("<dict>\
<key>spriteName</key>\
<string>%s</string>\
<key>x</key>\
<integer>%d</integer>\
<key>y</key>\
<integer>%d</integer>\
<key>width</key>\
<integer>%d</integer>\
<key>height</key>\
<integer>%d</integer>\
<key>z</key>\
<integer>%d</integer>\
<key>parallaxX</key>\
<integer>1</integer>\
<key>parallaxY</key>\
<integer>1</integer>\
<key>scaleX</key>\
<integer>%d</integer>\
</dict>",
imageName,
XCF.layers[i].dim.c.l, XCF.height - XCF.layers[j].dim.c.t - XCF.layers[i].dim.height,
XCF.layers[i].dim.width, XCF.layers[i].dim.height,
pureZ[i], getScaleXFromLayerName( XCF.layers[i].name )
);
}//< for layers
printf("</array></plist>");
// diagnostik info
//printf("maxZ=%d\n",maxZ);
//
// int z,l,c;
// for ( z = 0; z <= maxZ; ++z )
// {
// c = 0;
// for ( l =0; l < XCF.numLayers; ++l )
// {
// if ( pureZ[l] == z )
// c++;
// }
// printf("z=%d count:%d\n", z,c );
// }
free(pureZ);
return 0 ;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment