Nebula
Loading...
Searching...
No Matches
stb_image_write_16bit.h
Go to the documentation of this file.
1#ifndef INCLUDE_STB_IMAGE_WRITE_16_H
2#define INCLUDE_STB_IMAGE_WRITE_16_H
3
4#include <stdlib.h>
5
6// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
7#ifndef STBIW16DEF
8#ifdef STB_IMAGE_WRITE_16_STATIC
9#define STBIW16DEF static
10#else
11#ifdef __cplusplus
12#define STBIW16DEF extern "C"
13#else
14#define STBIW16DEF extern
15#endif
16#endif
17#endif
18
19#ifndef STB_IMAGE_WRITE_16_STATIC // C++ forbids static forward declarations
22#endif
23
24#ifndef STBI_WRITE_16_NO_STDIO
25STBIW16DEF int stbi_write_png16(char const* filename, int w, int h, int comp, const void* data, int stride_in_bytes);
26STBIW16DEF int stbi_write_png16_to_func(stbi_write_func* func, void* context, int w, int h, int comp, const void* data, int stride_in_bytes);
27
28#endif // INCLUDE_STB_IMAGE_WRITE_16_H
29
30#ifdef STB_IMAGE_WRITE_16_IMPLEMENTATION
31
32#ifdef _WIN32
33#ifndef _CRT_SECURE_NO_WARNINGS
34#define _CRT_SECURE_NO_WARNINGS
35#endif
36#ifndef _CRT_NONSTDC_NO_DEPRECATE
37#define _CRT_NONSTDC_NO_DEPRECATE
38#endif
39#endif
40
41
42#ifndef STBI_WRITE_16_NO_STDIO
43#include <stdio.h>
44#endif // STBI_WRITE_NO_STDIO
45
46#include <stdarg.h>
47#include <stdlib.h>
48#include <string.h>
49#include <math.h>
50
51#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
52// ok
53#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
54// ok
55#else
56#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
57#endif
58
59#ifndef STBIW_MALLOC
60#define STBIW_MALLOC(sz) malloc(sz)
61#define STBIW_REALLOC(p,newsz) realloc(p,newsz)
62#define STBIW_FREE(p) free(p)
63#endif
64
65#ifndef STBIW_REALLOC_SIZED
66#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
67#endif
68
69
70#ifndef STBIW_MEMMOVE
71#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
72#endif
73
74
75#ifndef STBIW_ASSERT
76#include <assert.h>
77#define STBIW_ASSERT(x) assert(x)
78#endif
79
80#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
81
82#ifdef STB_IMAGE_WRITE_STATIC
84static int stbi_write_force_png_16_filter = -1;
85#else
88#endif
89
90STBIW16DEF unsigned char* stbi_write_png16_to_mem(const unsigned short* pixels, int stride_bytes, int x, int y, int comp, int* out_len)
91{
92 int force_filter = stbi_write_force_png_16_filter;
93 int ctype[5] = { -1, 0, 4, 2, 6 };
94 unsigned char sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
95 unsigned char* out, * o, * filt, * zlib, * pixels8;
96 signed char* line_buffer;
97 int j, zlen;
98 int bytes_per_pixel = comp * 2;
99
100 /* Normalize stride_bytes to row stride in bytes */
101 if (stride_bytes == 0)
102 stride_bytes = x * bytes_per_pixel;
103
104 if (force_filter >= 5) {
105 force_filter = -1;
106 }
107
108 /* convert 16-bit samples to network-order bytes (big-endian) */
109 pixels8 = (unsigned char*)STBIW_MALLOC((size_t)y * stride_bytes);
110 if (!pixels8) return 0;
111 {
112 /* ? FIX: Treat stride_bytes as BYTE offset, cast pixels to byte pointer */
113 for (int r = 0; r < y; ++r) {
114 const unsigned char* src_bytes = (const unsigned char*)pixels + (size_t)r * stride_bytes;
115 const unsigned short* src = (const unsigned short*)src_bytes;
116 unsigned char* dst = pixels8 + (size_t)r * stride_bytes;
117 for (int i = 0; i < x; ++i) {
118 for (int c = 0; c < comp; ++c) {
119 unsigned short v = src[i * comp + c];
120 /* PNG requires big-endian sample bytes */
121 dst[(i * bytes_per_pixel) + c * 2 + 0] = STBIW_UCHAR(v >> 8);
122 dst[(i * bytes_per_pixel) + c * 2 + 1] = STBIW_UCHAR(v);
123 }
124 }
125 }
126 }
127
128 /* Build filtered image buffer (reuses existing filter logic, operating on bytes) */
129 filt = (unsigned char*)STBIW_MALLOC((x * bytes_per_pixel + 1) * y); if (!filt) { STBIW_FREE(pixels8); return 0; }
130 line_buffer = (signed char*)STBIW_MALLOC(x * bytes_per_pixel); if (!line_buffer) { STBIW_FREE(filt); STBIW_FREE(pixels8); return 0; }
131 for (j = 0; j < y; ++j) {
132 int filter_type;
133 if (force_filter > -1) {
134 filter_type = force_filter;
135 stbiw__encode_png_line(pixels8, stride_bytes, x, y, j, bytes_per_pixel, force_filter, line_buffer);
136 }
137 else {
138 int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
139 for (filter_type = 0; filter_type < 5; filter_type++) {
140 stbiw__encode_png_line(pixels8, stride_bytes, x, y, j, bytes_per_pixel, filter_type, line_buffer);
141 est = 0;
142 for (i = 0; i < x * bytes_per_pixel; ++i) {
143 est += abs((signed char)line_buffer[i]);
144 }
145 if (est < best_filter_val) {
146 best_filter_val = est;
147 best_filter = filter_type;
148 }
149 }
150 if (filter_type != best_filter) {
151 stbiw__encode_png_line(pixels8, stride_bytes, x, y, j, bytes_per_pixel, best_filter, line_buffer);
152 filter_type = best_filter;
153 }
154 }
155 filt[j * (x * bytes_per_pixel + 1)] = (unsigned char)filter_type;
156 STBIW_MEMMOVE(filt + j * (x * bytes_per_pixel + 1) + 1, line_buffer, x * bytes_per_pixel);
157 }
158 STBIW_FREE(line_buffer);
159 STBIW_FREE(pixels8);
160
161 zlib = stbi_zlib_compress(filt, y * (x * bytes_per_pixel + 1), &zlen, stbi_write_png_16_compression_level);
162 STBIW_FREE(filt);
163 if (!zlib) return 0;
164
165 /* allocate output and write PNG chunks; IHDR bit depth = 16 */
166 out = (unsigned char*)STBIW_MALLOC(8 + 12 + 13 + 12 + zlen + 12);
167 if (!out) { STBIW_FREE(zlib); return 0; }
168 *out_len = 8 + 12 + 13 + 12 + zlen + 12;
169
170 o = out;
171 STBIW_MEMMOVE(o, sig, 8); o += 8;
172 stbiw__wp32(o, 13); // header length
173 stbiw__wptag(o, "IHDR");
174 stbiw__wp32(o, x);
175 stbiw__wp32(o, y);
176 *o++ = 16; /* 16-bit depth */
177 *o++ = STBIW_UCHAR(ctype[comp]); /* color type */
178 *o++ = 0;
179 *o++ = 0;
180 *o++ = 0;
181 stbiw__wpcrc(&o, 13);
182
183 stbiw__wp32(o, zlen);
184 stbiw__wptag(o, "IDAT");
185 STBIW_MEMMOVE(o, zlib, zlen);
186 o += zlen;
187 STBIW_FREE(zlib);
188 stbiw__wpcrc(&o, zlen);
189
190 stbiw__wp32(o, 0);
191 stbiw__wptag(o, "IEND");
192 stbiw__wpcrc(&o, 0);
193
194 STBIW_ASSERT(o == out + *out_len);
195
196 return out;
197}
198
199STBIW16DEF int stbi_write_png16_to_func(stbi_write_func* func, void* context, int x, int y, int comp, const void* data, int stride_bytes)
200{
201 int len;
202 unsigned char* png = stbi_write_png16_to_mem((const unsigned short*)data, stride_bytes, x, y, comp, &len);
203 if (png == NULL) return 0;
204 func(context, png, len);
205 STBIW_FREE(png);
206 return 1;
207}
208
209#ifndef STBI_WRITE_NO_STDIO
210STBIW16DEF int stbi_write_png16(char const* filename, int x, int y, int comp, const void* data, int stride_bytes)
211{
212 FILE* f;
213 int len;
214 unsigned char* png = stbi_write_png16_to_mem((const unsigned short*)data, stride_bytes, x, y, comp, &len);
215 if (png == NULL) return 0;
216
217 f = stbiw__fopen(filename, "wb");
218 if (!f) { STBIW_FREE(png); return 0; }
219 fwrite(png, 1, len, f);
220 fclose(f);
221 STBIW_FREE(png);
222 return 1;
223}
224#endif
225
226#endif // STB_IMAGE_WRITE_16_IMPLEMENTATION
227
228#endif // INCLUDE_STB_IMAGE_WRITE_16_H
__forceinline scalar abs(scalar a)
Definition scalar.h:451
float r
Definition ssaocontext.cc:49
STBIW16DEF int stbi_write_png16(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
int stbi_write_force_png_16_filter
STBIW16DEF int stbi_write_png16_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes)
#define STBIW16DEF
Definition stb_image_write_16bit.h:14
int stbi_write_png_16_compression_level