使用 SDL_image 和 SDL_RWops 与 LibZip 将 png 从 zip 加载到表面上,但无法识别 png
Using SDL_image and SDL_RWops with LibZip to load pngs from a zip onto a surface, but won't recognize png
相关代码:
zip_stat_t filestat;
uint64_t filetotal = 0;
SDL_RWops* rwop = SDL_AllocRW();
//bunch of code that's not relevant to the matter goes here
std::vector<char> rwbuffer(filestat.size);
rwop = SDL_RWFromMem(rwbuffer.data(), filestat.size);
while(filetotal < filestat.size)
{
char buffer[256];
int64_t length;
//read the file into the buffer
length = zip_fread(file, buffer, 256);
if (length == -1)
{
u_error(std::cerr, CC_ERROR_ZIP, "zip_fread");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//write the buffer into the rwop stream
if ( (uint16_t)length != SDL_RWwrite(rwop, buffer, 1, (size_t)length) )
{
u_error(std::cerr, CC_ERROR_SDL, "SDL_RWwrite");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//Increment the count so that the loop ends
filetotal += length;
}
zip_fclose(file);
//Put it onto a surface
SDL_Surface* surf_load = IMG_Load_RW(rwop, 0);
if(surf_load == NULL)
{
u_error(std::cerr, CC_ERROR_IMAGE, "IMG_Load_RW");
SDL_FreeRW(rwop);
u_cleanup(surf_load);
return false;
}
//...
我已经用调试器转储了向量 rwbuffer 的内容,它是一个有效的 png,但是 IMG_Load_RW 仍然给我一个错误 "Unsupported image format." 我已经安装了 libpng 并且 IMG_Init 似乎工作正常,所以 SDL_image 库必须工作。显然 libzip 给了我正确的数据。我很困惑为什么会收到错误消息。
如果你在 IMG_Load_RW(rwop, 0);
之前调用 SDL_FreeRW(rwop);
那么你从内存中什么也得不到。
如果 freeRW 没有问题,则使用:
IMG_LoadPNG_RW
代替 IMG_Load_RW
也 IMG_isPNG
可以很好地检查。
在其他方面,您似乎在 SDL i SDL_Image 之间存在版本相关性错误。如果你使用 SDL2 那么也使用 SDL2_image lib.
已更新
zip_stat_t filestat;
uint64_t filetotal = 0;
SDL_RWops* rwop = SDL_AllocRW();
//bunch of code that's not relevant to the matter goes here
std::vector<char> rwbuffer(filestat.size);
rwop = SDL_RWFromMem(rwbuffer.data(), filestat.size);
while(filetotal < filestat.size)
{
char buffer[256];
int64_t length;
//read the file into the buffer
length = zip_fread(file, buffer, 256);
if (length == -1)
{
u_error(std::cerr, CC_ERROR_ZIP, "zip_fread");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//write the buffer into the rwop stream
if ( (uint16_t)length != SDL_RWwrite(rwop, buffer, 1, (size_t)length) )
{
u_error(std::cerr, CC_ERROR_SDL, "SDL_RWwrite");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//Increment the count so that the loop ends
filetotal += length;
}
zip_fclose(file);
//Put it onto a surface
SDL_Surface* surf_load = IMG_LoadPNG_RW(rwop, 0);
if(surf_load == NULL)
{
u_error(std::cerr, CC_ERROR_IMAGE, "IMG_Load_RW");
SDL_FreeRW(rwop);
u_cleanup(surf_load);
return false;
}
我明白了。在我读取数据的 while 循环结束时,RWops 流的查找值位于文件末尾,并且 IMG_LoadPNG_RW 没有重置它,所以我必须手动 SDL_RWseek( rwop, 0, RW_SEEK_SET);在 while 循环完成后读取 png 数据。
//Return the seek pointer of the RWop to the beginning so that the file can be read
SDL_RWseek(rwop,0,RW_SEEK_SET);
//Put it onto a surface
SDL_Surface* surf_load = IMG_Load_RW(rwop, 0);
if(surf_load == NULL)
{
u_error(std::cerr, CC_ERROR_IMAGE, "IMG_Load_RW");
SDL_FreeRW(rwop);
u_cleanup(surf_load);
return false;
}
相关代码:
zip_stat_t filestat;
uint64_t filetotal = 0;
SDL_RWops* rwop = SDL_AllocRW();
//bunch of code that's not relevant to the matter goes here
std::vector<char> rwbuffer(filestat.size);
rwop = SDL_RWFromMem(rwbuffer.data(), filestat.size);
while(filetotal < filestat.size)
{
char buffer[256];
int64_t length;
//read the file into the buffer
length = zip_fread(file, buffer, 256);
if (length == -1)
{
u_error(std::cerr, CC_ERROR_ZIP, "zip_fread");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//write the buffer into the rwop stream
if ( (uint16_t)length != SDL_RWwrite(rwop, buffer, 1, (size_t)length) )
{
u_error(std::cerr, CC_ERROR_SDL, "SDL_RWwrite");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//Increment the count so that the loop ends
filetotal += length;
}
zip_fclose(file);
//Put it onto a surface
SDL_Surface* surf_load = IMG_Load_RW(rwop, 0);
if(surf_load == NULL)
{
u_error(std::cerr, CC_ERROR_IMAGE, "IMG_Load_RW");
SDL_FreeRW(rwop);
u_cleanup(surf_load);
return false;
}
//...
我已经用调试器转储了向量 rwbuffer 的内容,它是一个有效的 png,但是 IMG_Load_RW 仍然给我一个错误 "Unsupported image format." 我已经安装了 libpng 并且 IMG_Init 似乎工作正常,所以 SDL_image 库必须工作。显然 libzip 给了我正确的数据。我很困惑为什么会收到错误消息。
如果你在 IMG_Load_RW(rwop, 0);
之前调用 SDL_FreeRW(rwop);
那么你从内存中什么也得不到。
如果 freeRW 没有问题,则使用:
IMG_LoadPNG_RW
代替 IMG_Load_RW
也 IMG_isPNG
可以很好地检查。
在其他方面,您似乎在 SDL i SDL_Image 之间存在版本相关性错误。如果你使用 SDL2 那么也使用 SDL2_image lib.
已更新
zip_stat_t filestat;
uint64_t filetotal = 0;
SDL_RWops* rwop = SDL_AllocRW();
//bunch of code that's not relevant to the matter goes here
std::vector<char> rwbuffer(filestat.size);
rwop = SDL_RWFromMem(rwbuffer.data(), filestat.size);
while(filetotal < filestat.size)
{
char buffer[256];
int64_t length;
//read the file into the buffer
length = zip_fread(file, buffer, 256);
if (length == -1)
{
u_error(std::cerr, CC_ERROR_ZIP, "zip_fread");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//write the buffer into the rwop stream
if ( (uint16_t)length != SDL_RWwrite(rwop, buffer, 1, (size_t)length) )
{
u_error(std::cerr, CC_ERROR_SDL, "SDL_RWwrite");
zip_fclose(file);
SDL_FreeRW(rwop);
return false;
}
//Increment the count so that the loop ends
filetotal += length;
}
zip_fclose(file);
//Put it onto a surface
SDL_Surface* surf_load = IMG_LoadPNG_RW(rwop, 0);
if(surf_load == NULL)
{
u_error(std::cerr, CC_ERROR_IMAGE, "IMG_Load_RW");
SDL_FreeRW(rwop);
u_cleanup(surf_load);
return false;
}
我明白了。在我读取数据的 while 循环结束时,RWops 流的查找值位于文件末尾,并且 IMG_LoadPNG_RW 没有重置它,所以我必须手动 SDL_RWseek( rwop, 0, RW_SEEK_SET);在 while 循环完成后读取 png 数据。
//Return the seek pointer of the RWop to the beginning so that the file can be read
SDL_RWseek(rwop,0,RW_SEEK_SET);
//Put it onto a surface
SDL_Surface* surf_load = IMG_Load_RW(rwop, 0);
if(surf_load == NULL)
{
u_error(std::cerr, CC_ERROR_IMAGE, "IMG_Load_RW");
SDL_FreeRW(rwop);
u_cleanup(surf_load);
return false;
}