Files
geant4/source/analysis/g4tools/include/tools/xpm
T
2019-12-06 15:12:28 +01:00

192 lines
4.2 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_xpm
#define tools_xpm
#include <cstdio> //FILE,size_t
#include <string>
#include <vector>
#include <ostream>
#include "charmanip"
namespace tools {
namespace xpm {
typedef unsigned char* (*file_reader)(std::ostream&,const std::string&,unsigned int&,unsigned int&,unsigned int&);
inline bool to_xpm(std::ostream& a_out,const std::string& a_file,const std::string& a_name,file_reader a_file_reader,bool a_verbose) {
// a_name is the xpm name. Then a string without a path and without
// the .xpm suffix.
unsigned int w,h,bpp;
unsigned char* buffer = a_file_reader(a_out,a_file,w,h,bpp);
if(!buffer) {
a_out << "tools::xpm::to_xpm :"
<< " read_file failed."
<< std::endl;
return false;
}
// get colormap :
typedef unsigned int color;
std::vector<color> colors;
{unsigned char r,g,b;
for(unsigned int j=0;j<h;j++) {
unsigned char* pos = buffer + j * (w * 3);
for(unsigned int i=0;i<w;i++) {
r = *pos;pos++;
g = *pos;pos++;
b = *pos;pos++;
color c = 0;
unsigned char* ca = (unsigned char*)&c;
ca[0] = r;
ca[1] = g;
ca[2] = b;
ca[3] = 0;
//printf("debug : get : %d %d %d : %lu\n",r,g,b,colors.size());
bool found = false;
std::vector<color>::iterator it;
for(it=colors.begin();it!=colors.end();++it) {
if(*it==c) {
found = true;
break;
}
}
if(!found) colors.push_back(c);
}
}}
unsigned int colorn = (unsigned int)colors.size();
//get a set of non problematic characters (for exa avoid \).
std::vector<unsigned char> chars;
{for(unsigned char c=0;c<255;c++) {
if(is_letter(c)||is_digit(c)) {
chars.push_back(c);
}
}}
unsigned int base = (unsigned int)chars.size();
unsigned int nchar = 1;
{unsigned int i = colorn;
while(i>=base) {
//unsigned int r = i%base;
i /= base;
nchar++;
}}
if(a_verbose) {
a_out << "colors " << colorn
<< " base " << base
<< " nchar " << nchar
<< std::endl;
}
std::string xpm = a_name+".xpm";
FILE* out = ::fopen(xpm.c_str(),"wb");
if(!out) {
a_out << "tools::xpm::to_xpm :"
<< " can't open " << xpm
<< std::endl;
delete [] buffer;
return false;
}
::fprintf(out,"%s","/* XPM */\n");
::fprintf(out,"static const char *%s[] = {\n",a_name.c_str());
::fprintf(out,"\"%u %u %u %u\",\n",w,h,colorn,nchar);
// write colormap :
{for(unsigned int index=0;index<colorn;index++) {
::fprintf(out,"%s","\"");
{unsigned int ix = index;
for(unsigned int ic=0;ic<nchar;ic++) {
::fprintf(out,"%c",chars[ix%base]);
ix /= base;
}}
::fprintf(out,"%s","\tc #");
color c = colors[index];
unsigned char* ca = (unsigned char*)&c;
::fprintf(out,"%02x%02x%02x",ca[0],ca[1],ca[2]);
::fprintf(out,"%s","\",\n");
}}
//pixmap :
{unsigned char r,g,b;
for(unsigned int j=0;j<h;j++) {
unsigned char* pos = buffer + j * (w * 3);
::fprintf(out,"%s","\"");
for(unsigned int i=0;i<w;i++) {
r = *pos;pos++;
g = *pos;pos++;
b = *pos;pos++;
color c;
unsigned char* ca = (unsigned char*)&c;
ca[0] = r;
ca[1] = g;
ca[2] = b;
ca[3] = 0;
bool found = false;
{for(unsigned int index=0;index<colorn;index++) {
//unsigned char c1 = index%base;
//unsigned char c2 = index/base;
if(c==colors[index]) {
{unsigned int ix = index;
for(unsigned int ic=0;ic<nchar;ic++) {
::fprintf(out,"%c",chars[ix%base]);
ix /= base;
}}
//::fprintf(out,"%c%c",chars[c1],chars[c2]);
found = true;
break;
}
}}
if(!found) {
a_out << "tools::xpm::to_xpm :"
<< " color not found in the colormap."
<< std::endl;
::fclose(out);
::remove(xpm.c_str());
delete [] buffer;
return false;
}
}
if(j==(h-1))
::fprintf(out,"%s\n","\"");
else
::fprintf(out,"%s\n","\",");
}}
::fprintf(out,"%s","};");
::fclose(out);
delete [] buffer;
return true;
}
}}
#endif