stbir_resize_uint8 内存访问崩溃

stbir_resize_uint8 crashing on memory access

我正在使用 stb_image 将图像上传到 GPU。如果我只是用 stbi_load 上传图像,我可以确认(nvidia Nsight)图像已正确存储在 GPU 内存中。但是,我喜欢在上传到 GPU 之前调整一些图像的大小。在这种情况下,我崩溃了。这是代码:

    int      textureWidth;
    int      textureHeight;
    int      textureChannelCount;
    stbi_uc* pixels = stbi_load(fullPath.string().c_str(), &textureWidth, &textureHeight, &textureChannelCount, STBI_rgb_alpha);

    if (!pixels) {
        char error[512];
        sprintf_s(error, "Failed to load image %s!", pathToTexture);
        throw std::runtime_error(error);
    }

    stbi_uc* resizedPixels = nullptr;
    uint32_t imageSize     = 0;
    if (scale > 1.0001f || scale < 0.9999f) {
        stbir_resize_uint8(pixels, textureWidth, textureHeight, 0, resizedPixels, textureWidth * scale, textureHeight * scale, 0, textureChannelCount);
        stbi_image_free(pixels);
        textureWidth *= scale;
        textureHeight *= scale;
        imageSize = textureWidth * textureHeight * textureChannelCount;
    } else {
        resizedPixels = pixels;
        imageSize     = textureWidth * textureHeight * textureChannelCount;
    }

    // Upload the image to the gpu

当此代码为 运行 且比例设置为 1.0f 时,它工作正常。但是,当我将比例设置为 0.25f 时,程序在方法 stbir_resize_uint8 中崩溃。我在这两种情况下提供的图像都是 1920x1080 RGBA PNG。整个图像的 Alpha 通道设置为 1.0f

我必须使用哪个函数来调整图像大小?

编辑:如果我自己分配内存,函数不再崩溃并且工作正常。但我虽然 stb 在内部处理所有内存分配。我错了吗?

我看到您在编辑中发现并解决了问题,但这里有一些有用的建议:


source(也是文档)中的注释似乎没有明确提到必须为调整大小的图像分配内存,但仔细看一下就清楚了在函数的签名处:

STBIRDEF int stbir_resize_uint8(     const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
                                           unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
                                     int num_channels);

想想您自己如何 return 您在函数中分配的内存块的地址。最简单的方法是像这样直接 return 指针:

unsigned char* allocate_memory( int size )
{ return (unsigned char*) malloc(size); }

但是 return 似乎是为错误代码保留的,因此您唯一的选择是操纵指针作为副作用。为此,您需要传递一个指向它的指针(指向指针的指针):

int allocate_memory( unsigned char** pointer_to_array, int size )
{
    *pointer_to_array = (unsigned char*) malloc(size);
    /* Check if allocation was successful and do other stuff... */
    return 0;
}

如果仔细查看调整大小函数的签名,您会注意到没有传递此类参数,因此无法return 内部分配内存的地址。 (unsigned char* output_pixels 而不是 unsigned char** output_pixels)。因此,您必须自己为调整大小的图像分配内存。

希望这对你以后有所帮助。


文档中有 mention 内存分配,但据我了解,这是关于执行调整大小所需的分配,与输出无关。