inlib
1.2.0
|
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