From cb00f2bdd3b704650910d1c41cb3c9cb414b5383 Mon Sep 17 00:00:00 2001 From: Sanjay Nambiar Date: Tue, 2 Jun 2026 02:48:16 +0100 Subject: [PATCH 1/2] stb_image_write: fix linker errors when writing HDR images with STBI_WRITE_NO_STDIO defined --- stb_image_write.h | 84 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/stb_image_write.h b/stb_image_write.h index e4b32ed1bc..5de9f34ea9 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -141,6 +141,7 @@ github:ignotion Adam Schackart Andrew Kensler + Sanjay Nambiar LICENSE @@ -634,8 +635,6 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) -#ifndef STBI_WRITE_NO_STDIO - static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) { int exponent; @@ -758,24 +757,90 @@ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int nco } } +static struct +{ + short temp; // temp field to force 2-byte alignment + char pair[201]; +} stbiw__u32_to_str_digitpairs = +{ + 0, + "00010203040506070809101112131415161718192021222324" + "25262728293031323334353637383940414243444546474849" + "50515253545556575859606162636465666768697071727374" + "75767778798081828384858687888990919293949596979899" +}; + +static int stbiw__u32_to_string(unsigned int value, char* dest) +{ + short num[6]; // temp storage for 2-byte alignment + char* s; + int len = 0; + + if (value == 0) { + *dest = '0'; + return 1; + } + + if (value < 100000000) + { + if (value <= 9999) { + if (value <= 99) { + len = (value > 9) ? 2 : 1; + } else { + len = (value > 999) ? 4 : 3; + } + } else { + if (value > 999999) { + len = (value > 9999999) ? 8 : 7; + } else { + len = (value > 99999) ? 6 : 5; + } + } + } else { + len = (value < 1000000000) ? 9 : 10; + } + + s = ((char*)num) + len + (len % 2); + while (value > 9) { + s -= 2; + *(unsigned short*)s = *(unsigned short*)&stbiw__u32_to_str_digitpairs.pair[(value % 100) * 2]; + value /= 100; + } + if (value) { + *--s = '0' + value; + } + memcpy(dest, s, len); + + return len; +} + static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) { + const char* header_str_part1 = "EXPOSURE= 1.0000000000000\n\n-Y "; + const char* header_str_part2 = " +X "; + const int header_str_part1_len = strlen(header_str_part1); + const int header_str_part2_len = strlen(header_str_part2); + if (y <= 0 || x <= 0 || data == NULL) return 0; else { // Each component is stored separately. Allocate scratch space for full output scanline. unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); - int i, len; + int i; char buffer[128]; + char* dst = buffer; char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; s->func(s->context, header, sizeof(header)-1); -#ifdef __STDC_LIB_EXT1__ - len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); -#else - len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); -#endif - s->func(s->context, buffer, len); + memcpy(dst, header_str_part1, header_str_part1_len); + dst += header_str_part1_len; + dst += stbiw__u32_to_string(y, dst); + memcpy(dst, header_str_part2, header_str_part2_len); + dst += header_str_part2_len; + dst += stbiw__u32_to_string(x, dst); + *dst++ = '\n'; + + s->func(s->context, buffer, dst - buffer); for(i=0; i < y; i++) stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); @@ -791,6 +856,7 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, return stbi_write_hdr_core(&s, x, y, comp, (float *) data); } +#ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) { stbi__write_context s = { 0 }; From aeb69073d7570a481245a665dc17726d68827062 Mon Sep 17 00:00:00 2001 From: Sanjay Nambiar Date: Thu, 4 Jun 2026 01:35:23 +0100 Subject: [PATCH 2/2] stb_image_write: update int to string function to a simpler one --- stb_image_write.h | 54 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/stb_image_write.h b/stb_image_write.h index 5de9f34ea9..d1456dec4d 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -757,60 +757,18 @@ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int nco } } -static struct -{ - short temp; // temp field to force 2-byte alignment - char pair[201]; -} stbiw__u32_to_str_digitpairs = -{ - 0, - "00010203040506070809101112131415161718192021222324" - "25262728293031323334353637383940414243444546474849" - "50515253545556575859606162636465666768697071727374" - "75767778798081828384858687888990919293949596979899" -}; - static int stbiw__u32_to_string(unsigned int value, char* dest) { - short num[6]; // temp storage for 2-byte alignment - char* s; + char buff[12] = {0}; + char* s = &buff[11]; int len = 0; - if (value == 0) { - *dest = '0'; - return 1; - } - - if (value < 100000000) - { - if (value <= 9999) { - if (value <= 99) { - len = (value > 9) ? 2 : 1; - } else { - len = (value > 999) ? 4 : 3; - } - } else { - if (value > 999999) { - len = (value > 9999999) ? 8 : 7; - } else { - len = (value > 99999) ? 6 : 5; - } - } - } else { - len = (value < 1000000000) ? 9 : 10; - } + do { + *--s = '0' + (value % 10); + } while(value /= 10); - s = ((char*)num) + len + (len % 2); - while (value > 9) { - s -= 2; - *(unsigned short*)s = *(unsigned short*)&stbiw__u32_to_str_digitpairs.pair[(value % 100) * 2]; - value /= 100; - } - if (value) { - *--s = '0' + value; - } + len = 11 - (s - buff); memcpy(dest, s, len); - return len; }