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 内存分配,但据我了解,这是关于执行调整大小所需的分配,与输出无关。
我正在使用 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 内存分配,但据我了解,这是关于执行调整大小所需的分配,与输出无关。