当 cairo 要求读取比我从 png 创建和 ImageSurface 时拥有的数据更多的数据时该怎么办?
What to do when cairo asks to read more data than I have when creating and ImageSurface from png?
我正在使用 cairomm 1.12.0 版和 cairo 1.14.6 版。
我正在尝试从我作为字节向量存储在内存中的 png 在 cairo 中创建一个 ImageSurface。大多数情况下这是可行的,但有时 Cairo 会向我的读取函数(lambda)传递一个要读取的长度(长度参数),该长度大于向量中剩余的长度。当我在 visual studio 中调试它时,我当然得到一个失败的调试断言 Expression: cannot seek vector iterator after end
Cairo::RefPtr<Cairo::ImageSurface> someFunc(const std::vector<BYTE>& src)
{
Cairo::RefPtr<Cairo::ImageSurface> ret;
if(src.size() > 0)
{
unsigned int read = 0;
ret = Cairo::ImageSurface::create_from_png_stream([&src, &read](unsigned char* data, unsigned int length) {
std::copy_n(src.begin() + read, length, data);
read += length;
return CAIRO_STATUS_SUCCESS;
});
}
return ret;
}
如果我尝试修改我的读取函数以复制剩余数据的最小值和 Cairo 要求读取的长度,我得到 CAIRO_STATUS_NO_MEMORY
,这会导致 std::bad_alloc
异常抛出。
Cairo::RefPtr<Cairo::ImageSurface> someFunc(const std::vector<BYTE>& src)
{
Cairo::RefPtr<Cairo::ImageSurface> ret;
if(src.size() > 0)
{
unsigned int read = 0;
ret = Cairo::ImageSurface::create_from_png_stream([&src, &read](unsigned char* data, unsigned int length) {
length = std::min((unsigned int)src.size() - read, length); // added
std::copy_n(src.begin() + read, length, data);
read += length;
return CAIRO_STATUS_SUCCESS;
});
}
return ret;
}
我认为这与 cairo-stream_read_func
中对 _cairo_output_stream_write
的调用有关-png.c,因为它传递的大小与传递我的读取函数的大小相同,因此可能需要一些数据。
...
status = png_closure->read_func (png_closure->closure, data, size);
...
_cairo_output_stream_write (png_closure->png_data, data, size);
我应该写 null 还是什么来填补字节差异?
如果 cairo 要求的数据多于您拥有的数据,则您的 PNG 已损坏。 Cairo 要求的字节数与 libpng 要求的字节数一样多,据说 libpng 知道它在做什么 (tm) 并要求正确的字节数。如果你没有足够的字节,你应该 return CAIRO_STATUS_READ_ERROR
从你的读取功能。
我正在使用 cairomm 1.12.0 版和 cairo 1.14.6 版。
我正在尝试从我作为字节向量存储在内存中的 png 在 cairo 中创建一个 ImageSurface。大多数情况下这是可行的,但有时 Cairo 会向我的读取函数(lambda)传递一个要读取的长度(长度参数),该长度大于向量中剩余的长度。当我在 visual studio 中调试它时,我当然得到一个失败的调试断言 Expression: cannot seek vector iterator after end
Cairo::RefPtr<Cairo::ImageSurface> someFunc(const std::vector<BYTE>& src)
{
Cairo::RefPtr<Cairo::ImageSurface> ret;
if(src.size() > 0)
{
unsigned int read = 0;
ret = Cairo::ImageSurface::create_from_png_stream([&src, &read](unsigned char* data, unsigned int length) {
std::copy_n(src.begin() + read, length, data);
read += length;
return CAIRO_STATUS_SUCCESS;
});
}
return ret;
}
如果我尝试修改我的读取函数以复制剩余数据的最小值和 Cairo 要求读取的长度,我得到 CAIRO_STATUS_NO_MEMORY
,这会导致 std::bad_alloc
异常抛出。
Cairo::RefPtr<Cairo::ImageSurface> someFunc(const std::vector<BYTE>& src)
{
Cairo::RefPtr<Cairo::ImageSurface> ret;
if(src.size() > 0)
{
unsigned int read = 0;
ret = Cairo::ImageSurface::create_from_png_stream([&src, &read](unsigned char* data, unsigned int length) {
length = std::min((unsigned int)src.size() - read, length); // added
std::copy_n(src.begin() + read, length, data);
read += length;
return CAIRO_STATUS_SUCCESS;
});
}
return ret;
}
我认为这与 cairo-stream_read_func
中对 _cairo_output_stream_write
的调用有关-png.c,因为它传递的大小与传递我的读取函数的大小相同,因此可能需要一些数据。
...
status = png_closure->read_func (png_closure->closure, data, size);
...
_cairo_output_stream_write (png_closure->png_data, data, size);
我应该写 null 还是什么来填补字节差异?
如果 cairo 要求的数据多于您拥有的数据,则您的 PNG 已损坏。 Cairo 要求的字节数与 libpng 要求的字节数一样多,据说 libpng 知道它在做什么 (tm) 并要求正确的字节数。如果你没有足够的字节,你应该 return CAIRO_STATUS_READ_ERROR
从你的读取功能。