Index: Makefile
===================================================================
--- Makefile (revision 8160)
+++ Makefile (working copy)
@@ -265,6 +265,7 @@
SOURCES += gui/components/gui_obj_view_t.cc
SOURCES += gui/components/gui_fixedwidth_textarea.cc
SOURCES += gui/components/gui_flowtext.cc
+SOURCES += gui/components/gui_flowtext_image.cc
SOURCES += gui/components/gui_image.cc
SOURCES += gui/components/gui_image_list.cc
SOURCES += gui/components/gui_komponente.cc
@@ -445,6 +446,8 @@
SOURCES += unicode.cc
SOURCES += utils/cbuffer_t.cc
SOURCES += utils/csv.cc
+SOURCES += utils/dr_rdpng.cc
+SOURCES += utils/imgloader.cc
SOURCES += utils/log.cc
SOURCES += utils/searchfolder.cc
SOURCES += utils/sha1.cc
@@ -629,6 +632,7 @@
include OSX/osx.mk
endif
+LIBS += -lpng
.PHONY: makeobj
Index: Simutrans.vcxproj
===================================================================
--- Simutrans.vcxproj (revision 8160)
+++ Simutrans.vcxproj (working copy)
@@ -70,7 +70,7 @@
4996;4373;%(DisableSpecificWarnings)
- kernel32.lib;user32.lib;gdi32.lib;shell32.lib;winmm.lib;zlibstat.lib;advapi32.lib;ws2_32.lib;imm32.lib;libbz2.lib;pthreadVC2.lib;libfreetype2.lib
+ kernel32.lib;user32.lib;gdi32.lib;shell32.lib;winmm.lib;zlibstat.lib;advapi32.lib;ws2_32.lib;imm32.lib;libbz2.lib;pthreadVC2.lib;libpng.lib;libfreetype2.lib
%(AdditionalLibraryDirectories)
false
libcmt.lib;%(IgnoreSpecificDefaultLibraries)
@@ -106,7 +106,7 @@
4200;4800;4311;4996;4373;%(DisableSpecificWarnings)
- kernel32.lib;user32.lib;gdi32.lib;shell32.lib;winmm.lib;zlibstat.lib;advapi32.lib;ws2_32.lib;imm32.lib;libbz2.lib;pthreadVC2.lib
+ kernel32.lib;user32.lib;gdi32.lib;shell32.lib;winmm.lib;zlibstat.lib;advapi32.lib;ws2_32.lib;imm32.lib;libbz2.lib;pthreadVC2.lib;libpng.lib;
%(AdditionalLibraryDirectories)
libcmt.lib;%(IgnoreSpecificDefaultLibraries)
false
@@ -137,6 +137,7 @@
+
@@ -283,6 +284,8 @@
+
+
@@ -450,6 +453,7 @@
+
@@ -609,6 +613,8 @@
+
+
Index: dataobj/height_map_loader.cc
===================================================================
--- dataobj/height_map_loader.cc (revision 8160)
+++ dataobj/height_map_loader.cc (working copy)
@@ -7,6 +7,7 @@
#include "environment.h"
#include "height_map_loader.h"
#include "../simio.h"
+#include "../utils/imgloader.h"
height_map_loader_t::height_map_loader_t(bool new_format):
@@ -18,225 +19,31 @@
// read height data from bmp or ppm files
bool height_map_loader_t::get_height_data_from_file( const char *filename, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values )
{
- if (FILE* const file = fopen(filename, "rb")) {
- char id[3];
- // parsing the header of this mixed file format is nottrivial ...
- id[0] = fgetc(file);
- id[1] = fgetc(file);
- id[2] = 0;
- if(strcmp(id, "P6")) {
- if(strcmp(id, "BM")) {
- fclose(file);
- dbg->error("height_map_loader_t::load_heightfield()","Heightfield has wrong image type %s instead P6/BM", id);
- return false;
- }
- // bitmap format
- fseek( file, 10, SEEK_SET );
- uint32 data_offset;
- sint32 w, h, format, table;
- sint16 bit_depth;
-#ifdef SIM_BIG_ENDIAN
- uint32 l;
- uint16 s;
- fread( &l, 4, 1, file );
- data_offset = endian(l);
- fseek( file, 18, SEEK_SET );
- fread( &l, 4, 1, file );
- w = endian(l);
- fread( &l, 4, 1, file );
- h = endian(l);
- fseek( file, 28, SEEK_SET );
- fread( &s, 2, 1, file );
- bit_depth = endian(s);
- fread( &l, 4, 1, file );
- format = endian(l);
- fseek( file, 46, SEEK_SET );
- fread( &l, 4, 1, file );
- table = endian(l);
-#else
- fread( &data_offset, 4, 1, file );
- fseek( file, 18, SEEK_SET );
- fread( &w, 4, 1, file );
- fread( &h, 4, 1, file );
- fseek( file, 28, SEEK_SET );
- fread( &bit_depth, 2, 1, file );
- fread( &format, 4, 1, file );
- fseek( file, 46, SEEK_SET );
- fread( &table, 4, 1, file );
-#endif
- if((bit_depth!=8 && bit_depth!=24) || format>1) {
- if(!update_only_values) {
- dbg->fatal("height_map_loader_t::get_height_data_from_file()","Can only use 8Bit (RLE or normal) or 24 bit bitmaps!");
- }
- fclose( file );
- return false;
- }
+ sint32 w, h;//, format, table;
+ img_loader *l=new img_loader();
+ if (l->load_image(filename)!=IMGR_OK) {
+ delete l;
+ return false;
+ }
- // skip parsing body
- if(update_only_values) {
- ww = w;
- hh = abs(h);
- return true;
- }
+ w=l->get_width();
+ h=l->get_height();
+ ww=w;
+ hh=h;
+ if (update_only_values) {
+ return true;
+ }
- // now read the data and convert them on the fly
- hfield = new sint8[w*h];
- memset( hfield, groundwater, w*h );
- if(bit_depth==8) {
- // convert color tables to height levels
- if(table==0) {
- table = 256;
- }
- sint8 h_table[256];
- fseek( file, 54, SEEK_SET );
- for( int i=0; i
0)
- bool mirror = (h<0);
- h = abs(h);
- for( sint32 y=0; y 0) {
- for( sint32 k = 0; k < Count; k++, x++ ) {
- hfield[x+(y*w)] = h_table[ColorIndex];
- }
- } else if (Count == 0) {
- sint32 Flag = ColorIndex;
- if (Flag == 0) {
- // goto next line
- x = 0;
- y--;
- }
- else if (Flag == 1) {
- // end of bitmap
- break;
- }
- else if (Flag == 2) {
- // skip with cursor
- x += (uint8)fgetc(file);
- y -= (uint8)fgetc(file);
- }
- else {
- // uncompressed run
- Count = Flag;
- for( sint32 k = 0; k < Count; k++, x++ ) {
- hfield[x+y*w] = h_table[(uint8)fgetc(file)];
- }
- if (ftell(file) & 1) { // alway even offset in file
- fseek(file, 1, SEEK_CUR);
- }
- }
- }
- }
- }
- }
- else {
- // uncompressed 24 bits
- bool mirror = (h<0);
- h = abs(h);
- for( sint32 y=0; yget_bits();
+ hfield = new sint8[w*h];
+ memset( hfield, groundwater, w*h );
+ for (int y=0;y='0' && *c<='9') {
- c++;
- }
- }
- // now the data
- sint32 w = param[0];
- sint32 h = param[1];
- if(param[2]!=255) {
- fclose(file);
- if(!update_only_values) {
- dbg->fatal("height_map_loader_t::load_heightfield()","Heightfield has wrong color depth %d", param[2] );
- }
- return false;
- }
-
- // report only values
- if(update_only_values) {
- fclose(file);
- ww = w;
- hh = h;
- return true;
- }
-
- // ok, now read them in
- hfield = new sint8[w*h];
- memset( hfield, groundwater, w*h );
-
- for(sint16 y=0; y( strstart(start, "src"));
+ if (start) {
+ while (*start=='"'||*start==' '||*start=='='||*start=='\'') start++;
+ char *end=start;
+ while (*end && *end!= '"' && *end != '\'') end++;
+ *end=0;
+ param=start;
+ if (param[0]!=0) {
+ // Load in Image and Store Image ID for displaying
+ gui_flowtext_image_t img=gui_flowtext_image_t(param);
+ image_id ret=img.get_image_id();
+ images.append(ret);
+ }
+ } else {
+ param="";
+ }
+ } else {
+ att=ATT_IMG_END;
+ }
+ }
else if (word[0] == 'i') {
att = endtag ? ATT_IT_END : ATT_IT_START;
}
@@ -239,6 +268,7 @@
const int width = size.w;
slist_tpl::iterator link = links.begin();
+ slist_tpl::iterator image=images.begin();
int xpos = 0;
int ypos = 0;
@@ -247,6 +277,8 @@
bool double_it = false;
bool link_it = false; // true, if currently underlining for a link
int extra_pixel = 0; // extra pixel before next line
+ int extra_pixels = 0; // extra pixels for image display
+ int extra_x_pixels=0; // extra pixels in x dimension for image display
int last_link_x = 0; // at this position ye need to continue underline drawing
int max_width = width;
int text_width = width;
@@ -276,8 +308,22 @@
}
extra_pixel = 1;
}
- xpos = 0;
- last_link_x = 0;
+
+ if ((extra_x_pixels+nxpos)>max_width) {
+ ypos+=extra_pixels;
+ extra_pixels=0;
+ extra_x_pixels=0;
+ }
+ if (extra_pixels>0) {
+ xpos=extra_x_pixels;
+ nxpos+=extra_x_pixels;
+ extra_pixels-= LINESPACE+extra_pixel;
+ } else {
+ xpos = 0;
+ extra_pixels = 0;
+ }
+ last_link_x = extra_x_pixels;
+
ypos += LINESPACE+extra_pixel;
extra_pixel = 0;
}
@@ -312,7 +358,9 @@
}
extra_pixel = 1;
}
- ypos += LINESPACE+extra_pixel;
+ ypos += LINESPACE+extra_pixel+extra_pixels;
+ extra_x_pixels=0;
+ extra_pixels=0;
last_link_x = 0;
extra_pixel = 0;
break;
@@ -341,18 +389,56 @@
double_it = true;
break;
- case ATT_H1_END:
- double_it = false;
- if(doit) {
- display_fillbox_wh_clip_rgb(offset.x + 1, offset.y + ypos + LINESPACE, xpos, 1, color, false);
- display_fillbox_wh_clip_rgb(offset.x, offset.y + ypos + LINESPACE-1, xpos, 1, double_color, false);
- }
+ case ATT_H1_END:
+ double_it = false;
+ if(doit) {
+ display_fillbox_wh_clip_rgb(offset.x + 1 + extra_x_pixels, offset.y + ypos + LINESPACE, xpos - extra_x_pixels, 1, color, false);
+ display_fillbox_wh_clip_rgb(offset.x + extra_x_pixels, offset.y + ypos + LINESPACE-1, xpos - extra_x_pixels, 1, double_color, false);
+ }
xpos = 0;
extra_pixel = 0;
ypos += LINESPACE+2;
+ if (extra_pixels>0) {
+ xpos=extra_x_pixels;
+ extra_pixels-= LINESPACE+extra_pixel;
+ }
+ else {
+ xpos = 0;
+ extra_pixels = 0;
+ }
color = SYSCOL_TEXT;
+ break;
+
+ case ATT_IMG_START:
+ if (image!=images.end()) {
+ //display image
+ KOORD_VAL xoff,yoff,xw,yw;
+ display_get_base_image_offset(image->id,&xoff,&yoff,&xw,&yw);
+ if ((xpos+xw>max_width)&&(xpos!=0)) {
+ // New Line if image is too large to fit on line (unless already at new line)
+ xpos=0;
+ ypos+=LINESPACE+extra_pixel+extra_pixels;
+ extra_pixel=0;
+ extra_pixels=0;
+ extra_x_pixels=0;
+ }
+ if (doit) {
+ display_base_img(image->id,offset.x+xpos,offset.y+ypos-yoff,0,0,0);
+ }
+ xpos+=xw;
+ //ypos+=yw-LINESPACE;
+ if (extra_pixels nodes;
slist_tpl links;
+ slist_tpl images;
char title[128];
};
Index: gui/components/gui_flowtext_image.cc
===================================================================
--- gui/components/gui_flowtext_image.cc (nonexistent)
+++ gui/components/gui_flowtext_image.cc (working copy)
@@ -0,0 +1,139 @@
+#include "gui_flowtext_image.h"
+
+#include "../../descriptor/image.h"
+#include "../../dataobj/environment.h"
+#include "../../simworld.h"
+#include "../../dataobj/scenario.h"
+#include "../../utils/imgloader.h"
+//#include "../../utils/dr_rdpng.h"
+#include "../../simdebug.h"
+
+gui_flowtext_image_t::gui_flowtext_image_t() {
+ _image_name="";
+ _image_id=0;
+}
+
+image_id gui_flowtext_image_t::get_image_id() {
+ return _image_id;
+}
+
+std::string gui_flowtext_image_t::get_image_name() {
+ return _image_name;
+}
+
+hashtable_tpl *gui_flowtext_image_t::_images=NULL;
+
+gui_flowtext_image_t::gui_flowtext_image_t(std::string filePath) {
+ // Initialize Image list if it has not already been done.
+ if (_images==NULL) {
+ _images=new hashtable_tpl();
+ }
+ _image_name=filePath;
+
+ // Check if image is already loaded
+ _image_id=_images->get(filePath.c_str());
+ if (_image_id>0) {
+ return;
+ }
+
+ // First Search for image in Scenario Path, then PAK path, the base path
+ scenario_t *scenario=world()->get_scenario();
+ std::string spath=scenario->get_scenario_path().c_str();
+
+ std::string path= env_t::program_dir+spath+filePath;
+ FILE *fp=fopen(path.c_str(),"rb");
+
+ if (fp==NULL) {
+ path= env_t::program_dir+env_t::objfilename + filePath;
+ fp=fopen(path.c_str(),"rb");
+ if (fp==NULL) {
+ path= env_t::program_dir+filePath;
+ fp=fopen(path.c_str(),"rb");
+ if (fp==NULL) {
+ // file not found
+ _image_id=0;
+ return;
+ }
+ }
+ }
+
+ fclose(fp);
+ dbg->message("gui_flow_text_image_t()","Loading File %s",path.c_str());
+ img_loader c=img_loader();
+ c.load_image(path.c_str());
+ dbg->message("gui_flow_text_image_t()","Loaded File %s",path.c_str());
+ /*if ((filePath.substr(filePath.length()-3,3)=="png")||(filePath.substr(filePath.length()-3,3)=="PNG")) {
+ // Load PNG Instead
+ unsigned char **block=new unsigned char * [1];
+ block[0]=(unsigned char *)malloc(1);
+ uint32 width=0;
+ uint32 height=0;
+ uint32 base_img_size=1;
+ load_block(block,&width,&height,path.c_str(),base_img_size);
+ c.set_bits(block[0],width,0-height,0x000000FF,0x0000FF00,0x00FF0000);
+ } else {
+ // Load BMP
+ c.load(path.c_str());
+ }*/
+ uint a = 0x00000000;
+ uint r = 0x00007C00;
+ uint g = 0x000003E0;
+ uint bl = 0x0000001F;
+ uint size=c.get_width()*c.get_height()+2;
+ uint16 *buffer=new uint16 [size];
+ size=size*2;
+ c.get_bits((void*)buffer,size,r,g,bl,a,false);
+ //PIXVAL pixel=0;
+ //PIXVAL prevPixel=0;
+ //PIXVAL count=0;
+ size_t len=0;
+ // Create a buffer to store all required PIXVAL data
+ PIXVAL *pixBuffer=new PIXVAL [(c.get_width()+2)*c.get_height()*3];
+ bool first=true;
+ for (uint32 i=0;i<(c.get_width()*c.get_height());i++) {
+ if (i%c.get_width()==0) {
+ if (first) {
+ first=false;
+ } else {
+ // Add end of line 0 terminator
+ pixBuffer[len]=0;
+ len++;
+ }
+ // Add 0 Transparent pixels
+ pixBuffer[len]=0;
+ len++;
+ // Add image width pixels
+ pixBuffer[len]=c.get_width();
+ len++;
+ }
+ // Add the pixel data
+ pixBuffer[len]=buffer[i];
+ len++;
+ }
+ // Add a 0 at the end of the data
+ pixBuffer[len]=0;
+ len++;
+
+ // Not sure how to correctly allocate data for bild_t, other than that in has a set of data + buffer of PIXVAL items
+ image_t *b=(image_t *)malloc(sizeof(PIXVAL)*len+128);
+ // Set image data
+ b->x=0;
+ b->y=0;
+ b->w=c.get_width();
+ b->h=c.get_height();
+ b->zoomable=0;
+ b->len=len;
+ for (uint32 i=0;idata[i]=pixBuffer[i];
+ }
+ // delete the temporary pixBuffer
+ delete pixBuffer;
+ // register the image
+ register_image(b);
+ // Store the image number for later retrieval
+ _image_id=b->imageid;
+ char * name=new char [_image_name.length()+1];
+ strcpy(name,_image_name.c_str());
+ // Store the image details in case it is accessed later
+ _images->put(name,_image_id);
+}
Index: gui/components/gui_flowtext_image.h
===================================================================
--- gui/components/gui_flowtext_image.h (nonexistent)
+++ gui/components/gui_flowtext_image.h (working copy)
@@ -0,0 +1,22 @@
+#ifndef GUI_COMPONENTS_FLOWTEXT_IMAGE_H
+#define GUI_COMPONENTS_FLOWTEXT_IMAGE_H
+
+#include
+#include "../../display/simimg.h"
+#include "../../tpl/hashtable_tpl.h"
+#include "../../tpl/stringhashtable_tpl.h"
+
+class gui_flowtext_image_t {
+public:
+ gui_flowtext_image_t(std::string filePath);
+ gui_flowtext_image_t();
+
+ image_id get_image_id();
+ std::string get_image_name();
+private:
+ image_id _image_id;
+ std::string _image_name;
+ static hashtable_tpl *_images;
+};
+
+#endif
Index: utils/imgloader.cc
===================================================================
--- utils/imgloader.cc (nonexistent)
+++ utils/imgloader.cc (working copy)
@@ -0,0 +1,916 @@
+
+#include "imgloader.h"
+#include "dr_rdpng.h"
+#include
+#include
+#include "../simio.h"
+#include "../simdebug.h"
+#include
+
+img_loader::img_loader(const char *filename):m_bitmap_data(0),m_bitmap_size(0),m_greyscale(0) {
+ dispose();
+ if (filename!=NULL) {
+ load_image(filename);
+ }
+}
+
+img_loader::~img_loader() {
+ dispose();
+}
+
+void img_loader::dispose(void) {
+ if (m_bitmap_data) {
+ delete[] m_bitmap_data;
+ m_bitmap_data=NULL;
+ }
+ memset(&m_bitmap_file_header,0,sizeof(m_bitmap_file_header));
+ memset(&m_bitmap_header,0,sizeof(m_bitmap_header));
+}
+
+ImgResult img_loader::load_image(const char * filename) {
+ if (filename==NULL) {
+ return IMGR_NULL;
+ }
+ std::ifstream file(filename, std::ios::binary | std::ios::in);
+
+ if (file.bad()) {
+ return IMGR_FILE_DOES_NOT_EXIST;
+ }
+
+ if (!file.is_open()) {
+ return IMGR_UNABLE_TO_OPEN;
+ }
+
+ dispose();
+ char signature[3]={0,0,0};
+ file.read(signature,2);
+ if (strcmp(signature,"BM")==0) {
+ file.close();
+ return this->load_bmp(filename);
+ } else if ((signature[0]=='P')&&(signature[1]>='1')&&(signature[1]<='6')) {
+ file.close();
+ return this->load_pxm(filename);
+ } else if (strcmp(signature,"‰P")==0) {
+ file.read(signature,2);
+ if (strcmp(signature,"NG")==0) {
+ file.close();
+ return this->load_png(filename);
+ } else {
+ file.close();
+ return IMGR_UNSUPPORTED_FORMAT;
+ }
+ }
+ file.close();
+ return IMGR_UNSUPPORTED_FORMAT;
+}
+
+
+void * img_loader::get_bits()
+{
+ return (void*)m_bitmap_data;
+}
+
+
+ImgResult img_loader::get_bits(void * buffer, uint32 & buffer_size, uint32 red_mask, uint32 green_mask, uint32 blue_mask, uint32 alpha_mask, bool include_padding)
+{
+ ImgResult result = IMGR_OK;
+ uint32 BitCountRed = color::bit_count_by_mask(red_mask);
+ uint32 BitCountGreen = color::bit_count_by_mask(green_mask);
+ uint32 BitCountBlue = color::bit_count_by_mask(blue_mask);
+ uint32 BitCountAlpha = color::bit_count_by_mask(alpha_mask);
+
+ unsigned int BitCount = (BitCountRed + BitCountGreen + BitCountBlue + BitCountAlpha + 7) & ~7;
+
+ if (BitCount > 32) {
+ return IMGR_INVALID_FORMAT;
+ }
+
+ unsigned int w = get_width();
+ unsigned int dataBytesPerLine = (w * BitCount + 7) / 8;
+ unsigned int LineWidth = (dataBytesPerLine + 3) & ~3;
+
+ if (buffer_size == 0 || buffer == 0) {
+ buffer_size = (get_width() * get_height() * BitCount) / 8 + sizeof(unsigned int);
+ return IMGR_OK;
+ }
+
+ uint8* BufferPtr = (uint8*)buffer;
+
+ uint32 BitPosRed = color::bit_position_by_mask(red_mask);
+ uint32 BitPosGreen = color::bit_position_by_mask(green_mask);
+ uint32 BitPosBlue = color::bit_position_by_mask(blue_mask);
+ uint32 BitPosAlpha = color::bit_position_by_mask(alpha_mask);
+
+ unsigned int j = 0;
+
+ for (uint32 i = 0; i < (uint32)m_bitmap_size; i++) {
+ *(uint32*)BufferPtr =
+ (color::convert(m_bitmap_data[i].Blue, 8, BitCountBlue) << BitPosBlue) |
+ (color::convert(m_bitmap_data[i].Green, 8, BitCountGreen) << BitPosGreen) |
+ (color::convert(m_bitmap_data[i].Red, 8, BitCountRed) << BitPosRed) |
+ (color::convert(m_bitmap_data[i].Alpha, 8, BitCountAlpha) << BitPosAlpha);
+
+ if (include_padding) {
+ j++;
+ if (j >= w) {
+ for (uint32 k = 0; k < LineWidth - dataBytesPerLine; k++) {
+ BufferPtr += (BitCount >> 3);
+ }
+ j = 0;
+ }
+
+ }
+
+ BufferPtr += (BitCount >> 3);
+ }
+
+ buffer_size -= sizeof(uint32);
+
+ return result;
+}
+
+
+ImgResult img_loader::load_bmp(const char *filename)
+{
+ std::ifstream file(filename, std::ios::binary | std::ios::in);
+
+ if (file.bad()) {
+ return IMGR_FILE_DOES_NOT_EXIST;
+ }
+
+ if (file.is_open() == false) {
+ return IMGR_UNABLE_TO_OPEN;
+ }
+ dispose();
+
+ file.read((char*) &m_bitmap_file_header, sizeof(BITMAP_FILEHEADER_SIZE));
+ if (m_bitmap_file_header.Signature!=BITMAP_SIGNATURE) {
+ return IMGR_INVALID_FORMAT;
+ }
+
+ file.read((char*) &m_bitmap_header,sizeof(BITMAP_HEADER));
+
+ // Load Color Table
+ file.seekg(BITMAP_FILEHEADER_SIZE+m_bitmap_header.HeaderSize,std::ios::beg);
+
+ uint32 color_table_size=0;
+ if (m_bitmap_header.BitCount==1) {
+ color_table_size=2;
+ } else if (m_bitmap_header.BitCount==4) {
+ color_table_size=16;
+ } else if (m_bitmap_header.BitCount==8) {
+ color_table_size=256;
+ }
+
+ // Always allocate full sized color table (and make sure it is not zero or MSVC will crash!)
+ BGRA* color_table = new BGRA[color_table_size+1];
+
+ file.read((char *)color_table,sizeof(BGRA)*m_bitmap_header.ClrUsed);
+ m_bitmap_size=get_width()*get_height();
+ m_bitmap_data=new RGBA[m_bitmap_size];
+
+ uint32 line_width=((get_width()*get_bit_count()/8)+3)&~3;
+ uint8* line=new uint8[line_width];
+
+ file.seekg(m_bitmap_file_header.BitsOffset,std::ios::beg);
+
+ sint32 index=0;
+
+ ImgResult result=IMGR_OK;
+
+ if (m_bitmap_header.Compression==0) {
+ for (uint32 y=0;y>4)&0x0f].Red;
+ m_bitmap_data[index].Green=color_table[(Color>>4)&0x0f].Green;
+ m_bitmap_data[index].Blue=color_table[(Color>>4)&0x0f].Blue;
+ m_bitmap_data[index].Alpha=color_table[(Color>>4)&0x0f].Alpha;
+ index++;
+ m_bitmap_data[index].Red=color_table[Color & 0x0f].Red;
+ m_bitmap_data[index].Green=color_table[Color & 0x0f].Green;
+ m_bitmap_data[index].Blue=color_table[Color & 0x0f].Blue;
+ m_bitmap_data[index].Alpha=color_table[Color & 0x0f].Alpha;
+ index++;
+ line_ptr++;
+ x++;
+ } else if (m_bitmap_header.BitCount==8) {
+ uint32 Color=*((uint8*)line_ptr);
+ m_bitmap_data[index].Red=color_table[Color].Red;
+ m_bitmap_data[index].Green=color_table[Color].Green;
+ m_bitmap_data[index].Blue=color_table[Color].Blue;
+ m_bitmap_data[index].Alpha=color_table[Color].Alpha;
+ index++;
+ line_ptr++;
+ } else if (m_bitmap_header.BitCount==16) {
+ uint32 Color = *((uint16*) line_ptr);
+ m_bitmap_data[index].Red=((Color >> 10) & 0x1f) << 3;
+ m_bitmap_data[index].Green=((Color >> 5) & 0x1f) << 3;
+ m_bitmap_data[index].Blue=(Color & 0x1f) << 3;
+ m_bitmap_data[index].Alpha=255;
+ index++;
+ line_ptr+=2;
+ } else if (m_bitmap_header.BitCount==24) {
+ uint32 Color=*((uint32*)line_ptr);
+ m_bitmap_data[index].Red=(Color>>16)&0xff;
+ m_bitmap_data[index].Green=(Color>>8)&0xff;
+ m_bitmap_data[index].Blue=Color&0xff;
+ m_bitmap_data[index].Alpha=255;
+ index++;
+ line_ptr+=3;
+ } else if (m_bitmap_header.BitCount==32) {
+ uint32 Color=*((uint32*)line_ptr);
+ m_bitmap_data[index].Alpha=(Color>>24)&0xff;
+ m_bitmap_data[index].Red=(Color>>16)&0xff;
+ m_bitmap_data[index].Green=(Color>>8)&0xff;
+ m_bitmap_data[index].Blue=Color&0xff;
+ index++;
+ line_ptr+=4;
+ }
+ }
+ }
+ } else if (m_bitmap_header.Compression==1) {
+ // RLE Compression
+ uint8 Count=0;
+ uint8 color_index=0;
+ int x=0,y=0;
+ while (file.eof()==false) {
+ file.read((char *)&Count,sizeof(uint8));
+ file.read((char *)&color_index,sizeof(uint8));
+
+ if (Count>0) {
+ index=x+y*get_width();
+ for (int k=0;k0){
+ // Bitmaps are inverted by default, uninvert the bitmap
+ for (int yi=0;yi 16) {
+ return false;
+ }
+
+ unsigned int w = get_width();
+ unsigned int dataBytesPerLine = (w * BitCount + 7) / 8;
+ unsigned int LineWidth = (dataBytesPerLine + 3) & ~3;
+
+ if (Size == 0 || Buffer == 0) {
+ Size = (LineWidth * get_height() * BitCount) / 8;
+ return true;
+ }
+
+
+ if (OptimalPalette) {
+ PaletteSize = 0;
+ // Not implemented
+ } else {
+ if (BitCount == 1) {
+ PaletteSize = 2;
+ // Not implemented: Who need that?
+ } else if (BitCount == 4) { // 2:2:1
+ PaletteSize = 16;
+ Palette = new BGRA[PaletteSize];
+ for (int r = 0; r < 4; r++) {
+ for (int g = 0; g < 2; g++) {
+ for (int b = 0; b < 2; b++) {
+ Palette[r | g << 2 | b << 3].Red = r ? (r << 6) | 0x3f : 0;
+ Palette[r | g << 2 | b << 3].Green = g ? (g << 7) | 0x7f : 0;
+ Palette[r | g << 2 | b << 3].Blue = b ? (b << 7) | 0x7f : 0;
+ Palette[r | g << 2 | b << 3].Alpha = 0xff;
+ }
+ }
+ }
+ } else if (BitCount == 8) { // 3:3:2
+ PaletteSize = 256;
+ Palette = new BGRA[PaletteSize];
+ for (int r = 0; r < 8; r++) {
+ for (int g = 0; g < 8; g++) {
+ for (int b = 0; b < 4; b++) {
+ Palette[r | g << 3 | b << 6].Red = r ? (r << 5) | 0x1f : 0;
+ Palette[r | g << 3 | b << 6].Green = g ? (g << 5) | 0x1f : 0;
+ Palette[r | g << 3 | b << 6].Blue = b ? (b << 6) | 0x3f : 0;
+ Palette[r | g << 3 | b << 6].Alpha = 0xff;
+ }
+ }
+ }
+ } else if (BitCount == 16) { // 5:5:5
+ // Not implemented
+ }
+ }
+
+ unsigned int j = 0;
+ uint8* BufferPtr = (uint8*) Buffer;
+
+ for (uint32 i = 0; i < (uint32)m_bitmap_size; i++) {
+ if (BitCount == 1) {
+ // Not implemented: Who needs that?
+ } else if (BitCount == 4) {
+ *BufferPtr = ((m_bitmap_data[i].Red >> 6) | (m_bitmap_data[i].Green >> 7) << 2 | (m_bitmap_data[i].Blue >> 7) << 3) << 4;
+ i++;
+ *BufferPtr |= (m_bitmap_data[i].Red >> 6) | (m_bitmap_data[i].Green >> 7) << 2 | (m_bitmap_data[i].Blue >> 7) << 3;
+ } else if (BitCount == 8) {
+ *BufferPtr = (m_bitmap_data[i].Red >> 5) | (m_bitmap_data[i].Green >> 5) << 3 | (m_bitmap_data[i].Blue >> 5) << 6;
+ } else if (BitCount == 16) {
+ // Not implemented
+ }
+
+ if (IncludePadding) {
+ j++;
+ if (j >= w) {
+ for (unsigned int k = 0; k < (LineWidth - dataBytesPerLine); k++) {
+ BufferPtr += BitCount / 8;
+ }
+ j = 0;
+ }
+ }
+
+ BufferPtr++;
+ }
+
+ Result = true;
+
+ return Result;
+}
+
+
+bool img_loader::save_BMP(char * filename,uint32 BitCount) {
+ bool result=true;
+ std::ofstream file(filename, std::ios::out | std::ios::binary);
+
+ if (file.is_open()==false) {
+ return false;
+ }
+ BITMAP_FILEHEADER bfh;
+ BITMAP_HEADER bh;
+ memset(&bfh,0,sizeof(bfh));
+ memset(&bh,0,sizeof(bh));
+
+ bfh.Signature=BITMAP_SIGNATURE;
+ bfh.BitsOffset=BITMAP_FILEHEADER_SIZE+sizeof(BITMAP_HEADER);
+ bfh.Size=(get_width()*get_height()*BitCount)/8+bfh.BitsOffset;
+
+ bh.HeaderSize=sizeof(BITMAP_HEADER);
+ bh.BitCount=BitCount;
+
+ if (BitCount==32) {
+ bh.Compression=3;
+ bh.AlphaMask = 0xff000000;
+ bh.RedMask = 0x00ff0000;
+ bh.GreenMask = 0x0000ff00;
+ bh.BlueMask = 0x000000ff;
+ } else if (BitCount==16) {
+ bh.Compression=3;
+ bh.AlphaMask = 0x00000000;
+ bh.RedMask = 0x0000001f;
+ bh.GreenMask = 0x000007E0;
+ bh.BlueMask = 0x0000F800;
+ } else {
+ bh.Compression=0;
+ }
+
+ unsigned int line_width=(get_width()+3)&~3;
+
+ bh.Planes=1;
+ bh.Height=get_height();
+ bh.Width=get_width();
+ bh.SizeImage=(line_width*BitCount*get_height())/8;
+ bh.PelsPerMeterX=3780;
+ bh.PelsPerMeterY=3780;
+
+ if (BitCount==32) {
+ file.write((char*) &bfh, sizeof(BITMAP_FILEHEADER));
+ file.write((char*) &bh, sizeof(BITMAP_HEADER));
+ file.write((char*) m_bitmap_data, bh.SizeImage);
+ } else if (BitCount==16) {
+ uint8* Bitmap = new uint8[bh.SizeImage];
+ BGRA *Palette = 0;
+ uint32 PaletteSize = 0;
+
+ if (get_bits_with_palette(Bitmap, bh.SizeImage, BitCount, Palette, PaletteSize)) {
+ bfh.BitsOffset += PaletteSize * sizeof(BGRA);
+ file.write((char*) &bfh, BITMAP_FILEHEADER_SIZE);
+ file.write((char*) &bh, sizeof(BITMAP_HEADER));
+ file.write((char*) Palette, PaletteSize * sizeof(BGRA));
+ file.write((char*) Bitmap, bh.SizeImage);
+ }
+ delete [] Bitmap;
+ delete [] Palette;
+ } else {
+ uint32 RedMask = 0;
+ uint32 GreenMask = 0;
+ uint32 BlueMask = 0;
+ uint32 AlphaMask = 0;
+
+ if (BitCount == 16) {
+ RedMask = 0x0000F800;
+ GreenMask = 0x000007E0;
+ BlueMask = 0x0000001F;
+ AlphaMask = 0x00000000;
+ } else if (BitCount==24) {
+ RedMask = 0x00FF0000;
+ GreenMask = 0x0000FF00;
+ BlueMask = 0x000000FF;
+ } else {
+ result=false;
+ }
+ if (result) {
+ if (get_bits(NULL, bh.SizeImage, RedMask, GreenMask, BlueMask, AlphaMask)) {
+ uint8* Bitmap = new uint8[bh.SizeImage];
+ if (get_bits(Bitmap, bh.SizeImage, RedMask, GreenMask, BlueMask, AlphaMask)) {
+ file.write((char*) &bfh, sizeof(BITMAP_FILEHEADER));
+ file.write((char*) &bh, sizeof(BITMAP_HEADER));
+ file.write((char*) Bitmap, bh.SizeImage);
+ }
+ delete [] Bitmap;
+ }
+ }
+ }
+ file.close();
+ return result;
+}
+
+
+bool img_loader::save_PNG(char * filename)
+{
+ return (bool)write_png(filename, (uint8*)m_bitmap_data, get_width(), get_height(), get_bit_count());
+
+}
+
+
+bool img_loader::save_PXM(char * filename, int level)
+{
+ FILE *f=fopen(filename,"wb");
+ if (f==NULL) {
+ return false;
+ }
+ fprintf(f,"P%d\n#Simutrans PxM Writer\n%d\n%d\n",level,get_width(),get_height());
+ if (level!=1&&level!=4) {
+ fprintf(f,"255\n");
+ }
+ if (level<=6) {
+ for (uint32 y=0;y384) {
+ fprintf(f,"1 ");
+ } else {
+ fprintf(f,"0 ");
+ }
+ } else if (level==2) {
+ int v=(m_bitmap_data[location].Red+m_bitmap_data[location].Green+m_bitmap_data[location].Blue)/3;
+ if (v>255) {
+ v=255;
+ }
+ fprintf(f,"%d ",v);
+ } else if (level==3) {
+ fprintf(f,"%d %d %d\t",m_bitmap_data[location].Red,m_bitmap_data[location].Green,m_bitmap_data[location].Blue);
+ } else if (level==4) {
+ uint8 val=0;
+ for (int x2=0;x2<8;x2++) {
+ val=val<<1;
+ int v=m_bitmap_data[location+x2].Red+m_bitmap_data[location+x2].Green+m_bitmap_data[location+x2].Blue;
+ if (v>384) {
+ val+=1;
+ }
+
+ }
+ fputc(val,f);
+ x+=7;
+ } else if (level==5) {
+ int v=(m_bitmap_data[location].Red+m_bitmap_data[location].Green+m_bitmap_data[location].Blue)/3;
+ if (v>255) {
+ v=255;
+ }
+ fputc(v,f);
+ } else if (level==6) {
+ fputc(m_bitmap_data[location].Red,f);
+ fputc(m_bitmap_data[location].Green,f);
+ fputc(m_bitmap_data[location].Blue,f);
+ }
+ }
+ if (level<4) {
+ fprintf(f,"\n");
+ }
+ }
+ }
+ return false;
+}
+
+
+bool img_loader::is_greyscale(void)
+{
+ return m_greyscale;
+}
+
+
+ImgResult img_loader::load_png(const char *filename) {
+ unsigned char **block=new unsigned char * [1];
+ block[0]=(unsigned char *)malloc(1);
+ uint32 width=0;
+ uint32 height=0;
+ uint32 base_img_size=1;
+ if (!load_block(block,&width,&height,filename,base_img_size)) {
+ return IMGR_UNKNOWN_ERROR;
+ }
+ this->set_bits(block[0],width,height,0x0000FF00,0x00FF0000,0xFF000000,0x000000FF);
+ return IMGR_OK;
+}
+
+
+uint32 img_loader::read_next_number_pxm(std::ifstream& file) {
+ char c=file.get();
+ while ((c<'0')||(c>'9')) {
+ // If there is a # then the line is a comment - read to end of line
+ if (c=='#') {
+ while (c!='\n') {
+ c=file.get();
+ if (file.fail()) {
+ return -1;
+ }
+ }
+ if (file.fail()) {
+ return -1;
+ }
+ }
+ // get next character
+ c=file.get();
+ }
+ uint32 ret_val=0;
+ while ((c>='0')&&(c<='9')) {
+ ret_val*=10;
+ ret_val+=(c-'0');
+ if (file.fail()) {
+ return ret_val;
+ }
+ c=file.get();
+ }
+ file.unget();
+ return ret_val;
+}
+
+
+inline sint32 img_loader::standardize_number_pxm(sint32 val, sint32 maxval) {
+ if (maxval==255) {
+ return val;
+ } else if (maxval<255) {
+ return val*255/maxval;
+ } else {
+ int dif=maxval/256;
+ int ret=val/dif;
+ if (ret>255) {
+ return 255;
+ }
+ return ret;
+ }
+}
+
+ImgResult img_loader::load_pxm(const char* filename) {
+ std::ifstream file(filename, std::ios::binary | std::ios::in);
+ char signature[3]={0,0,0};
+ file.read(signature,2);
+ // convert second character of signature to level
+ uint8 level=signature[1]-'0';
+ if ((level<1)||(level>6)) {
+ // should never get here, as the value is checked before entering the function.
+ return IMGR_INVALID_FORMAT;
+ }
+
+ //char buffer[256];
+ bool binary_data=(level>=4);
+
+ // Read in the width and height of the image
+ int width=read_next_number_pxm(file);
+ int height=read_next_number_pxm(file);
+
+ // If width or height are negative an error has occured.
+ if ((width<0)||(height<0)) {
+ return IMGR_INVALID_FORMAT;
+ }
+
+ int maxval=1;
+ // If image is not Black and White read in the max value (can be up to 65535)
+ if ((level!=1)&&(level!=4)) {
+ maxval=read_next_number_pxm(file);
+ }
+ // Read in and check that we have a whitespace character
+ char c=file.get();
+ if ((c!=' ')&&(c!='\t')&&(c!='\n')&&(c!='\r')) {
+ return IMGR_INVALID_FORMAT;
+ }
+ m_bitmap_header.Width=width;
+ m_bitmap_header.Height=height;
+ m_bitmap_header.BitCount=32;
+ m_bitmap_header.Compression=3;
+ m_bitmap_size=width*height;
+
+ // Alocate space for bitmap data
+ m_bitmap_data=new RGBA[m_bitmap_size];
+
+ if (binary_data) {
+ // Read in Binary Data
+ if (level==4) {
+ // Black and white image encoded to individual bits, padded to a full byte for each line
+ int line_len=(width+7)/8;
+ char *buffer=new char [line_len];
+ for (int y=0;y=0;i--) {
+ if (x1255) {
+ r*=256;
+ r+=file.get();
+ }
+ r=standardize_number_pxm(r,maxval);
+ if (level==5) {
+ // If greyscale green and blue are the same value as red
+ g=r;
+ b=r;
+ } else {
+ // If color, read in green and blue values
+ g=file.get();
+ if (maxval>255) {
+ g*=256;
+ g+=file.get();
+ }
+ b=file.get();
+ if (maxval>255) {
+ b*=256;
+ b+=file.get();
+ }
+ g=standardize_number_pxm(g,maxval);
+ b=standardize_number_pxm(b,maxval);
+ }
+ int location=y*width+x;
+ m_bitmap_data[location].Red=r;
+ m_bitmap_data[location].Green=g;
+ m_bitmap_data[location].Blue=b;
+ m_bitmap_data[location].Alpha=0;
+ }
+ }
+ }
+ } else {
+ // Read in ASCII Data
+ for (int y=0;y 8192) {
+ m_bitmap_header.Width=8192;
+ }
+ return m_bitmap_header.Width<0?-m_bitmap_header.Width:m_bitmap_header.Width;
+}
+
+
+uint32 img_loader::get_height(void) {
+ if (abs(m_bitmap_header.Height) > 8192) {
+ m_bitmap_header.Height=8192;
+ }
+ return m_bitmap_header.Height<0?-m_bitmap_header.Height:m_bitmap_header.Height;
+}
+
+
+inline uint32 img_loader::get_bit_count() {
+ return m_bitmap_header.BitCount;
+}
+
+inline uint32 img_loader::color::bit_count_by_mask(uint32 mask) {
+ uint32 bit_count=0;
+ while (mask) {
+ mask&=mask-1;
+ bit_count++;
+ }
+ return bit_count;
+}
+
+inline uint32 img_loader::color::bit_position_by_mask(uint32 mask) {
+ return bit_count_by_mask((mask & (~mask + 1)) - 1);
+}
+
+inline uint32 img_loader::color::component_by_mask(uint32 color, uint32 mask) {
+ uint32 component=color&mask;
+ return component>>bit_position_by_mask(mask);
+}
+
+inline uint32 img_loader::color::bit_count_to_mask(uint32 bit_count) {
+ return (bit_count == 32)?0xFFFFFFFF:(1<>= (from_bit_count-to_bit_count);
+ } else {
+ color <<= (to_bit_count-from_bit_count);
+ if (color>0) {
+ color|=bit_count_to_mask(to_bit_count-from_bit_count);
+ }
+ }
+ return color;
+}
Index: utils/imgloader.h
===================================================================
--- utils/imgloader.h (nonexistent)
+++ utils/imgloader.h (working copy)
@@ -0,0 +1,213 @@
+#include "../simtypes.h"
+#ifndef IMGLOADER_H
+#define IMGLOADER_H
+
+/**
+ * \enum ImgResult
+ * ImgResult is for storing return values from the various functions in the img_loader class
+ */
+enum ImgResult {
+ IMGR_OK, /// Image Successfully Loaded
+ IMGR_NULL, /// NULL value passed
+ IMGR_FILE_DOES_NOT_EXIST, /// File refered to does not exist
+ IMGR_UNABLE_TO_OPEN, /// File refered to exists but is not able to be opened
+ IMGR_UNSUPPORTED_FORMAT, /// File refered to exists but is in an unsupported format
+ IMGR_INVALID_FORMAT, /// File refered to exists and indicates it is a supported format, but is not
+ IMGR_UNKNOWN_ERROR /// An unknown error occured...
+};
+
+#ifndef __LITTLE_ENDIAN__
+ #ifndef __BIG_ENDIAN__
+ #define __LITTLE_ENDIAN__
+ #endif
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+ #define BITMAP_SIGNATURE 0x4d42
+#else
+ #define BITMAP_SIGNATURE 0x424d
+#endif
+
+#pragma pack(push, 1)
+typedef struct _BITMAP_FILEHEADER {
+ uint16 Signature;
+ uint32 Size;
+ uint32 Reserved;
+ uint32 BitsOffset;
+} BITMAP_FILEHEADER;
+
+const int BITMAP_FILEHEADER_SIZE=14;
+
+typedef struct _BITMAP_HEADER {
+ uint32 HeaderSize;
+ sint32 Width;
+ sint32 Height;
+ uint16 Planes;
+ uint16 BitCount;
+ uint32 Compression;
+ uint32 SizeImage;
+ sint32 PelsPerMeterX;
+ sint32 PelsPerMeterY;
+ uint32 ClrUsed;
+ uint32 ClrImportant;
+ uint32 RedMask;
+ uint32 GreenMask;
+ uint32 BlueMask;
+ uint32 AlphaMask;
+ uint32 CsType;
+ uint32 Endpoints[9]; // see http://msdn2.microsoft.com/en-us/library/ms536569.aspx
+ uint32 GammaRed;
+ uint32 GammaGreen;
+ uint32 GammaBlue;
+} BITMAP_HEADER;
+
+typedef struct _RGBA {
+ uint8 Red;
+ uint8 Green;
+ uint8 Blue;
+ uint8 Alpha;
+} RGBA;
+
+typedef struct _BGRA {
+ uint8 Blue;
+ uint8 Green;
+ uint8 Red;
+ uint8 Alpha;
+} BGRA;
+
+#pragma pack(pop)
+
+/**
+ * \class img_loader
+ * The img_loader class is for the loading of images. It currently supports most BMP & PBM formats, and all PNG formats.
+ */
+class img_loader {
+ public:
+ /**
+ * img_loader constructor
+ * @param filename is an optional filename parameter to load an image.
+ */
+ img_loader(const char *filename=NULL);
+ ~img_loader();
+ /**
+ * load_image
+ * @param filename is the name/path to the file to load.
+ * @return Returns an ImgResult enum indicating the result of the attempt to load the file.
+ */
+ ImgResult load_image(const char *filename);
+ /**
+ * get_bits
+ * @return returns a void * array pointing to the ARGB buffer of this image.
+ */
+ void * get_bits();
+ /**
+ * get_bits
+ * @param buffer is a buffer for the image to be loaded into.
+ * @param buffer_size is the size of the buffer passed in
+ * @param red_mask is the mask that should be used for the red bits
+ * @param green_mask is the mask that should be used for the green bits
+ * @param blue_mask is the mask that should be used for the blue bits
+ * @param alpha_mask is an option mask that should be used for the alpha bits (defaults to 0)
+ * @param include_padding is an option to include padding on the image (defaults to false)
+ * @return Returns an ImgResult enum indicating the result of the attempt to load the file.
+ * Get Bits returns the image data in the format requested
+ */
+ ImgResult get_bits(void *buffer, uint32 &buffer_size, uint32 red_mask, uint32 green_mask,uint32 blue_mask,uint32 alpha_mask=0,bool include_padding=false);
+
+ /**
+ * set_bits
+ * @param buffer is a buffer to load the bits from
+ * @param width is the width of the image
+ * @param height is the height of the image
+ * @param red_mask is the mask that should be used for the red bits
+ * @param green_mask is the mask that should be used for the green bits
+ * @param blue_mask is the mask that should be used for the blue bits
+ * @param alpha_mask is an option mask that should be used for the alpha bits (defaults to 0)
+ * @return returns true on success, false of failure
+ * Set Bits sets the data from the format specified
+ */
+ bool set_bits(void *buffer, uint32 width, uint32 height, uint32 red_mask, uint32 green_mask, uint32 blue_mask,uint32 alpha_mask=0);
+
+ /**
+ * dispose
+ * Disposes of current Bitmap Data
+ */
+ void dispose(void);
+
+ /**
+ * save_BMP
+ * @param filename is the name to save the file as
+ * @param BitCount to save as, defaults to 32
+ * @return true on success, false on failure
+ * Saves the image as a BMP file
+ */
+ bool save_BMP(char * filename, uint32 BitCount=32);
+
+ /**
+ * save_PNG
+ * @param filename is the name to save the file as
+ * @return true on success, false on failure
+ * Saves the image as a PNG file
+ */
+ bool save_PNG(char * filename);
+
+ /**
+ * save_PBM
+ * @param filename is the name to save the file as
+ * @param level is the type of PBM to save as (defaults to P6)
+ * @return true on success, false on failure
+ * Saves the image as a PBM file
+ */
+ bool save_PXM(char * filename,int level=6);
+
+ /**
+ * is_greyscale
+ * @return Returns true if the image is Greyscale, false otherwise
+ * Returns true if the image is greyscale
+ */
+ bool is_greyscale(void);
+
+ /**
+ * get_width
+ * @return returns the width of the image
+ * Returns the width of the image - where no image is loaded, it will return 0
+ */
+ uint32 get_width(void);
+
+ /**
+ * get_height
+ * @return returns the height of the image
+ * Returns the height of the image - where no image is loaded, it will return 0
+ */
+ uint32 get_height(void);
+
+ /**
+ * get_bit_count
+ * @return returns the bit_count of the image
+ * Returns the bit_count of the image - where no image is loaded, it will return 0
+ */
+ uint32 get_bit_count(void);
+
+ class color {
+ public:
+ static uint32 bit_count_by_mask(uint32 mask);
+ static uint32 bit_position_by_mask(uint32 mask);
+ static uint32 component_by_mask(uint32 color, uint32 mask);
+ static uint32 bit_count_to_mask(uint32 bit_count);
+ static uint32 convert(uint32 color, uint32 from_bit_count, uint32 to_bit_count);
+ };
+ private:
+ ImgResult load_bmp(const char *filename);
+ ImgResult load_png(const char *filename);
+ ImgResult load_pxm(const char *filename);
+ uint32 read_next_number_pxm(std::ifstream& file);
+ sint32 standardize_number_pxm(sint32 val, sint32 maxval);
+ bool get_bits_with_palette(void* Buffer, uint32 &Size, uint32 BitCount, BGRA* &Palette, uint32 &PaletteSize, bool OptimalPalette=false, bool IncludePadding=true);
+ BITMAP_FILEHEADER m_bitmap_file_header;
+ BITMAP_HEADER m_bitmap_header;
+ RGBA *m_bitmap_data;
+ sint32 m_bitmap_size;
+ sint8 m_greyscale;
+
+};
+#endif