访问冲突写入位置0x00BB9000

时间:2014-03-28 10:16:14

标签: c++

我目前正在处理PNG格式。而且,我正在努力了解它的特点:

  

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

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

但是,我无法理解字节宽度是多少?

因为当我尝试在C ++中将一个bmp图像转换为png图像时,我收到以下错误:

  

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

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

时,我得到了这个
  

宽度= 1600,   身高= 900,   bytewidth = 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;
}

我实际上是在标记的行上得到了这个错误。

有什么好的建议吗?

3 个答案:

答案 0 :(得分:0)

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

看起来很可疑 - 我不知道png_malloc()是如何工作的,但我想您正在分配sizeof(uint8_t) * BytesPerPixel(可能是sizeof(uint8_t) * 4)而不是sizeof(uint8_t) * NumberOfPixels (应该相当大)。

答案 1 :(得分:0)

我认为你的rgbbitmap.bytes_per_pixel = 1是错误的。 如果你在RGB8中工作你的bytes_per_pixel = 3,在RGBA8中是4,依此类推。

答案 2 :(得分:0)

设置

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个字节乘以行中的像素。您实际上计算了该值,bytes_per_row,但由于某种原因无法使用它。

相关问题