Restored final picture saving (in constant memory usage)
This commit is contained in:
parent
6c4a16966c
commit
c39ef6adce
18 changed files with 296 additions and 9 deletions
|
@ -8,6 +8,7 @@
|
||||||
#include "SoftwareCanvasRenderer.h"
|
#include "SoftwareCanvasRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "RenderConfig.h"
|
#include "RenderConfig.h"
|
||||||
|
#include "ColorProfile.h"
|
||||||
|
|
||||||
void startRender(SoftwareCanvasRenderer *renderer, char *outputpath)
|
void startRender(SoftwareCanvasRenderer *renderer, char *outputpath)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +16,7 @@ void startRender(SoftwareCanvasRenderer *renderer, char *outputpath)
|
||||||
renderer->render();
|
renderer->render();
|
||||||
printf("\rSaving %s ... \n", outputpath);
|
printf("\rSaving %s ... \n", outputpath);
|
||||||
remove(outputpath);
|
remove(outputpath);
|
||||||
//renderer->render_area->saveToFile(outputpath);
|
renderer->saveToDisk(outputpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayHelp()
|
void displayHelp()
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "ColorProfile.h"
|
#include "ColorProfile.h"
|
||||||
#include "SoftwareCanvasRenderer.h"
|
#include "SoftwareCanvasRenderer.h"
|
||||||
#include "WidgetPreviewCanvas.h"
|
#include "WidgetPreviewCanvas.h"
|
||||||
|
#include "Canvas.h"
|
||||||
|
|
||||||
class RenderThread:public QThread
|
class RenderThread:public QThread
|
||||||
{
|
{
|
||||||
|
@ -150,12 +151,11 @@ void DialogRender::saveRender()
|
||||||
{
|
{
|
||||||
filepath = filepath.append(".png");
|
filepath = filepath.append(".png");
|
||||||
}
|
}
|
||||||
std::string filepathstr = filepath.toStdString();
|
if (canvas_renderer->saveToDisk(filepath.toStdString()))
|
||||||
/*if (canvas_renderer->render_area->saveToFile((char*)filepathstr.c_str()))
|
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
|
QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
|
||||||
}
|
}
|
||||||
else*/
|
else
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, "Message", QString(tr("Can't write to file : %1")).arg(filepath));
|
QMessageBox::critical(this, "Message", QString(tr("Can't write to file : %1")).arg(filepath));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "CanvasPortion.h"
|
#include "CanvasPortion.h"
|
||||||
#include "CanvasPreview.h"
|
#include "CanvasPreview.h"
|
||||||
|
#include "CanvasPictureWriter.h"
|
||||||
|
|
||||||
Canvas::Canvas()
|
Canvas::Canvas()
|
||||||
{
|
{
|
||||||
|
@ -86,3 +87,24 @@ CanvasPortion *Canvas::at(int x, int y) const
|
||||||
|
|
||||||
return portions[y * horizontal_portion_count + x];
|
return portions[y * horizontal_portion_count + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CanvasPortion *Canvas::atPixel(int x, int y) const
|
||||||
|
{
|
||||||
|
assert(x >= 0 && x < width);
|
||||||
|
assert(y >= 0 && y < height);
|
||||||
|
|
||||||
|
int pwidth = portions[0]->getWidth();
|
||||||
|
int pheight = portions[0]->getHeight();
|
||||||
|
|
||||||
|
return at(x / pwidth, y / pheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Canvas::saveToDisk(const std::string &filepath, const ColorProfile &profile, int antialias) const
|
||||||
|
{
|
||||||
|
assert(antialias >= 1);
|
||||||
|
|
||||||
|
CanvasPictureWriter writer(this);
|
||||||
|
writer.setColorProfile(profile);
|
||||||
|
writer.setAntialias(antialias);
|
||||||
|
return writer.saveCanvas(filepath);
|
||||||
|
}
|
||||||
|
|
|
@ -24,11 +24,19 @@ public:
|
||||||
inline int getVerticalPortionCount() const {return vertical_portion_count;}
|
inline int getVerticalPortionCount() const {return vertical_portion_count;}
|
||||||
|
|
||||||
CanvasPortion *at(int x, int y) const;
|
CanvasPortion *at(int x, int y) const;
|
||||||
|
CanvasPortion *atPixel(int x, int y) const;
|
||||||
|
|
||||||
inline int getWidth() const {return width;}
|
inline int getWidth() const {return width;}
|
||||||
inline int getHeight() const {return height;}
|
inline int getHeight() const {return height;}
|
||||||
inline CanvasPreview *getPreview() const {return preview;}
|
inline CanvasPreview *getPreview() const {return preview;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the canvas to a picture file on disk.
|
||||||
|
*
|
||||||
|
* Returns true if the save was successful.
|
||||||
|
*/
|
||||||
|
bool saveToDisk(const std::string &filepath, const ColorProfile &profile, int antialias) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CanvasPortion*> portions;
|
std::vector<CanvasPortion*> portions;
|
||||||
int horizontal_portion_count;
|
int horizontal_portion_count;
|
||||||
|
|
89
src/render/software/CanvasPictureWriter.cpp
Normal file
89
src/render/software/CanvasPictureWriter.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#include "CanvasPictureWriter.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "Canvas.h"
|
||||||
|
#include "CanvasPortion.h"
|
||||||
|
#include "ColorProfile.h"
|
||||||
|
#include "PackStream.h"
|
||||||
|
|
||||||
|
CanvasPictureWriter::CanvasPictureWriter(const Canvas *canvas):
|
||||||
|
canvas(canvas)
|
||||||
|
{
|
||||||
|
profile = new ColorProfile();
|
||||||
|
antialias = 1;
|
||||||
|
width = canvas->getWidth();
|
||||||
|
height = canvas->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
CanvasPictureWriter::~CanvasPictureWriter()
|
||||||
|
{
|
||||||
|
delete profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasPictureWriter::setAntialias(int antialias)
|
||||||
|
{
|
||||||
|
assert(antialias >= 1);
|
||||||
|
assert(canvas->getWidth() % antialias == 0);
|
||||||
|
assert(canvas->getHeight() % antialias == 0);
|
||||||
|
|
||||||
|
this->antialias = antialias;
|
||||||
|
this->width = canvas->getWidth() / antialias;
|
||||||
|
this->height = canvas->getHeight() / antialias;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasPictureWriter::setColorProfile(const ColorProfile &profile)
|
||||||
|
{
|
||||||
|
profile.copy(this->profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanvasPictureWriter::saveCanvas(const std::string &filepath)
|
||||||
|
{
|
||||||
|
return save(filepath, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CanvasPictureWriter::getPixel(int x, int y)
|
||||||
|
{
|
||||||
|
if (antialias > 1)
|
||||||
|
{
|
||||||
|
int basex = x * antialias;
|
||||||
|
int basey = y * antialias;
|
||||||
|
double factor = 1.0 / (antialias * antialias);
|
||||||
|
Color comp = COLOR_BLACK;
|
||||||
|
|
||||||
|
for (int ix = 0; ix < antialias; ix++)
|
||||||
|
{
|
||||||
|
for (int iy = 0; iy < antialias; iy++)
|
||||||
|
{
|
||||||
|
Color col = getRawPixel(basex + ix, basey + iy);
|
||||||
|
comp.r += col.r * factor;
|
||||||
|
comp.g += col.g * factor;
|
||||||
|
comp.b += col.b * factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile->apply(comp).to32BitBGRA();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return profile->apply(getRawPixel(x, y)).to32BitBGRA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color CanvasPictureWriter::getRawPixel(int x, int y)
|
||||||
|
{
|
||||||
|
// Get the portion this pixel is in
|
||||||
|
CanvasPortion *portion = canvas->atPixel(x, y);
|
||||||
|
|
||||||
|
// Get the pack stream positioned at the pixel
|
||||||
|
PackStream stream;
|
||||||
|
if (not portion->getReadStream(stream, x - portion->getXOffset(), y - portion->getYOffset()))
|
||||||
|
{
|
||||||
|
return COLOR_BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the pixel and apply tone mapping
|
||||||
|
Color col;
|
||||||
|
col.load(&stream);
|
||||||
|
return col;
|
||||||
|
}
|
54
src/render/software/CanvasPictureWriter.h
Normal file
54
src/render/software/CanvasPictureWriter.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef CANVASPICTUREWRITER_H
|
||||||
|
#define CANVASPICTUREWRITER_H
|
||||||
|
|
||||||
|
#include "software_global.h"
|
||||||
|
|
||||||
|
#include "PictureWriter.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace software {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Picture writer to create the final image from canvas portions.
|
||||||
|
*/
|
||||||
|
class SOFTWARESHARED_EXPORT CanvasPictureWriter: public PictureWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CanvasPictureWriter(const Canvas *canvas);
|
||||||
|
virtual ~CanvasPictureWriter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the antialias factor, 1 for no antialiasing.
|
||||||
|
*/
|
||||||
|
void setAntialias(int antialias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color profile to apply to final pixels.
|
||||||
|
*/
|
||||||
|
void setColorProfile(const ColorProfile &profile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the saving process.
|
||||||
|
*
|
||||||
|
* Returns true if saving was successful.
|
||||||
|
*/
|
||||||
|
bool saveCanvas(const std::string &filepath);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual unsigned int getPixel(int x, int y) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Color getRawPixel(int x, int y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Canvas *canvas;
|
||||||
|
int antialias;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
ColorProfile *profile;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CANVASPICTUREWRITER_H
|
|
@ -89,14 +89,14 @@ void CanvasPortion::saveToDisk()
|
||||||
{
|
{
|
||||||
if (pixels)
|
if (pixels)
|
||||||
{
|
{
|
||||||
std::string filepath = FileSystem::getTempFile("paysages_portion_" + std::to_string(index) + ".dat");
|
filepath = FileSystem::getTempFile("paysages_portion_" + std::to_string(index) + ".dat");
|
||||||
PackStream stream;
|
PackStream stream;
|
||||||
stream.bindToFile(filepath, true);
|
stream.bindToFile(filepath, true);
|
||||||
stream.write(&width);
|
stream.write(&width);
|
||||||
stream.write(&height);
|
stream.write(&height);
|
||||||
for (int x = 0; x < width; x++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
pixels[y * width + x].getComposite().save(&stream);
|
pixels[y * width + x].getComposite().save(&stream);
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,23 @@ void CanvasPortion::saveToDisk()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanvasPortion::getReadStream(PackStream &stream, int x, int y)
|
||||||
|
{
|
||||||
|
if (FileSystem::isFile(filepath))
|
||||||
|
{
|
||||||
|
int unused_i;
|
||||||
|
double unused_d;
|
||||||
|
stream.bindToFile(filepath);
|
||||||
|
stream.skip(unused_i, 2);
|
||||||
|
stream.skip(unused_d, (y * width + x - 1) * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment)
|
void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment)
|
||||||
{
|
{
|
||||||
CHECK_COORDINATES();
|
CHECK_COORDINATES();
|
||||||
|
|
|
@ -46,6 +46,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void saveToDisk();
|
void saveToDisk();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a stream to pixel data, and position it on a given pixel.
|
||||||
|
*
|
||||||
|
* Returns true if the stream was successfully located, false if it was not possible.
|
||||||
|
*/
|
||||||
|
bool getReadStream(PackStream &stream, int x=0, int y=0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a fragment to the pixel located at (x, y).
|
* Add a fragment to the pixel located at (x, y).
|
||||||
*
|
*
|
||||||
|
@ -75,6 +82,7 @@ private:
|
||||||
int yoffset;
|
int yoffset;
|
||||||
CanvasPixel *pixels;
|
CanvasPixel *pixels;
|
||||||
CanvasPreview *preview;
|
CanvasPreview *preview;
|
||||||
|
std::string filepath;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public:
|
||||||
|
|
||||||
inline int getWidth() const {return width;}
|
inline int getWidth() const {return width;}
|
||||||
inline int getHeight() const {return height;}
|
inline int getHeight() const {return height;}
|
||||||
|
inline const ColorProfile *getToneMapping() const {return profile;}
|
||||||
|
|
||||||
const Color &getFinalPixel(int x, int y) const;
|
const Color &getFinalPixel(int x, int y) const;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "CanvasPortion.h"
|
#include "CanvasPortion.h"
|
||||||
#include "CanvasPixelShader.h"
|
#include "CanvasPixelShader.h"
|
||||||
#include "RenderConfig.h"
|
#include "RenderConfig.h"
|
||||||
|
#include "ColorProfile.h"
|
||||||
|
#include "CanvasPreview.h"
|
||||||
|
|
||||||
SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
||||||
{
|
{
|
||||||
|
@ -18,6 +20,7 @@ SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
||||||
interrupted = false;
|
interrupted = false;
|
||||||
canvas = new Canvas();
|
canvas = new Canvas();
|
||||||
progress = 0.0;
|
progress = 0.0;
|
||||||
|
samples = 1;
|
||||||
|
|
||||||
rasterizers.push_back(new SkyRasterizer(this, 0));
|
rasterizers.push_back(new SkyRasterizer(this, 0));
|
||||||
rasterizers.push_back(new WaterRasterizer(this, 1));
|
rasterizers.push_back(new WaterRasterizer(this, 1));
|
||||||
|
@ -50,6 +53,7 @@ void SoftwareCanvasRenderer::setSize(int width, int height, int samples)
|
||||||
if (not started)
|
if (not started)
|
||||||
{
|
{
|
||||||
canvas->setSize(width * samples, height * samples);
|
canvas->setSize(width * samples, height * samples);
|
||||||
|
this->samples = samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +116,11 @@ const Rasterizer &SoftwareCanvasRenderer::getRasterizer(int client_id) const
|
||||||
return *(rasterizers[client_id]);
|
return *(rasterizers[client_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoftwareCanvasRenderer::saveToDisk(const std::string &filepath) const
|
||||||
|
{
|
||||||
|
return getCanvas()->saveToDisk(filepath, *getCanvas()->getPreview()->getToneMapping(), samples);
|
||||||
|
}
|
||||||
|
|
||||||
void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion)
|
void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion)
|
||||||
{
|
{
|
||||||
for (auto &rasterizer:rasterizers)
|
for (auto &rasterizer:rasterizers)
|
||||||
|
|
|
@ -52,6 +52,13 @@ public:
|
||||||
*/
|
*/
|
||||||
const Rasterizer &getRasterizer(int client_id) const;
|
const Rasterizer &getRasterizer(int client_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the rendered canvas to a picture file on disk.
|
||||||
|
*
|
||||||
|
* Returns true if the save was successful.
|
||||||
|
*/
|
||||||
|
bool saveToDisk(const std::string &filepath) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Rasterize the scenery into a canvas portion.
|
* @brief Rasterize the scenery into a canvas portion.
|
||||||
|
@ -68,6 +75,7 @@ private:
|
||||||
double progress_segment;
|
double progress_segment;
|
||||||
|
|
||||||
Canvas *canvas;
|
Canvas *canvas;
|
||||||
|
int samples;
|
||||||
std::vector<Rasterizer*> rasterizers;
|
std::vector<Rasterizer*> rasterizers;
|
||||||
bool started;
|
bool started;
|
||||||
bool interrupted;
|
bool interrupted;
|
||||||
|
|
|
@ -46,7 +46,8 @@ SOURCES += SoftwareRenderer.cpp \
|
||||||
CanvasLiveClient.cpp \
|
CanvasLiveClient.cpp \
|
||||||
CanvasPreview.cpp \
|
CanvasPreview.cpp \
|
||||||
RenderConfig.cpp \
|
RenderConfig.cpp \
|
||||||
CanvasPixelShader.cpp
|
CanvasPixelShader.cpp \
|
||||||
|
CanvasPictureWriter.cpp
|
||||||
|
|
||||||
HEADERS += SoftwareRenderer.h\
|
HEADERS += SoftwareRenderer.h\
|
||||||
software_global.h \
|
software_global.h \
|
||||||
|
@ -82,7 +83,8 @@ HEADERS += SoftwareRenderer.h\
|
||||||
CanvasLiveClient.h \
|
CanvasLiveClient.h \
|
||||||
CanvasPreview.h \
|
CanvasPreview.h \
|
||||||
RenderConfig.h \
|
RenderConfig.h \
|
||||||
CanvasPixelShader.h
|
CanvasPixelShader.h \
|
||||||
|
CanvasPictureWriter.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace software {
|
||||||
class CanvasLiveClient;
|
class CanvasLiveClient;
|
||||||
class CanvasPreview;
|
class CanvasPreview;
|
||||||
class CanvasPixelShader;
|
class CanvasPixelShader;
|
||||||
|
class CanvasPictureWriter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
std::string FileSystem::getTempFile(const std::string &filename)
|
std::string FileSystem::getTempFile(const std::string &filename)
|
||||||
{
|
{
|
||||||
return QDir::temp().filePath(QString::fromStdString(filename)).toStdString();
|
return QDir::temp().filePath(QString::fromStdString(filename)).toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileSystem::isFile(const std::string &filepath)
|
||||||
|
{
|
||||||
|
return QFileInfo(QString::fromStdString(filepath)).exists();
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,11 @@ public:
|
||||||
* filename must not contain directory separators.
|
* filename must not contain directory separators.
|
||||||
*/
|
*/
|
||||||
static std::string getTempFile(const std::string &filename);
|
static std::string getTempFile(const std::string &filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given path points to a file.
|
||||||
|
*/
|
||||||
|
static bool isFile(const std::string &filepath);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,3 +114,13 @@ std::string PackStream::readString()
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackStream::skip(const int &value, int count)
|
||||||
|
{
|
||||||
|
stream->skipRawData(sizeof(value) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackStream::skip(const double &value, int count)
|
||||||
|
{
|
||||||
|
stream->skipRawData(sizeof(value) * count);
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ public:
|
||||||
void read(char* value, int max_length);
|
void read(char* value, int max_length);
|
||||||
std::string readString();
|
std::string readString();
|
||||||
|
|
||||||
|
void skip(const int &value, int count=1);
|
||||||
|
void skip(const double &value, int count=1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFile* file;
|
QFile* file;
|
||||||
QDataStream* stream;
|
QDataStream* stream;
|
||||||
|
|
|
@ -49,3 +49,46 @@ TEST(PackStream, All)
|
||||||
}
|
}
|
||||||
delete stream;
|
delete stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PackStream, Skip)
|
||||||
|
{
|
||||||
|
PackStream* stream;
|
||||||
|
int i1=1, i2=2, i3=3;
|
||||||
|
double d1=1.1, d2=2.2;
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack", true);
|
||||||
|
|
||||||
|
stream->write(&i1);
|
||||||
|
stream->write(&i2);
|
||||||
|
stream->write(&d1);
|
||||||
|
stream->write(&d2);
|
||||||
|
stream->write(&i3);
|
||||||
|
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
int resi;
|
||||||
|
double resd;
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack");
|
||||||
|
stream->skip(i1, 1);
|
||||||
|
stream->read(&resi);
|
||||||
|
EXPECT_EQ(2, resi);
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack");
|
||||||
|
stream->skip(i1, 2);
|
||||||
|
stream->read(&resd);
|
||||||
|
EXPECT_DOUBLE_EQ(1.1, resd);
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack");
|
||||||
|
stream->skip(i1, 2);
|
||||||
|
stream->skip(d1, 2);
|
||||||
|
stream->read(&resi);
|
||||||
|
EXPECT_EQ(3, resi);
|
||||||
|
delete stream;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue