【问题标题】:libpng: writing a png fails: stops at header write errorlibpng:写入 png 失败:在标头写入错误处停止
【发布时间】:2012-08-17 04:19:56
【问题描述】:

我不知道出了什么问题。当我尝试编写 PNG 时,出现错误:“写入标头时出错”。

我需要添加其他内容吗?我从这里获取了 .lib/.h 文件:http://www.eden.net.nz/7/20071024/

编辑:我终于成功了。

解决办法:

#pragma comment(lib, "zlib_s.lib") // must be before libpng!
#pragma comment(lib, "libpng_s.lib") // must be after zlib!

很奇怪吧?

这是工作代码,它是一个稍微修改过的版本:http://zarb.org/~gc/html/libpng.html
未来说明:这必须编译为 C 代码!

#pragma comment(lib, "zlib_s.lib") // must be before libpng!
#pragma comment(lib, "libpng_s.lib") // must be after zlib!

#define PNG_DEBUG 0
#include "png.h"

int x, y;

int width, height;
png_byte color_type;
png_byte bit_depth;

png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep *row_pointers;


char *save_png(char *savefile, void *data_in, int w, int h, int BPP){
    unsigned char *data = (unsigned char *)*data_in;
    int p = 0;
    FILE *fp;

    width = w;
    height = h;
    color_type = 2;
    bit_depth = 8;

    // create file 
    fp = fopen(savefile, "wb");
    if(!fp) return "[write_png_file] File %s could not be opened for writing";

    // initialize stuff 
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if(!png_ptr) return "[write_png_file] png_create_write_struct failed";

    info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) return "[write_png_file] png_create_info_struct failed";
    if(setjmp(png_jmpbuf(png_ptr))) return "[write_png_file] Error during init_io";

    png_init_io(png_ptr, fp);
    // write header 
    if(setjmp(png_jmpbuf(png_ptr))) return "[write_png_file] Error during writing header";

    png_set_IHDR(
        png_ptr, info_ptr, width, height,
        bit_depth, color_type, PNG_INTERLACE_NONE,
        PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE
    );

    png_write_info(png_ptr, info_ptr);

    row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
    for(y = 0; y < height; y++){
        row_pointers[y] = (png_byte*)malloc(width*BPP);//png_get_rowbytes(png_ptr,info_ptr));
        for(x = 0; x < width; x++){
            row_pointers[y][x*BPP+0] = data[p++];
            row_pointers[y][x*BPP+1] = data[p++];
            row_pointers[y][x*BPP+2] = data[p++];
        }
    }
    // write bytes 
    if(setjmp(png_jmpbuf(png_ptr))) return "[write_png_file] Error during writing bytes";

    png_write_image(png_ptr, row_pointers);

    // end write 
    if(setjmp(png_jmpbuf(png_ptr))) return "[write_png_file] Error during end of write";

    png_write_end(png_ptr, NULL);

    // cleanup heap allocation 
    for(y = 0; y < height; y++){
        free(row_pointers[y]);
    }
    free(row_pointers);

    fclose(fp);

    return "0";
}

【问题讨论】:

  • 你在这里写的是纯 C,所以你应该把它编译为 C。永远不要在 C++ 代码中使用 setjmp/longjmp 或其他有副作用的 C 函数.这就是第一个警告的内容。
  • @trion,我明白了...是否可以将其编译为 c++ 代码?
  • @trion,当我尝试将其编译为 .c 文件时,我遇到了数千个荒谬的错误。甚至可以在 c++ 项目中编译 c 文件(我看不到 .c 文件添加选项,所以我只是将 .cpp 重命名为 .c)?我得到奇怪的错误,例如:“y not declared”即使它被声明了!
  • 您为什么要这样做?您在这里没有使用任何 C++ 功能。如果您想在项目的另一部分使用 C++,请创建一个声明 extern "C" void write_png_file(char *file_name) 的标头,将源文件编译为 C,然后使用 C++ 文件中的 write_png_file。
  • @trion,我想将其转换为 c++,因为我无法编译 C,正如我所说:我得到了数千个荒谬的错误。所以我想知道 Visual Studio 2008 是否支持它,因为当我想创建新的源文件时找不到 .c 文件扩展名。目前我刚刚将 .cpp 重命名为 .c,现在它抛出“数千个荒谬的错误”,我不知道出了什么问题……它们没有意义。

标签: c++ windows visual-studio-2008 png libpng


【解决方案1】:

问题出在库的顺序上:

#pragma comment(lib, "zlib_s.lib") // must be before libpng!
#pragma comment(lib, "libpng_s.lib") // must be after zlib!

很奇怪,但这解决了问题!

【讨论】:

    猜你喜欢
    • 2017-11-17
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 2021-09-06
    • 1970-01-01
    相关资源
    最近更新 更多