【问题标题】:Using SDL_image and SDL_RWops with LibZip to load pngs from a zip onto a surface, but won't recognize png使用带有 LibZip 的 SDL_image 和 SDL_RWops 将 png 从 zip 加载到表面上,但无法识别 png
【发布时间】:2020-04-06 19:31:16
【问题描述】:

相关代码:

  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 仍然给我一个错误“不支持的图像格式”。我已经安装了 libpng 并且 IMG_Init 似乎工作正常,所以 SDL_image 库必须工作。显然 libzip 给了我正确的数据。我很困惑为什么会出错。

【问题讨论】:

  • "IMG_Init 似乎工作正常" 所以你传入IMG_INIT_PNG 并验证该位也返回了?
  • 使用调试器,是否达到zip_fclose(file);SDL_FreeRW(rwop);这对线?
  • genpfault: 是的,我在这个 ripi2 之前成功运行的初始化函数中做到了这一点:最后一个 zip_fclose(file);已达到,在 SDL_Surface* surf_load = IMG_Load_RW(rwop, 0) 之前没有 SDL_FreeRW(rwop);因为在那之前没有发生错误所以被执行。 IMG_Load_RW 错误发生后我没有检查,但我没有收到段错误或任何东西。

标签: c++ sdl sdl-image libzip


【解决方案1】:

我想通了。在我读取数据的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;
  }

【讨论】:

  • 我很高兴@laura,发布代码示例并让所有人都清楚是一个很好的做法。就像您在问题中所做的那样。
  • 感谢您帮助拼凑,您确保我完成了所有简单的事情,因此我仔细检查了所有数据。
【解决方案2】:

如果您在调用IMG_Load_RW(rwop, 0); 之前调用SDL_FreeRW(rwop);,那么您将一无所获。

如果没有问题,那么使用:

IMG_LoadPNG_RW instread 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;
  }

【讨论】:

  • 我很困惑,我认为我在错误 if 语句之外发布的代码中没有这样做。能具体点吗?
  • 看起来你在 while 循环完成工作时调用了SDL_FreeRW(rwop);。
  • 这也应该伴随着一条错误消息,最重要的是,我仔细检查以确保我仍然可以使用匹配 rwbuffer 的 rwop->hidden.unknown.data1 获得指向向量的指针。数据()。你知道为什么它会调用相关的错误吗?
  • 我更新了答案。试试IMG_LoadPNG_RW 它来自 SDL Image 1.2.8
  • 我也试过了,IMG_LoadPNG_RW 给了我一个“不是 PNG”错误,当我检查时 IMG_isPNG 返回 false。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多