Created
November 10, 2013 17:22
-
-
Save panzi/7401096 to your computer and use it in GitHub Desktop.
Usage: visprim <width> <height> <output-filename> [number-of-threads]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CPP = g++ | |
LIB = `Magick++-config --cppflags --cxxflags --ldflags --libs` -lboost_thread-mt | |
CPPFLAGS = -Wall -O3 `Magick++-config --cppflags --cxxflags` | |
LDFLAGS = $(LIB) -Wall -O3 | |
BIN = visprim | |
.PHONY: all zip clean | |
all: $(BIN) | |
$(BIN): visprim.cpp | |
$(CPP) $< -o $@ $(LDFLAGS) | |
zip: visprim.zip | |
visprim.zip: | |
zip -r9 visprim.zip visprim.cpp Makefile | |
clean: | |
rm -f $(BIN) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <iostream> | |
#include <iomanip> | |
#include <boost/lexical_cast.hpp> | |
#include <boost/thread.hpp> | |
#include <Magick++.h> | |
using namespace std; | |
using namespace boost; | |
using namespace Magick; | |
void usage(const char * appname) { | |
cout << "Usage: " << appname << " <width> <height> <output-filename> [number-of-threads]" << endl; | |
} | |
bool inline isprime(unsigned int n) { | |
if (n == 2) { | |
return true; | |
} | |
else if (!(n & 1) || n < 2) { | |
return false; | |
} | |
else { | |
unsigned int stop = (unsigned int)ceil(sqrt((double)n)); | |
for (unsigned int p = 3; p <= stop; p += 2) { | |
if (n % p == 0) { | |
return false; | |
} | |
} | |
return true; | |
} | |
} | |
class Worker { | |
private: | |
PixelPacket *const pixel_cache; | |
const unsigned int begin; | |
const unsigned int end; | |
public: | |
Worker(PixelPacket *pixel_cache, unsigned int begin, unsigned int end) : | |
pixel_cache(pixel_cache), begin(begin), end(end) {} | |
void operator () () const { | |
const ColorRGB red( 1, 0, 0 ); | |
for (unsigned int i = begin; i < end; ++ i) { | |
if (isprime(i)) { | |
pixel_cache[i] = red; | |
} | |
} | |
} | |
}; | |
int main(int argc, char * argv[]) { | |
if (argc < 4 || argc > 5) { | |
cerr << "*** illegal number of arguments" << endl; | |
if (argc < 1) { | |
usage("visprim"); | |
} | |
else { | |
usage(*argv); | |
} | |
return 1; | |
} | |
unsigned int width; | |
unsigned int height; | |
unsigned int threadcount = 1; | |
const char * filename = argv[3]; | |
try { | |
width = lexical_cast<unsigned int>(argv[1]); | |
height = lexical_cast<unsigned int>(argv[2]); | |
if (argc == 5) { | |
threadcount = lexical_cast<unsigned int>(argv[4]); | |
} | |
} | |
catch (bad_lexical_cast &) { | |
cerr << "*** illegal argument" << endl; | |
usage(*argv); | |
return 1; | |
} | |
if (threadcount == 0) { | |
cerr << "*** illegal argument" << endl; | |
usage(*argv); | |
return 1; | |
} | |
Image image( Geometry( width, height ), ColorRGB( 1, 1, 1 ) ); | |
// Ensure that there are no other references to this image | |
image.modifyImage(); | |
image.type(TrueColorType); | |
PixelPacket *pixel_cache = image.getPixels(0,0,width,height); | |
unsigned int n = width * height; | |
if (threadcount == 1) { | |
Worker(pixel_cache, 0, n)(); | |
} | |
else { | |
thread_group threads; | |
unsigned int begin = 0; | |
double segment = ((double)n * (double)n) / (threadcount * 2.0l); | |
double area = 0; | |
double x = 0; | |
for (unsigned int i = 0; i < threadcount - 1; ++ i) { | |
area += segment; | |
x = sqrt(2.0l * area); | |
unsigned int end = (unsigned int) x; | |
threads.create_thread( Worker(pixel_cache, begin, end) ); | |
begin = end; | |
} | |
threads.create_thread( Worker(pixel_cache, begin, n) ); | |
threads.join_all(); | |
} | |
// Save changes to underlying image | |
image.syncPixels(); | |
image.write( filename ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment