Estou salvando um Cairo::ImageSurface
como parte de um arquivo binário. Escrever pixels de surface->get_data()
funciona bem, no entanto, produz um arquivo muito maior comparado a quando escrevo com surface->write_to_png(std::string name)
. Então, estou tentando usar surface->write_to_png_stream(const SlotWriteFunc &write_func);
e Cairo::ImageSurface::create_from_png_stream(const SlotReadFunc &read_func)
;
Inicialmente, o callback Cairo::Surface::SlotWriteFunc fez sentido para mim, ele é chamado várias vezes ao escrever a superfície e fornece parâmetros const unsigned char*
como dados e unsigned int
como comprimento, mas Cairo::Surface::SlotReadFunc me confunde, pois ele também fornece um unsigned int
que determina quantos dados ele quer ler. Por que não é um unsigned int&
, para que eu possa dizer o comprimento com base no arquivo? Isso me leva a uma conclusão que eu não entendo nem SlotWriteFunc
um nem outro.
Por favor, explique como usar SlotWriteFunc
e SlotReadFunc
.
Obrigado pela ajuda.
O exemplo a seguir grava no arquivo corretamente, mas gera um erro quando eu chamo create_from_png_stream
:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
#include <fstream>
#include <iostream>
#include <cairomm/cairomm.h>
class PNGStream {
public:
std::fstream *file;
Cairo::ErrorStatus write(const unsigned char *data, unsigned int length) {
std::cout << length << std::endl;
file->write(reinterpret_cast<char *>(&length), sizeof(length));
file->write(reinterpret_cast<const char*>(data), length);
return Cairo::ErrorStatus::CAIRO_STATUS_SUCCESS;
}
Cairo::ErrorStatus read(unsigned char *data, unsigned int length) {
std::cout << length << std::endl;
// I'm not sure, what comes here
return Cairo::ErrorStatus::CAIRO_STATUS_SUCCESS;
}
};
int main() {
std::fstream file;
PNGStream png_stream;
png_stream.file = &file;
auto surface = Cairo::ImageSurface::create(Cairo::Surface::Format::ARGB32, 1920, 1080);
auto cr = Cairo::Context::create(surface);
cr->set_source_rgb(0, 0, 0);
cr->paint();
file.open("test.png", std::ios::binary | std::ios::out);
surface->write_to_png_stream(sigc::mem_fun(png_stream, &PNGStream::write));
file.close();
file.open("test.png", std::ios::binary | std::ios::in);
auto surface2 = Cairo::ImageSurface::create_from_png_stream(sigc::mem_fun(png_stream, &PNGStream::read)); //error
file.close();
return 0;
}