Skip to content

Commit 8aee0a8

Browse files
committed
Sources du TP n°2
0 parents  commit 8aee0a8

27 files changed

+14596
-0
lines changed

Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Makefile TD n°2
2+
CXX = g++ -std=c++14
3+
CXXFLAGS = -O2 -Wall -pedantic -march=native
4+
#CXXFLAGS = -g -Wall -pedantic -march=native
5+
LIBS = -lm
6+
7+
all: Mandelbrot.exe matvec.exe
8+
9+
Mandelbrot.exe: Mandelbrot.cpp lodepng/lodepng.cpp
10+
$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
11+
12+
matvec.exe: matvec.cpp
13+
$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
14+
15+
cleanall:
16+
@rm -rf *.o *~ *.exe

Mandelbrot.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# include <iostream>
2+
# include <cstdlib>
3+
# include <string>
4+
# include <chrono>
5+
# include <cmath>
6+
# include "lodepng/lodepng.h"
7+
8+
/** Une structure complexe est définie pour la bonne raison que la classe
9+
* complex proposée par g++ est très lente ! Le calcul est bien plus rapide
10+
* avec la petite structure donnée ci--dessous
11+
**/
12+
struct Complex
13+
{
14+
Complex() : real(0.), imag(0.)
15+
{}
16+
Complex(double r, double i) : real(r), imag(i)
17+
{}
18+
Complex operator + ( const Complex& z )
19+
{
20+
return Complex(real + z.real, imag + z.imag );
21+
}
22+
Complex operator * ( const Complex& z )
23+
{
24+
return Complex(real*z.real-imag*z.imag, real*z.imag+imag*z.real);
25+
}
26+
double sqNorm() { return real*real + imag*imag; }
27+
double real,imag;
28+
};
29+
30+
/** Pour un c complexe donné, calcul le nombre d'itérations de mandelbrot
31+
* nécessaires pour détecter une éventuelle divergence. Si la suite
32+
* converge, la fonction retourne la valeur maxIter
33+
**/
34+
int iterMandelbrot( int maxIter, const Complex& c)
35+
{
36+
Complex z{0.,0.};
37+
// On vérifie dans un premier temps si le complexe
38+
// n'appartient pas à une zone de convergence connue :
39+
// Appartenance aux disques C0{(0,0),1/4} et C1{(-1,0),1/4}
40+
if ( c.real*c.real+c.imag*c.imag < 0.0625 )
41+
return maxIter;
42+
if ( (c.real+1)*(c.real+1)+c.imag*c.imag < 0.0625 )
43+
return maxIter;
44+
// Appartenance à la cardioïde {(1/4,0),1/2(1-cos(theta))}
45+
if ((c.real > -0.75) && (c.real < 0.5) ) {
46+
Complex ct{c.real-0.25,c.imag};
47+
double ctnrm2 = sqrt(ct.sqNorm());
48+
if (ctnrm2 < 0.5*(1-ct.real/ctnrm2)) return maxIter;
49+
}
50+
int niter = 0;
51+
while ((z.sqNorm() < 4.) && (niter < maxIter))
52+
{
53+
z = z*z + c;
54+
++niter;
55+
}
56+
return niter;
57+
}
58+
59+
/**
60+
* On parcourt chaque pixel de l'espace image et on fait correspondre par
61+
* translation et homothétie une valeur complexe c qui servira pour
62+
* itérer sur la suite de Mandelbrot. Le nombre d'itérations renvoyé
63+
* servira pour construire l'image finale.
64+
**/
65+
std::vector<int> computeMandelbrotSet( int W, int H, int maxIter )
66+
{
67+
std::chrono::time_point<std::chrono::system_clock> start, end;
68+
// Calcul le facteur d'échelle pour rester dans le disque de rayon 2
69+
// centré en (0,0)
70+
double scaleX = 3./(W-1);
71+
double scaleY = 2.25/(H-1);
72+
//
73+
std::vector<int> pixels(W*H);
74+
start = std::chrono::system_clock::now();
75+
// On parcourt les pixels de l'espace image :
76+
for ( int i = 0; i < H; ++i )
77+
for ( int j = 0; j < W; ++j ) {
78+
Complex c{-2.+j*scaleX,-1.125+i*scaleY};
79+
pixels[i*W+j] = iterMandelbrot( maxIter, c );
80+
}
81+
end = std::chrono::system_clock::now();
82+
std::chrono::duration<double> elapsed_seconds = end-start;
83+
std::cout << "Temps calcul ensemble mandelbrot : " << elapsed_seconds.count()
84+
<< std::endl;
85+
return pixels;
86+
}
87+
88+
/** Construit et sauvegarde l'image finale **/
89+
void savePicture( const std::string& fileName, int W, int H, const std::vector<int>& nbIters, int maxIter )
90+
{
91+
std::vector<unsigned char> image(4*W*H);
92+
double scaleCol = 1./maxIter;//16777216
93+
for ( int i = 0; i < H; ++i ) {
94+
for ( int j = 0; j < W; ++j ) {
95+
double iter = scaleCol*nbIters[i*W+j];
96+
unsigned r = unsigned (iter*256.) & 0xFF;
97+
unsigned b = (unsigned (iter*65536) & 0xFF);
98+
unsigned g = (unsigned( iter*16777216) & 0xFF);
99+
image[4*(i*W+j)+0] = (unsigned char)(256-r);
100+
image[4*(i*W+j)+1] = (unsigned char)(256-g);
101+
image[4*(i*W+j)+2] = (unsigned char)(256-b);
102+
image[4*(i*W+j)+3] = 255;
103+
}
104+
}
105+
unsigned error = lodepng::encode(fileName.c_str(), image, W, H);
106+
107+
//if there's an error, display it
108+
if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
109+
}
110+
111+
int main()
112+
{
113+
const int W = 800;
114+
const int H = 600;
115+
// Normalement, pour un bon rendu, il faudrait le nombre d'itérations
116+
// ci--dessous :
117+
//const int maxIter = 16777216;
118+
const int maxIter = 8*65536;
119+
auto iters = computeMandelbrotSet( W, H, maxIter );
120+
savePicture("mandelbrot.png", W, H, iters, maxIter);
121+
return EXIT_SUCCESS;
122+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# TP n°2 : MPI et messages collectifs

lodepng/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
LodePNG
2+
-------
3+
4+
PNG encoder and decoder in C and C++.
5+
6+
Home page: http://lodev.org/lodepng/
7+
8+
Only two files are needed to allow your program to read and write PNG files: lodepng.cpp and lodepng.h.
9+
10+
For C, you can rename lodepng.cpp to lodepng.c and it'll work. C++ only adds extra API.
11+
12+
The other files in the project are just examples, unit tests, etc...
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
LodePNG Examples
3+
4+
Copyright (c) 2005-2012 Lode Vandevenne
5+
6+
This software is provided 'as-is', without any express or implied
7+
warranty. In no event will the authors be held liable for any damages
8+
arising from the use of this software.
9+
10+
Permission is granted to anyone to use this software for any purpose,
11+
including commercial applications, and to alter it and redistribute it
12+
freely, subject to the following restrictions:
13+
14+
1. The origin of this software must not be misrepresented; you must not
15+
claim that you wrote the original software. If you use this software
16+
in a product, an acknowledgment in the product documentation would be
17+
appreciated but is not required.
18+
19+
2. Altered source versions must be plainly marked as such, and must not be
20+
misrepresented as being the original software.
21+
22+
3. This notice may not be removed or altered from any source
23+
distribution.
24+
*/
25+
26+
//g++ lodepng.cpp example_4bit_palette.cpp -ansi -pedantic -Wall -Wextra -O3
27+
28+
29+
30+
/*
31+
LodePNG 4-bit palette example.
32+
This example encodes a 511x511 PNG with a 4-bit palette.
33+
Both image and palette contain sine waves, resulting in a sort of plasma.
34+
The 511 (rather than power of two 512) size is of course chosen on purpose to
35+
confirm that scanlines not filling up an entire byte size are working.
36+
37+
NOTE: a PNG image with a translucent palette is perfectly valid. However there
38+
exist some programs that cannot correctly read those, including, surprisingly,
39+
Gimp 2.8 image editor (until you set mode to RGB).
40+
*/
41+
42+
#include <cmath>
43+
#include <iostream>
44+
45+
#include "lodepng.h"
46+
47+
int main(int argc, char *argv[])
48+
{
49+
//check if user gave a filename
50+
if(argc < 2)
51+
{
52+
std::cout << "please provide a filename to save to" << std::endl;
53+
return 0;
54+
}
55+
56+
//create encoder and set settings and info (optional)
57+
lodepng::State state;
58+
59+
//generate palette
60+
for(int i = 0; i < 16; i++)
61+
{
62+
unsigned char r = 127 * (1 + std::sin(5 * i * 6.28318531 / 16));
63+
unsigned char g = 127 * (1 + std::sin(2 * i * 6.28318531 / 16));
64+
unsigned char b = 127 * (1 + std::sin(3 * i * 6.28318531 / 16));
65+
unsigned char a = 63 * (1 + std::sin(8 * i * 6.28318531 / 16)) + 128; /*alpha channel of the palette (tRNS chunk)*/
66+
67+
//palette must be added both to input and output color mode, because in this
68+
//sample both the raw image and the expected PNG image use that palette.
69+
lodepng_palette_add(&state.info_png.color, r, g, b, a);
70+
lodepng_palette_add(&state.info_raw, r, g, b, a);
71+
}
72+
73+
//both the raw image and the encoded image must get colorType 3 (palette)
74+
state.info_png.color.colortype = LCT_PALETTE; //if you comment this line, and create the above palette in info_raw instead, then you get the same image in a RGBA PNG.
75+
state.info_png.color.bitdepth = 4;
76+
state.info_raw.colortype = LCT_PALETTE;
77+
state.info_raw.bitdepth = 4;
78+
state.encoder.auto_convert = 0; //we specify ourselves exactly what output PNG color mode we want
79+
80+
//generate some image
81+
const unsigned w = 511;
82+
const unsigned h = 511;
83+
std::vector<unsigned char> image;
84+
image.resize((w * h * 4 + 7) / 8, 0);
85+
for(unsigned y = 0; y < h; y++)
86+
for(unsigned x = 0; x < w; x++)
87+
{
88+
size_t byte_index = (y * w + x) / 2;
89+
bool byte_half = (y * w + x) % 2 == 1;
90+
91+
int color = (int)(4 * ((1 + std::sin(2.0 * 6.28318531 * x / (double)w))
92+
+ (1 + std::sin(2.0 * 6.28318531 * y / (double)h))) );
93+
94+
image[byte_index] |= (unsigned char)(color << (byte_half ? 0 : 4));
95+
}
96+
97+
//encode and save
98+
std::vector<unsigned char> buffer;
99+
unsigned error = lodepng::encode(buffer, image.empty() ? 0 : &image[0], w, h, state);
100+
if(error)
101+
{
102+
std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
103+
return 0;
104+
}
105+
lodepng::save_file(buffer, argv[1]);
106+
}

lodepng/examples/example_bmp2png.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
LodePNG Examples
3+
4+
Copyright (c) 2005-2010 Lode Vandevenne
5+
6+
This software is provided 'as-is', without any express or implied
7+
warranty. In no event will the authors be held liable for any damages
8+
arising from the use of this software.
9+
10+
Permission is granted to anyone to use this software for any purpose,
11+
including commercial applications, and to alter it and redistribute it
12+
freely, subject to the following restrictions:
13+
14+
1. The origin of this software must not be misrepresented; you must not
15+
claim that you wrote the original software. If you use this software
16+
in a product, an acknowledgment in the product documentation would be
17+
appreciated but is not required.
18+
19+
2. Altered source versions must be plainly marked as such, and must not be
20+
misrepresented as being the original software.
21+
22+
3. This notice may not be removed or altered from any source
23+
distribution.
24+
*/
25+
26+
/*
27+
Load a BMP image and convert it to a PNG image. This example also shows how
28+
to use other data with the same memory structure as BMP, such as the image
29+
format native to win32, GDI (HBITMAP, BITMAPINFO, ...) often encountered if
30+
you're programming for Windows in Visual Studio.
31+
32+
This example only supports uncompressed 24-bit RGB or 32-bit RGBA bitmaps.
33+
For other types of BMP's, use a full fledged BMP decoder, or convert the
34+
bitmap to 24-bit or 32-bit format.
35+
36+
NOTE: it overwrites the output file without warning if it exists!
37+
*/
38+
39+
//g++ lodepng.cpp example_bmp2png.cpp -ansi -pedantic -Wall -Wextra -O3
40+
41+
#include "lodepng.h"
42+
43+
#include <iostream>
44+
45+
//returns 0 if all went ok, non-0 if error
46+
//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel
47+
unsigned decodeBMP(std::vector<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& bmp)
48+
{
49+
static const unsigned MINHEADER = 54; //minimum BMP header size
50+
51+
if(bmp.size() < MINHEADER) return -1;
52+
if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM'
53+
unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts
54+
//read width and height from BMP header
55+
w = bmp[18] + bmp[19] * 256;
56+
h = bmp[22] + bmp[23] * 256;
57+
//read number of channels from BMP header
58+
if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported.
59+
unsigned numChannels = bmp[28] / 8;
60+
61+
//The amount of scanline bytes is width of image times channels, with extra bytes added if needed
62+
//to make it a multiple of 4 bytes.
63+
unsigned scanlineBytes = w * numChannels;
64+
if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4;
65+
66+
unsigned dataSize = scanlineBytes * h;
67+
if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels
68+
69+
image.resize(w * h * 4);
70+
71+
/*
72+
There are 3 differences between BMP and the raw image buffer for LodePNG:
73+
-it's upside down
74+
-it's in BGR instead of RGB format (or BRGA instead of RGBA)
75+
-each scanline has padding bytes to make it a multiple of 4 if needed
76+
The 2D for loop below does all these 3 conversions at once.
77+
*/
78+
for(unsigned y = 0; y < h; y++)
79+
for(unsigned x = 0; x < w; x++)
80+
{
81+
//pixel start byte position in the BMP
82+
unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x;
83+
//pixel start byte position in the new raw image
84+
unsigned newpos = 4 * y * w + 4 * x;
85+
if(numChannels == 3)
86+
{
87+
image[newpos + 0] = bmp[bmpos + 2]; //R
88+
image[newpos + 1] = bmp[bmpos + 1]; //G
89+
image[newpos + 2] = bmp[bmpos + 0]; //B
90+
image[newpos + 3] = 255; //A
91+
}
92+
else
93+
{
94+
image[newpos + 0] = bmp[bmpos + 3]; //R
95+
image[newpos + 1] = bmp[bmpos + 2]; //G
96+
image[newpos + 2] = bmp[bmpos + 1]; //B
97+
image[newpos + 3] = bmp[bmpos + 0]; //A
98+
}
99+
}
100+
return 0;
101+
}
102+
103+
int main(int argc, char *argv[])
104+
{
105+
if(argc < 3)
106+
{
107+
std::cout << "Please provice input PNG and output BMP file names" << std::endl;
108+
return 0;
109+
}
110+
111+
std::vector<unsigned char> bmp;
112+
lodepng::load_file(bmp, argv[1]);
113+
std::vector<unsigned char> image;
114+
unsigned w, h;
115+
unsigned error = decodeBMP(image, w, h, bmp);
116+
117+
if(error)
118+
{
119+
std::cout << "BMP decoding error " << error << std::endl;
120+
return 0;
121+
}
122+
123+
std::vector<unsigned char> png;
124+
error = lodepng::encode(png, image, w, h);
125+
126+
if(error)
127+
{
128+
std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl;
129+
return 0;
130+
}
131+
132+
lodepng::save_file(png, argv[2]);
133+
134+
}

0 commit comments

Comments
 (0)