C++ 访问冲突写入位置0x00BB9000

C++ 访问冲突写入位置0x00BB9000,c++,C++,我目前正在研究PNG格式。我试图了解它的特点: 宽度、高度、字节宽度、每宽度字节数、RGB像素(红色、绿色、蓝色) 参考和,宽度是图像的分辨率宽度(以像素为单位),高度是图像的分辨率高度(以像素为单位),每个宽度的字节仅取8或16作为值,RGB像素的三项取0到255作为整数值 但是,我不明白什么是字节宽度 因为在C++中尝试将一个BMP图像转换成PNG图像时,我得到以下错误: Project.exe中0x01038F6C处未处理的异常:0xC0000005:访问冲突写入位置0x00BB9000

我目前正在研究PNG格式。我试图了解它的特点:

宽度、高度、字节宽度、每宽度字节数、RGB像素(红色、绿色、蓝色)

参考和,宽度是图像的分辨率宽度(以像素为单位),高度是图像的分辨率高度(以像素为单位),每个宽度的字节仅取8或16作为值,RGB像素的三项取0到255作为整数值

但是,我不明白什么是字节宽度

因为在C++中尝试将一个BMP图像转换成PNG图像时,我得到以下错误:

Project.exe中0x01038F6C处未处理的异常:0xC0000005:访问冲突写入位置0x00BB9000

当我将输出png特征初始化为:

宽度=1600, 高度=900, 字节宽度=1, 每宽度字节数=1, RGB像素(红色=255,绿色=255,蓝色=255)

使用此代码:

#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE

#include <png.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

typedef struct _RGBPixel {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} RGBPixel;

/* Structure for containing decompressed bitmaps. */
typedef struct _RGBBitmap {
    RGBPixel *pixels;
    size_t width;
    size_t height;
    size_t bytewidth;
    uint8_t bytes_per_pixel;
} RGBBitmap;

/* Returns pixel of bitmap at given point. */
#define RGBPixelAtPoint(image, x, y) \
    *(((image)->pixels) + (((image)->bytewidth * (y)) \
                        + ((x) * (image)->bytes_per_pixel)))

/* Attempts to save PNG to file; returns 0 on success, non-zero on error. */
int save_png_to_file(RGBBitmap *bitmap, const char *path)
{
    FILE *fp = fopen(path, "wb");
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    size_t x, y;
    png_uint_32 bytes_per_row;
    png_byte **row_pointers = NULL;

    if (fp == NULL) return -1;

    /* Initialize the write struct. */
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL) {
        fclose(fp);
        return -1;
    }

    /* Initialize the info struct. */
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_write_struct(&png_ptr, NULL);
        fclose(fp);
        return -1;
    }

    /* Set up error handling. */
    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
        return -1;
    }

    /* Set image attributes. */
    png_set_IHDR(png_ptr,
                 info_ptr,
                 bitmap->width,
                 bitmap->height,
                 8,
                 PNG_COLOR_TYPE_RGB,
                 PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);

    /* Initialize rows of PNG. */
    bytes_per_row = bitmap->width * bitmap->bytes_per_pixel;
    row_pointers = (png_byte **)png_malloc(png_ptr, bitmap->height * sizeof(png_byte *));
    for (y = 0; y < bitmap->height; ++y) {
        uint8_t *row = (uint8_t *)png_malloc(png_ptr, sizeof(uint8_t)* bitmap->bytes_per_pixel);
        row_pointers[y] = (png_byte *)row;
        for (x = 0; x < bitmap->width; ++x) {
            RGBPixel color = RGBPixelAtPoint(bitmap, x, y);
            *row++ = color.red;
            *row++ = color.green;  /************* MARKED LINE ***************/
            *row++ = color.blue;
        }
    }

    /* Actually write the image data. */
    png_init_io(png_ptr, fp);
    png_set_rows(png_ptr, info_ptr, row_pointers);
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

    /* Cleanup. */
    for (y = 0; y < bitmap->height; y++) {
        png_free(png_ptr, row_pointers[y]);
    }
    png_free(png_ptr, row_pointers);

    /* Finish writing. */
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp);
    return 0;
}

int main()
{
    RGBBitmap rgbbitmap;
    rgbbitmap.height = 1600;
    rgbbitmap.width = 900;
    rgbbitmap.bytes_per_pixel = 1;
    rgbbitmap.bytewidth = 1;

    RGBPixel rgbpixel;
    rgbpixel.blue = 255;
    rgbpixel.green = 255;
    rgbpixel.red = 255;
    rgbbitmap.pixels = &rgbpixel;

    save_png_to_file(&rgbbitmap, "abc.bmp");

        return 0;
}
#定义WIN32_LEAN_和_MEAN
#定义\u CRT\u SECURE\u NO\u弃用
#包括
#包括
#包括
#包括
typedef结构\u RGBPixel{
uint8_t蓝;
uint8_t绿色;
uint8_t红色;
}RGB像素;
/*用于包含解压缩位图的结构*/
类型定义结构_RGBBitmap{
RGB像素*像素;
尺寸和宽度;
尺寸和高度;
大小字节宽度;
每像素8字节;
}RGBBitmap;
/*返回给定点位图的像素*/
#定义RGB像素点(图像,x,y)\
*((图像)->像素)+((图像)->字节宽度*(y))\
+((x)*(图像)->每像素字节数)
/*尝试将PNG保存到文件;成功时返回0,错误时返回非零*/
int save_png_to_文件(RGBBitmap*位图,const char*路径)
{
文件*fp=fopen(路径,“wb”);
png_structp png_ptr=NULL;
png_infop info_ptr=NULL;
尺寸x,y;
png每行32字节;
png_字节**行指针=NULL;
if(fp==NULL)返回-1;
/*初始化写结构*/
png_ptr=png_create_write_struct(png_LIBPNG_VER_STRING,NULL,NULL);
如果(png_ptr==NULL){
fclose(fp);
返回-1;
}
/*初始化信息结构*/
info_ptr=png_create_info_struct(png_ptr);
if(info_ptr==NULL){
png_destroy_write_struct(&png_ptr,NULL);
fclose(fp);
返回-1;
}
/*设置错误处理*/
if(setjmp(png_jmpbuf(png_ptr))){
png_destroy_write_struct(&png_ptr和&info_ptr);
fclose(fp);
返回-1;
}
/*设置图像属性*/
png\U set\U IHDR(png\U ptr,
信息,
位图->宽度,
位图->高度,
8.
PNG_颜色_类型_RGB,
PNG\u交错\u无,
PNG\压缩\类型\默认值,
PNG_过滤器_类型_默认值);
/*初始化PNG的行*/
每行字节数=位图->宽度*位图->每像素字节数;
行指针=(png_字节**)png_malloc(png_ptr,位图->高度*大小(png_字节*);
对于(y=0;yheight;++y){
uint8_t*行=(uint8_t*)png_malloc(png_ptr,sizeof(uint8_t)*位图->每像素字节数);
行指针[y]=(png字节*)行;
对于(x=0;xwidth;++x){
RGB像素颜色=RGB像素点(位图,x,y);
*row++=color.red;
*行++=color.green;/*************标记行***************/
*row++=color.blue;
}
}
/*实际写入图像数据*/
png_init_io(png_ptr,fp);
png_设置_行(png_ptr、信息_ptr、行指针);
png_write_png(png_ptr,info_ptr,png_TRANSFORM_IDENTITY,NULL);
/*清理*/
对于(y=0;yheight;y++){
png_-free(png_-ptr,行指针[y]);
}
png_免费(png_ptr,行指针);
/*写完*/
png_destroy_write_struct(&png_ptr和&info_ptr);
fclose(fp);
返回0;
}
int main()
{
RGBBitmap RGBBitmap;
rgbbitmap.height=1600;
rgbbitmap.width=900;
rgbbitmap.bytes_/_像素=1;
rgbbitmap.bytewidth=1;
RGB像素RGB像素;
rgbpixel.blue=255;
rgbpixel.green=255;
rgbpixel.red=255;
rgbbitmap.pixels=&rgbpixel;
将_png_保存到_文件(&rgbbitmap,“abc.bmp”);
返回0;
}
实际上,我在标记的行上得到了那个错误

有什么好的建议吗?

这个

uint8_t *row = (uint8_t *)png_malloc(png_ptr, sizeof(uint8_t)* bitmap->bytes_per_pixel);

看起来很可疑-我不知道png_malloc()是如何工作的,但我猜您是在分配
sizeof(uint8_t)*bytesperpoixel
(可能是
sizeof(uint8_t)*4
)而不是
sizeof(uint8_t)*NumberOfPixels
(应该大得多)

我认为您的rgbbitmap.bytes\u per\u pixel=1是错误的。 如果在RGB8中工作,则每像素字节数=3,在RGBA8中为4,依此类推。

设置后

rgbbitmap.bytes_per_pixel = 3;  // was 1 which is probably wrong
当然

uint8_t *row = (uint8_t *)png_malloc(png_ptr, sizeof(uint8_t)* bitmap->bytes_per_pixel);
一定是

uint8_t *row = (uint8_t *)png_malloc(png_ptr, sizeof(uint8_t)* bitmap->bytes_per_pixel*bitmap->width);

,即每行必须为该行中的所有字节保留足够的空间;-),即每像素3字节乘以一行中的像素。实际上,您可以计算该值,即每行字节数,但由于某种原因无法使用它。

您是否应该在
行+
之前进行边界检查?bytewidth可能意味着“以像素为单位的字节宽度”,然后应该是8。@PeterSchneider,当我这样做时,我在
RGBPixel color=RGBPixelAtPoint(位图,x,y)上得到相同的发布错误行。@PeterSchneider,这可能是来自RGB颜色吗?当我用3或4替换每个像素的字节时,我在
RGBPixel color=RGBPixelAtPoint(位图,x,y)上得到了相同的发布错误行。为什么不尝试通过数组样式访问请求像素:像素[(行+列)*字节数]?此问题可能来自RGB颜色?此问题可能来自RGB颜色?感谢您的响应,如果我正确理解,我还需要将每个像素的字节数更改为3?初始化将是(1600900,3,1255255)?还是因为我没有将
abc.bmp
转换为
abc.png
并覆盖它?我需要