diff --git a/SConstruct b/SConstruct index 5c679f1c1..c05404919 100644 --- a/SConstruct +++ b/SConstruct @@ -49,58 +49,73 @@ def CheckProtobuf(context, version): context.Result(ret) return ret + AddOption('--cxx', dest='cxx', type='string', nargs=1, action='store', metavar='STRING', help='C++ Compiler') AddOption('--stxxlroot', dest='stxxlroot', type='string', nargs=1, action='store', metavar='STRING', help='root directory of STXXL') AddOption('--verbosity', dest='verbosity', type='string', nargs=1, action='store', metavar='STRING', help='make Scons talking') AddOption('--buildconfiguration', dest='buildconfiguration', type='string', nargs=1, action='store', metavar='STRING', help='debug or release') -env = Environment(ENV = {'PATH' : os.environ['PATH']} ,COMPILER = GetOption('cxx')) -if sys.platform.startswith("freebsd"): - env.ParseConfig('pkg-config --cflags --libs protobuf') + +env = Environment( ENV = {'PATH' : os.environ['PATH']} ,COMPILER = GetOption('cxx')) +conf = Configure(env, custom_tests = { 'CheckBoost' : CheckBoost, 'CheckProtobuf' : CheckProtobuf }) + + if GetOption('cxx') is None: #default Compiler print 'Using default C++ Compiler: ', env['CXX'] else: env.Replace(CXX = GetOption('cxx')) print 'Using user supplied C++ Compiler: ', env['CXX'] -if GetOption('stxxlroot') is not None: - env.Append(CPPPATH = GetOption('stxxlroot')+'/include') - env.Append(LIBPATH = GetOption('stxxlroot')+'/lib') - print 'STXXLROOT = ', GetOption('stxxlroot') -if sys.platform == 'win32': - #SCons really wants to use Microsoft compiler - print "Compiling is not yet supported on Windows" - Exit(-1) -else: #Mac OS X - if sys.platform == 'darwin': - print "Compiling is experimental on Mac" - env.Append(CPPPATH = ['/opt/local/include/', '/opt/local/include/libxml2']) - env.Append(LIBPATH = ['/opt/local/lib']) - elif sys.platform.startswith('freebsd'): - env.Append(CPPPATH = ['/usr/local/include', '/usr/local/include/libxml2']) - env.Append(LIBPATH = ['/usr/local/lib']) - else: - env.Append(CPPPATH = ['/usr/include', '/usr/include/include', '/usr/include/libxml2/']) + if GetOption('buildconfiguration') == 'debug': env.Append(CCFLAGS = ['-Wall', '-g3', '-rdynamic']) else: - env.Append(CCFLAGS = ['-O3', '-DNDEBUG', '-march=native']) -#print "Compiling with: ", env['CXX'] -conf = Configure(env, custom_tests = { 'CheckBoost' : CheckBoost, 'CheckProtobuf' : CheckProtobuf }) -if not conf.CheckHeader('omp.h'): - print "Compiler does not support OpenMP. Exiting" - if sys.platform == 'darwin': - print "Continuing because we are on Mac. This might be fatal." - else: + env.Append(CCFLAGS = ['-O3', '-DNDEBUG']) + + +if sys.platform == 'darwin': #Mac OS X + #os x default installations + env.Append(CPPPATH = ['/usr/include/libxml2'] ) + env.Append(CPPPATH = ["/usr/X11/include"]) #comes with os x + + #assume stxxl and boost are installed via homebrew. call brew binary to get folder locations + import subprocess + stxxl_prefix = subprocess.check_output(["brew", "--prefix", "libstxxl"]).strip() + env.Append(CPPPATH = [stxxl_prefix+"/include"] ) + env.Append(LIBPATH = [stxxl_prefix+"/lib"] ) + boost_prefix = subprocess.check_output(["brew", "--prefix", "boost"]).strip() + env.Append(CPPPATH = [boost_prefix+"/include"] ) + env.Append(LIBPATH = [boost_prefix+"/lib"] ) +elif sys.platform.startswith("freebsd"): + env.ParseConfig('pkg-config --cflags --libs protobuf') + env.Append(CPPPATH = ['/usr/local/include', '/usr/local/include/libxml2']) + env.Append(LIBPATH = ['/usr/local/lib']) + if GetOption('stxxlroot') is not None: + env.Append(CPPPATH = GetOption('stxxlroot')+'/include') + env.Append(LIBPATH = GetOption('stxxlroot')+'/lib') + print 'STXXLROOT = ', GetOption('stxxlroot') + if GetOption('buildconfiguration') != 'debug': + env.Append(CCFLAGS = ['-march=native']) + #print "Compiling with: ", env['CXX'] + if not conf.CheckHeader('omp.h'): + print "Compiler does not support OpenMP. Exiting" Exit(-1) + env.Append(CCFLAGS = ['-fopenmp']) + env.Append(LINKFLAGS = ['-fopenmp']) +elif sys.platform == 'win32': + #SCons really wants to use Microsoft compiler + print "Compiling is not yet supported on Windows" + Exit(-1) +else: + print "Unknown platform.." + env.Append(CPPPATH = ['/usr/include', '/usr/include/include', '/usr/include/libxml2/']) + + if not conf.CheckLibWithHeader('bz2', 'bzlib.h', 'CXX'): print "bz2 library not found. Exiting" Exit(-1) -if not conf.CheckLibWithHeader('png', 'png.h', 'CXX'): - print "png library or header not found. Exiting" +if not conf.CheckLibWithHeader('libzip', 'zip.h', 'CXX'): + print "Zip library not found. Exiting" Exit(-1) -if not conf.CheckLibWithHeader('pthread', 'pthread.h', 'CXX'): - print "pthread not found. Exiting" - Exit(-1) if not conf.CheckLibWithHeader('protobuf', 'google/protobuf/descriptor.h', 'CXX'): print "Google Protobuffer library not found. Exiting" Exit(-1) @@ -120,16 +135,10 @@ if not conf.CheckLibWithHeader('xml2', 'libxml/xmlreader.h', 'CXX'): if not conf.CheckLibWithHeader('z', 'zlib.h', 'CXX'): print "zlib library or header not found. Exiting" Exit(-1) -if not conf.CheckLibWithHeader('zip', 'zip.h', 'CXX'): - print "Zip library not found. Exiting" - Exit(-1) #Check BOOST installation if not (conf.CheckBoost('1.41')): print 'Boost version >= 1.41 needed' Exit(-1); -if not conf.CheckLib('boost_system', language="C++"): - print "boost_system library not found. Exiting" - Exit(-1) if not conf.CheckLibWithHeader('boost_thread', 'boost/thread.hpp', 'CXX'): if not conf.CheckLibWithHeader('boost_thread-mt', 'boost/thread.hpp', 'CXX'): print "boost thread library not found. Exiting" @@ -139,14 +148,21 @@ if not conf.CheckLibWithHeader('boost_thread', 'boost/thread.hpp', 'CXX'): env.Append(CCFLAGS = ' -lboost_thread-mt') env.Append(LINKFLAGS = ' -lboost_thread-mt') if not conf.CheckLibWithHeader('boost_regex', 'boost/regex.hpp', 'CXX'): - print "boost/regex.hpp not found. Exiting" - Exit(-1) -if not conf.CheckCXXHeader('boost/array.hpp'): - print "boost/thread.hpp not found. Exiting" - Exit(-1) -if not conf.CheckCXXHeader('boost/asio.hpp'): - print "boost/thread.hpp not found. Exiting" - Exit(-1) + if not conf.CheckLibWithHeader('boost_regex-mt', 'boost/regex.hpp', 'CXX'): + print "boost/regex.hpp not found. Exiting" + Exit(-1) + else: + print "using boost_regex -mt" + env.Append(CCFLAGS = ' -lboost_regex-mt') + env.Append(LINKFLAGS = ' -lboost_regex-mt') +if not conf.CheckLib('boost_system', language="C++"): + if not conf.CheckLib('boost_system-mt', language="C++"): + print "boost_system library not found. Exiting" + Exit(-1) + else: + print "using boost -mt" + env.Append(CCFLAGS = ' -lboost_system-mt') + env.Append(LINKFLAGS = ' -lboost_system-mt') if not conf.CheckCXXHeader('boost/bind.hpp'): print "boost/bind.hpp not found. Exiting" Exit(-1) @@ -189,18 +205,25 @@ if not conf.CheckCXXHeader('boost/tuple/tuple.hpp'): if not conf.CheckCXXHeader('boost/unordered_map.hpp'): print "boost thread header not found. Exiting" Exit(-1) +#if os.sysconf('SC_NPROCESSORS_ONLN') > 1: +# env.Append(CCFLAGS = ' -D_GLIBCXX_PARALLEL'); +if not (conf.CheckBoost('1.41')): + print 'Boost version >= 1.41 needed' + Exit(-1); +#check for protobuf 2.3.0, else rebuild proto files +if not (conf.CheckProtobuf('2.3.0')): + print 'libprotobuf version >= 2.3.0 needed' + Exit(-1); +if not (env.Detect('protoc')): + print 'protobuffer compiler not found' + protobld = Builder(action = 'protoc -I=DataStructures/pbf-proto --cpp_out=DataStructures/pbf-proto $SOURCE') env.Append(BUILDERS = {'Protobuf' : protobld}) env.Protobuf('DataStructures/pbf-proto/fileformat.proto') env.Protobuf('DataStructures/pbf-proto/osmformat.proto') -env.Append(CCFLAGS = ['-fopenmp']) -env.Append(LINKFLAGS = ['-fopenmp']) env.Program(target = 'osrm-extract', source = ["extractor.cpp", Glob('DataStructures/pbf-proto/*.pb.cc'), Glob('Util/*.cpp')]) env.Program(target = 'osrm-prepare', source = ["createHierarchy.cpp", 'Contractor/EdgeBasedGraphFactory.cpp', Glob('Util/SRTMLookup/*.cpp'), Glob('Algorithms/*.cpp')]) -env.Append(CCFLAGS = ['-lboost_regex', '-lboost_iostreams', '-lbz2', '-lz', '-lprotobuf']) -env.Append(LINKFLAGS = ['-lboost_system']) env.Program(target = 'osrm-routed', source = ["routed.cpp", 'Descriptors/DescriptionFactory.cpp', Glob('ThirdParty/*.cc')], CCFLAGS = env['CCFLAGS'] + ['-DROUTED']) env = conf.Finish() - diff --git a/ThirdParty/PngImage.cc b/ThirdParty/PngImage.cc index 9034663b8..b004974ff 100644 --- a/ThirdParty/PngImage.cc +++ b/ThirdParty/PngImage.cc @@ -22,321 +22,107 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================*/ -#include "PngImage.hh" +#ifndef PNG_IMAGE_HH +#define PNG_IMAGE_HH -#include +#include +#include -#include -#include -#include - -PngImage::PngImage(): - mImageData(0), mImageWidth(0), mImageHeight(0) -{} - -PngImage::PngImage(int width, int height, - unsigned char red, unsigned char green, - unsigned char blue, unsigned char alpha): - mImageData(0) +class PngImage { - createImage(width, height, red, green, blue, alpha); + public: + // Constructor, destructor and copying + // ----------------------------------- + PngImage(); + PngImage(int width, int height, + unsigned char red = 0, unsigned char green = 0, + unsigned char blue = 0, unsigned char alpha = 255); + ~PngImage(); + + // If there is image data, these will perform deep copying. + PngImage(const PngImage&); + PngImage& operator=(const PngImage&); + + // Delete the image data, freeing the memory + void deleteImageData(); + + + // Load image + // ---------- + bool loadImage(const char* filename, bool printErrorMsg = true); + bool loadImage(const std::string& filename, bool printErrorMsg = true); + + bool loadImageFromMemory(const unsigned char* data, unsigned dataSize); + + + // Create image (rather than loading one) + // -------------------------------------- + void createImage(int width, int height, + unsigned char red = 0, unsigned char green = 0, + unsigned char blue = 0, unsigned char alpha = 255); + + + // Save image + // ---------- + bool saveImage(const char* filename, bool printErrorMsg = true) const; + bool saveImage(const std::string& filename, + bool printErrorMsg = true) const; + + + // Image data access + // ----------------- + int width() const; + int height() const; + + unsigned char* rawImagePtr(); + const unsigned char* rawImagePtr() const; + + void setPixel(int x, int y, + unsigned char red, unsigned char green, unsigned char blue, + unsigned char alpha = 255); + + unsigned char getColorComponent(int x, int y, int component) const; + + + void drawImageAt(const PngImage&, int x, int y); + + + +//-------------------------------------------------------------------------- + private: + unsigned char* mImageData; + int mImageWidth, mImageHeight; +}; + +inline int PngImage::width() const { return mImageWidth; } +inline int PngImage::height() const { return mImageHeight; } + +inline unsigned char* PngImage::rawImagePtr() +{ return mImageData; } + +inline const unsigned char* PngImage::rawImagePtr() const +{ return mImageData; } + +inline void PngImage::setPixel(int x, int y, + unsigned char red, unsigned char green, + unsigned char blue, unsigned char alpha) +{ + assert(x >= 0 && mImageWidth > x && y >= 0 && mImageHeight > y); + + unsigned char* ptr = mImageData + 4 * (x + y*mImageWidth); + ptr[0] = red; + ptr[1] = green; + ptr[2] = blue; + ptr[3] = alpha; } -PngImage::~PngImage() +inline unsigned char +PngImage::getColorComponent(int x, int y, int component) const { - delete[] mImageData; + assert(x >= 0 && mImageWidth > x && y >= 0 && mImageHeight > y); + assert(component >= 0 && component < 4); + + return mImageData[4 * (x + y*mImageWidth) + component]; } -PngImage::PngImage(const PngImage& rhs): - mImageData(0), - mImageWidth(rhs.mImageWidth), mImageHeight(rhs.mImageHeight) -{ - if(rhs.mImageData) - { - const int size = mImageWidth*mImageHeight*4; - mImageData = new unsigned char[size]; - std::memcpy(mImageData, rhs.mImageData, size); - } -} - -PngImage& PngImage::operator=(const PngImage& rhs) -{ - if(mImageData != rhs.mImageData) - { - delete[] mImageData; - mImageWidth = rhs.mImageWidth; - mImageHeight = rhs.mImageHeight; - if(rhs.mImageData) - { - const int size = mImageWidth*mImageHeight*4; - mImageData = new unsigned char[size]; - std::memcpy(mImageData, rhs.mImageData, size); - } - else - mImageData = 0; - } - return *this; -} - -void PngImage::deleteImageData() -{ - delete[] mImageData; - mImageData = 0; - mImageWidth = mImageHeight = 0; -} - -void PngImage::createImage(int width, int height, - unsigned char red, unsigned char green, - unsigned char blue, unsigned char alpha) -{ - assert(width > 0 && height > 0); - - delete[] mImageData; - const int size = width*height*4; - mImageData = new unsigned char[size]; - mImageWidth = width; - mImageHeight = height; - - for(int i = 0; i < size; i += 4) - { - mImageData[i] = red; - mImageData[i+1] = green; - mImageData[i+2] = blue; - mImageData[i+3] = alpha; - } -} - -namespace -{ - struct FilePtr - { - std::FILE* fp; - - FilePtr(): fp(0) {} - ~FilePtr() { if(fp) std::fclose(fp); } - }; - - struct PNGStructPtrs - { - png_structp read; - png_structp write; - png_infop info; - - PNGStructPtrs(): read(0), write(0), info(0) {} - - ~PNGStructPtrs() - { - if(read) - { - if(info) png_destroy_read_struct(&read, &info, 0); - else png_destroy_read_struct(&read, 0, 0); - } - else if(write) - { - if(info) png_destroy_write_struct(&write, &info); - else png_destroy_write_struct(&write, 0); - } - } - }; - - void readPngData(PNGStructPtrs& ptrs, - unsigned char* & imageData, - int& imageWidth, int& imageHeight) - { - png_read_info(ptrs.read, ptrs.info); - - imageData = new unsigned char[4 * ptrs.info->width * ptrs.info->height]; - imageWidth = ptrs.info->width; - imageHeight = ptrs.info->height; - - png_set_expand(ptrs.read); - png_set_filler(ptrs.read, 0xff, PNG_FILLER_AFTER); - png_set_palette_to_rgb(ptrs.read); - png_set_gray_to_rgb(ptrs.read); - png_set_strip_16(ptrs.read); - - unsigned char* addr = imageData; - for(int i = 0; i < imageHeight; ++i) - { - png_read_rows(ptrs.read, (png_bytepp) &addr, 0, 1); - addr += imageWidth * 4; - } - - png_read_end(ptrs.read, ptrs.info); - } -} - -bool PngImage::loadImage(const char* filename, bool printErrorMsg) -{ - deleteImageData(); - - FilePtr iFile; - iFile.fp = std::fopen(filename, "rb"); - if(!iFile.fp) - { - if(printErrorMsg) - { - std::fprintf(stderr, "Can't open "); - std::perror(filename); - } - return false; - } - - png_byte header[8]; - std::fread(header, 1, 8, iFile.fp); - if(png_sig_cmp(header, 0, 8)) - { - if(printErrorMsg) - std::fprintf(stderr, "%s is not a PNG file.\n", filename); - return false; - } - std::fseek(iFile.fp, 0, SEEK_SET); - - PNGStructPtrs ptrs; - ptrs.read = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if(!ptrs.read) - { - if(printErrorMsg) - std::fprintf(stderr, "Initializing libpng failed.\n"); - return false; - } - - ptrs.info = png_create_info_struct(ptrs.read); - if(!ptrs.info) - { - if(printErrorMsg) - std::fprintf(stderr, "Initializing libpng failed.\n"); - return false; - } - - if(setjmp(ptrs.read->jmpbuf)) return false; - - png_init_io(ptrs.read, iFile.fp); - readPngData(ptrs, mImageData, mImageWidth, mImageHeight); - return true; -} - -bool PngImage::loadImage(const std::string& filename, bool printErrorMsg) -{ - return loadImage(filename.c_str(), printErrorMsg); -} - -namespace -{ - const unsigned char* gPngData; - size_t gPngDataSize, gCurrentPngDataIndex; - - void pngDataReader(png_structp png_ptr, png_bytep data, - png_size_t length) - { - if(gCurrentPngDataIndex + length > gPngDataSize) - png_error(png_ptr, "Read error"); - else - { - std::memcpy(data, gPngData+gCurrentPngDataIndex, length); - gCurrentPngDataIndex += length; - } - } -} - -bool PngImage::loadImageFromMemory(const unsigned char* data, unsigned dataSize) -{ - deleteImageData(); - - gPngData = data; - gPngDataSize = dataSize; - gCurrentPngDataIndex = 0; - - PNGStructPtrs ptrs; - ptrs.read = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if(!ptrs.read) return false; - - png_set_read_fn(ptrs.read, 0, pngDataReader); - - ptrs.info = png_create_info_struct(ptrs.read); - if(!ptrs.info) return false; - - if(setjmp(ptrs.read->jmpbuf)) return false; - readPngData(ptrs, mImageData, mImageWidth, mImageHeight); - return true; -} - -bool PngImage::saveImage(const char* filename, bool printErrorMsg) const -{ - if(!mImageData) return true; - - FilePtr oFile; - oFile.fp = std::fopen(filename, "wb"); - if(!oFile.fp) - { - if(printErrorMsg) - { - std::fprintf(stderr, "Can't write to "); - std::perror(filename); - } - return false; - } - - PNGStructPtrs ptrs; - ptrs.write = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if(!ptrs.write) - { - if(printErrorMsg) - std::fprintf(stderr, "Initializing libpng failed.\n"); - return false; - } - - ptrs.info = png_create_info_struct(ptrs.write); - if(!ptrs.info) - { - if(printErrorMsg) - std::fprintf(stderr, "Initializing libpng failed.\n"); - return false; - } - - if(setjmp(ptrs.write->jmpbuf)) return false; - - png_init_io(ptrs.write, oFile.fp); - - png_set_IHDR(ptrs.write, ptrs.info, mImageWidth, mImageHeight, 8, - PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_write_info(ptrs.write, ptrs.info); - - for(int i = 0; i < mImageHeight; ++i) - png_write_row(ptrs.write, mImageData + i*mImageWidth*4); - - png_write_end(ptrs.write, 0); - return true; -} - -bool PngImage::saveImage(const std::string& filename, bool printErrorMsg) const -{ - return saveImage(filename.c_str(), printErrorMsg); -} - -void PngImage::drawImageAt(const PngImage& src, int x, int y) -{ - if(!mImageData || !src.mImageData) return; - - for(int yInd = 0; yInd < src.mImageHeight; ++yInd) - { - const int destY = y + yInd; - if(destY >= 0 && destY < mImageHeight) - { - unsigned char* srcPtr = src.mImageData + 4*yInd*src.mImageWidth; - for(int xInd = 0; xInd < src.mImageWidth; ++xInd) - { - const int destX = x + xInd; - if(destX >= 0 && destX < mImageWidth) - { - unsigned char* destPtr = - mImageData + 4*(destX + destY*mImageWidth); - for(int i = 0; i < 4; ++i) - destPtr[i] = srcPtr[i]; - } - srcPtr += 4; - } - } - } -} +#endif