I make image to ASCII converter and I try to resize image using stb_image_resize.h for better result, but i get segmentation fault when resizing the image or in some cases asserts -- STBIR_ASSERT (info->channels >= 0) or STBIR_ASSERT (info->channels <= MAX_CHANNELS). I tried to do like in this answer https://stackoverflow.com/a/65873156, but it doesn't work.
prefixes
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
#include <stdint.h>
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_IMPLEMENTATION
unsigned char* stbir_malloc(size_t size, void* context){
return (unsigned char *) malloc(size);
}
void stbir_free(void* memory, void* context){
memory = nullptr;
context = nullptr;
}
#define STBIR_MALLOC stbir_malloc
#define STBIR_FREE stbir_free
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
Image structure(took from https://youtu.be/028GNYC32Rg)
struct Image {
uint8_t* data = NULL;
size_t size = 0;
int w;
int h;
int channels;
Image(const char* filename){
if (read(filename)){
printf("Read %s\n", filename);
size = w*h*channels;
} else {
printf("Failed to read %s\n", filename);
}
}
Image(int w, int h, int channels) : w(w), h(h), channels(channels){
size = w*h*channels;
data = new uint8_t[size];
}
Image(const Image& image) : Image(image.w, image.h, image.channels){
memcpy(data, image.data, size);
}
~Image(){
stbi_image_free(data);
}
Resize function
Image& resize(int width, int height){
unsigned char* resizedPixels = nullptr;
stbir_resize_uint8(data, w, h, 0, resizedPixels, width, height, 0, channels);
stbi_image_free(data);
data = resizedPixels;
w = width;
h = height;
size = w*h*channels;
return *this;
}
Edit: I've used GDB and don't understand how alloc_context is equal to 0x0:
165
(gdb) n
Breakpoint 1, stbir_malloc (size=65280, context=0x0) at ascii.cpp:15
15 //1 breakpoint
(gdb) n
16 return (unsigned char *) malloc(size);
(gdb) n
stbir__resize_arbitrary (alloc_context=0x0, input_data=0x7ffff78f7010, input_w=600, input_h=300, input_stride_in_bytes=0, output_data=0x0, output_w=300, output_h=150, output_stride_in_bytes=0, s0=0, t0=0, s1=1, t1=1, transform=0x0, channels=3, alpha_channel=-1, flags=0, type=STBIR_TYPE_UINT8, h_filter=STBIR_FILTER_DEFAULT, v_filter=STBIR_FILTER_DEFAULT, edge_horizontal=STBIR_EDGE_CLAMP, edge_vertical=STBIR_EDGE_CLAMP, colorspace=STBIR_COLORSPACE_LINEAR) at /media/D/workspaceOfC++/projects/quickStuff/ASCII/stb_image_resize.h:2448
2448 if (!extra_memory)
(gdb) n
2451 result = stbir__resize_allocated(&info, input_data, input_stride_in_bytes,
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x000055555557b01a in stbir__encode_scanline (stbir_info=0x7fffffffe070, num_pixels=300, output_buffer=0x0, encode_buffer=0x5555555a6f40, channels=3, alpha_channel=-1, decode=0) at /media/D/workspaceOfC++/projects/quickStuff/ASCII/stb_image_resize.h:1755
1755 ((unsigned char*)output_buffer)[index] = STBIR__ENCODE_LINEAR8(encode_buffer[index]);
(gdb) n
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
The program is not being run.
(gdb)
The program is not being run.
(gdb) q
I've solved the problem, it was because resizedPixels was equal to nullptr, after i've changed it to (unsigned char *) malloc(width * height * 3), it converted image. Thanks for help :)