00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <fstream>
00033 #include <sstream>
00034 #include "ls_image.h"
00035 #include "bstream.h"
00036 #include "font_data.inc"
00037 #include "string_utils.h"
00038 #include "share_utils.h"
00039
00040 using namespace std;
00041
00042 const MP_Font medium_bold_font = { 0, 128, 7, 13, medium_bold_font_data };
00043 const MP_Font giant_font = { 0, 128, 9, 15, giant_font_data };
00044
00045 void Palette::setPredefined (int num)
00046 {
00047 clear();
00048 switch(num)
00049 {
00050 case 0:
00051 add(0,Colour(0,0,0));
00052 add(1,Colour(1,1,1));
00053 break;
00054 case 1:
00055 add(0,Colour(0,0,0));
00056 add(0.4f,Colour(0,0,0.5f));
00057 add(0.75f,Colour(0,0.6f,1));
00058 add(1,Colour(1,1,1));
00059 break;
00060 case 4:
00061 add(0,Colour(0,0,.5f));
00062 add(0.15f,Colour(0,0,1));
00063 add(0.4f,Colour(0,1,1));
00064 add(0.7f,Colour(1,1,0));
00065 add(0.9f,Colour(1,.33f,0));
00066 add(1,Colour(.5f,0,0));
00067 break;
00068 case 10:
00069 addb( 0, 0, 0,255);
00070 addb( 42, 0,112,255);
00071 addb( 85, 0,221,255);
00072 addb(127,255,237,217);
00073 addb(170,255,180, 0);
00074 addb(212,255, 75, 0);
00075 addb(255,100, 0, 0);
00076 break;
00077 case 11:
00078 addb( 0, 0, 0,255);
00079 addb( 13, 10, 20,255);
00080 addb( 26, 30,184,255);
00081 addb( 38, 80,235,255);
00082 addb( 52,191,239,250);
00083 addb( 65,228,240,245);
00084 addb( 76,241,241,212);
00085 addb( 77,241,241,212);
00086 addb( 88,245,240,175);
00087 addb(101,248,235,130);
00088 addb(114,250,204, 38);
00089 addb(127,243,153, 13);
00090 addb(140,204, 77, 0);
00091 addb(153,165, 32, 32);
00092 addb(166,114, 0, 32);
00093 addb(179,128,128,153);
00094 addb(192,179,179,204);
00095 addb(205,204,204,230);
00096 addb(218,230,230,242);
00097 addb(231,242,242,250);
00098 addb(255,252,252,255);
00099 break;
00100 default:
00101 planck_fail("Palette #"+dataToString(num)+" not yet supported.");
00102 }
00103 }
00104
00105 void LS_Image::write_char (int xpos, int ypos, const Colour &col, char c,
00106 int scale)
00107 {
00108 planck_assert ((c>=font.offset) && (c<font.offset+font.num_chars),
00109 "write_char: character out of range");
00110 for (int i=0; i<font.xpix; ++i)
00111 for (int j=0; j<font.ypix; ++j)
00112 {
00113 int ofs = (c-font.offset)*font.xpix*font.ypix + j*font.xpix + i;
00114 if (font.data[ofs]!=' ')
00115 for (int m=0; m<scale; ++m)
00116 for (int n=0; n<scale; ++n)
00117 put_pixel(xpos+scale*i+m,ypos+scale*j+n,col);
00118 }
00119 }
00120
00121 LS_Image::LS_Image ()
00122 : font(medium_bold_font) {}
00123
00124 LS_Image::LS_Image (int xres, int yres)
00125 : font(medium_bold_font), pixel(xres,yres,Colour(0,0,0)) {}
00126
00127 void LS_Image::annotate (int xpos, int ypos, const Colour &col,
00128 const string &text, int scale)
00129 {
00130 for (tsize m=0; m<text.length(); ++m)
00131 write_char(xpos+m*scale*font.xpix, ypos, col, text[m],scale);
00132 }
00133
00134 void LS_Image::annotate_centered (int xpos, int ypos, const Colour &col,
00135 const string &text, int scale)
00136 {
00137 xpos-=(scale*text.length()*font.xpix)/2;
00138 ypos-=scale*font.ypix/2;
00139 annotate (xpos,ypos,col,text,scale);
00140 }
00141
00142 void LS_Image::set_font (const MP_Font &fnt)
00143 { font = fnt; }
00144
00145 void LS_Image::write_TGA (const string &file) const
00146 {
00147 ofstream out(file.c_str(), ios_base::out | ios_base::binary);
00148 planck_assert(out, "could not create file '" + file + "'");
00149
00150 tsize xres=pixel.size1(), yres=pixel.size2();
00151
00152 bostream bo(out);
00153 const uint8 header[18] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00154 uint8(xres%256), uint8(xres/256), uint8(yres%256), uint8(yres/256), 24, 32};
00155
00156 bo.put (header, 18);
00157 vector <uint8> line(3*xres);
00158 for (tsize j=0; j<yres; ++j)
00159 {
00160 for (tsize i=0; i<xres; ++i)
00161 {
00162 line[i*3 ]=pixel[i][j].b;
00163 line[i*3+1]=pixel[i][j].g;
00164 line[i*3+2]=pixel[i][j].r;
00165 }
00166 bo.put(line.data(),3*xres);
00167 }
00168 planck_assert(out,"error writing output file '" + file + "'");
00169 }
00170
00171 namespace {
00172
00173 void write_equal_range (const arr<Colour8> &px, tsize begin, tsize end,
00174 vector<uint8> &buf)
00175 {
00176 chunkMaker cm (end-begin,128);
00177 uint64 cbeg, csz;
00178 while (cm.getNext(cbeg,csz))
00179 {
00180 buf.push_back(uint8(csz-1+128));
00181 buf.push_back(px[begin].b);
00182 buf.push_back(px[begin].g);
00183 buf.push_back(px[begin].r);
00184 }
00185 }
00186 void write_unequal_range (const arr<Colour8> &px, tsize begin, tsize end,
00187 vector<uint8> &buf)
00188 {
00189 chunkMaker cm (end-begin,128);
00190 uint64 cbeg, csz;
00191 while (cm.getNext(cbeg,csz))
00192 {
00193 buf.push_back(uint8(csz-1));
00194 for (tsize cnt=begin+cbeg; cnt< begin+cbeg+csz; ++cnt)
00195 {
00196 buf.push_back(px[cnt].b);
00197 buf.push_back(px[cnt].g);
00198 buf.push_back(px[cnt].r);
00199 }
00200 }
00201 }
00202
00203 }
00204
00205 void LS_Image::write_TGA_rle(const string &file) const
00206 {
00207 ofstream out(file.c_str(), ios_base::out | ios_base::binary);
00208 planck_assert(out, "could not create file '" + file + "'");
00209
00210 tsize xres=pixel.size1(), yres=pixel.size2();
00211
00212 bostream bo(out);
00213 const uint8 header[18] = { 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00214 uint8(xres%256), uint8(xres/256), uint8(yres%256), uint8(yres/256), 24, 32};
00215
00216 bo.put(header,18);
00217 vector<uint8> buf;
00218 arr<Colour8> px(xres);
00219 for (tsize y=0; y<yres; ++y)
00220 {
00221 buf.clear();
00222 for (tsize x=0; x<xres; ++x)
00223 px[x] = pixel[x][y];
00224 tsize xstart=0;
00225 while (xstart<xres)
00226 {
00227 if (xstart==xres-1)
00228 {
00229 write_unequal_range (px,xstart,xstart+1,buf);
00230 xstart=xres;
00231 }
00232 else
00233 {
00234 if (px[xstart+1]==px[xstart])
00235 {
00236 tsize xend=xstart+2;
00237 while ((xend<xres) && (px[xend]==px[xstart])) ++xend;
00238 write_equal_range (px,xstart,xend,buf);
00239 xstart=xend;
00240 }
00241 else
00242 {
00243 tsize xend=xstart+2;
00244 while ((xend<xres) && (px[xend]!=px[xend-1])) ++xend;
00245 write_unequal_range (px,xstart,xend,buf);
00246 xstart=xend;
00247 }
00248 }
00249 }
00250 bo.put(buf.data(), buf.size());
00251 }
00252 planck_assert(out,"error writing output file '" + file + "'");
00253 }
00254
00255 void LS_Image::write_PPM (const string &file) const
00256 {
00257 ofstream out(file.c_str(), ios_base::out | ios_base::binary);
00258 planck_assert(out, "could not create file '" + file + "'");
00259
00260 tsize xres=pixel.size1(), yres=pixel.size2();
00261
00262 bostream bo(out);
00263
00264 ostringstream header;
00265 header << "P6" << endl << xres << endl << yres << endl << 255 << endl;
00266 string hdrdata = header.str();
00267 bo.put(hdrdata.c_str(),hdrdata.size());
00268
00269 vector <uint8> line(3*xres);
00270 for (tsize j=0; j<yres; ++j)
00271 {
00272 for (tsize i=0; i<xres; ++i)
00273 {
00274 line[i*3 ]=pixel[i][j].r;
00275 line[i*3+1]=pixel[i][j].g;
00276 line[i*3+2]=pixel[i][j].b;
00277 }
00278 bo.put(line.data(),3*xres);
00279 }
00280 planck_assert(out,"error writing output file '" + file + "'");
00281 }