inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/xpm
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file exlib.license for terms.
00003 
00004 #ifndef inlib_xpm
00005 #define inlib_xpm
00006 
00007 #include <cstdio> //FILE,size_t
00008 #include <string>
00009 #include <vector>
00010 #include <ostream>
00011 
00012 #include "charmanip"
00013 
00014 namespace inlib {
00015 namespace xpm {
00016 
00017 typedef unsigned char* (*file_reader)(std::ostream&,const std::string&,unsigned int&,unsigned int&,unsigned int&);
00018 
00019 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) {
00020   // a_name is the xpm name. Then a string without a path and without
00021   // the .xpm suffix.
00022 
00023   unsigned int w,h,bpp;
00024   unsigned char* buffer = a_file_reader(a_out,a_file,w,h,bpp);
00025   if(!buffer) {
00026     a_out << "inlib::xpm::to_xpm :"
00027           << " read_file failed."
00028           << std::endl;
00029     return false;
00030   }
00031 
00032   // get colormap :
00033   
00034   typedef unsigned int color;
00035   std::vector<color> colors;
00036 
00037  {unsigned char r,g,b;
00038   for(unsigned int j=0;j<h;j++) {
00039     unsigned char* pos = buffer + j * (w * 3);
00040     for(unsigned int i=0;i<w;i++) {
00041       r = *pos;pos++;
00042       g = *pos;pos++;
00043       b = *pos;pos++;
00044 
00045       color c = 0;
00046       unsigned char* ca = (unsigned char*)&c;
00047       ca[0] = r;
00048       ca[1] = g;
00049       ca[2] = b;
00050       ca[3] = 0;
00051      
00052       //printf("debug : get : %d %d %d : %lu\n",r,g,b,colors.size());
00053 
00054       bool found = false;
00055       std::vector<color>::iterator it;
00056       for(it=colors.begin();it!=colors.end();++it) {
00057         if(*it==c) {
00058           found = true;
00059           break;
00060         }
00061       }
00062       if(!found) colors.push_back(c);
00063 
00064     }
00065   }}
00066 
00067   unsigned int colorn = (unsigned int)colors.size();
00068 
00069   //get a set of non problematic characters (for exa avoid \).
00070   std::vector<unsigned char> chars;
00071  {for(unsigned char c=0;c<255;c++) {
00072     if(inlib::is_letter(c)||inlib::is_digit(c)) {
00073       chars.push_back(c);
00074     }    
00075   }}
00076 
00077   unsigned int base = (unsigned int)chars.size();
00078 
00079   unsigned int nchar = 1;
00080  {unsigned int i = colorn;
00081   while(i>=base) {
00082     //unsigned int r = i%base;
00083     i /= base;
00084     nchar++;
00085   }}
00086 
00087   if(a_verbose) {
00088     a_out << "colors " << colorn
00089           << " base " << base
00090           << " nchar " << nchar
00091           << std::endl;
00092   }
00093 
00094   std::string xpm = a_name+".xpm";
00095 
00096   FILE* out = ::fopen(xpm.c_str(),"wb");
00097   if(!out) {
00098     a_out << "inlib::xpm::to_xpm :"
00099           << " can't open " << xpm
00100           << std::endl;
00101     delete [] buffer;
00102     return false;
00103   }
00104 
00105   ::fprintf(out,"%s","/* XPM */\n");
00106   ::fprintf(out,"static const char *%s[] = {\n",a_name.c_str());
00107   ::fprintf(out,"\"%u %u %u %u\",\n",w,h,colorn,nchar);
00108 
00109   // write colormap :
00110  {for(unsigned int index=0;index<colorn;index++) {
00111     ::fprintf(out,"%s","\"");
00112 
00113    {unsigned int ix = index;
00114     for(unsigned int ic=0;ic<nchar;ic++) {
00115       ::fprintf(out,"%c",chars[ix%base]);
00116       ix /= base;
00117     }}
00118 
00119     ::fprintf(out,"%s","\tc #");
00120 
00121     color c = colors[index];
00122     unsigned char* ca = (unsigned char*)&c;
00123     ::fprintf(out,"%02x%02x%02x",ca[0],ca[1],ca[2]);
00124 
00125     ::fprintf(out,"%s","\",\n");
00126   }}
00127 
00128   //pixmap :
00129  {unsigned char r,g,b;
00130   for(unsigned int j=0;j<h;j++) {
00131     unsigned char* pos = buffer + j * (w * 3);
00132     ::fprintf(out,"%s","\"");
00133     for(unsigned int i=0;i<w;i++) {
00134       r = *pos;pos++;
00135       g = *pos;pos++;
00136       b = *pos;pos++;
00137 
00138       color c;
00139       unsigned char* ca = (unsigned char*)&c;
00140       ca[0] = r;
00141       ca[1] = g;
00142       ca[2] = b;
00143       ca[3] = 0;
00144      
00145       bool found = false;
00146      {for(unsigned int index=0;index<colorn;index++) {
00147         //unsigned char c1 = index%base;
00148         //unsigned char c2 = index/base;
00149         if(c==colors[index]) {
00150 
00151          {unsigned int ix = index;
00152           for(unsigned int ic=0;ic<nchar;ic++) {
00153             ::fprintf(out,"%c",chars[ix%base]);
00154             ix /= base;
00155           }}
00156 
00157           //::fprintf(out,"%c%c",chars[c1],chars[c2]);
00158 
00159           found = true;
00160           break;
00161         }
00162       }}
00163       if(!found) {
00164         a_out << "inlib::xpm::to_xpm :"
00165               << " color not found in the colormap."
00166               << std::endl;
00167         ::fclose(out);
00168         ::remove(xpm.c_str());
00169         delete [] buffer;
00170         return false;
00171       }
00172 
00173     }
00174     if(j==(h-1)) 
00175       ::fprintf(out,"%s\n","\"");
00176     else
00177       ::fprintf(out,"%s\n","\",");
00178   }}
00179   
00180   ::fprintf(out,"%s","};");
00181 
00182   ::fclose(out);
00183   delete [] buffer;
00184 
00185   return true;
00186 }
00187 
00188 
00189 }}
00190 
00191 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines