stb_image_write.h (40569B)
1 /* stb_image_write - v1.05 - public domain - http://nothings.org/stb/stb_image_write.h 2 writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015 3 no warranty implied; use at your own risk 4 5 Before #including, 6 7 #define STB_IMAGE_WRITE_IMPLEMENTATION 8 9 in the file that you want to have the implementation. 10 11 Will probably not work correctly with strict-aliasing optimizations. 12 13 ABOUT: 14 15 This header file is a library for writing images to C stdio. It could be 16 adapted to write to memory or a general streaming interface; let me know. 17 18 The PNG output is not optimal; it is 20-50% larger than the file 19 written by a decent optimizing implementation. This library is designed 20 for source code compactness and simplicity, not optimal image file size 21 or run-time performance. 22 23 BUILDING: 24 25 You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. 26 You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace 27 malloc,realloc,free. 28 You can define STBIW_MEMMOVE() to replace memmove() 29 30 USAGE: 31 32 There are four functions, one for each image file format: 33 34 int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 35 int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 36 int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 37 int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); 38 39 There are also four equivalent functions that use an arbitrary write function. You are 40 expected to open/close your file-equivalent before and after calling these: 41 42 int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); 43 int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 44 int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 45 int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); 46 47 where the callback is: 48 void stbi_write_func(void *context, void *data, int size); 49 50 You can define STBI_WRITE_NO_STDIO to disable the file variant of these 51 functions, so the library will not use stdio.h at all. However, this will 52 also disable HDR writing, because it requires stdio for formatted output. 53 54 Each function returns 0 on failure and non-0 on success. 55 56 The functions create an image file defined by the parameters. The image 57 is a rectangle of pixels stored from left-to-right, top-to-bottom. 58 Each pixel contains 'comp' channels of data stored interleaved with 8-bits 59 per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is 60 monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. 61 The *data pointer points to the first byte of the top-left-most pixel. 62 For PNG, "stride_in_bytes" is the distance in bytes from the first byte of 63 a row of pixels to the first byte of the next row of pixels. 64 65 PNG creates output files with the same number of components as the input. 66 The BMP format expands Y to RGB in the file format and does not 67 output alpha. 68 69 PNG supports writing rectangles of data even when the bytes storing rows of 70 data are not consecutive in memory (e.g. sub-rectangles of a larger image), 71 by supplying the stride between the beginning of adjacent rows. The other 72 formats do not. (Thus you cannot write a native-format BMP through the BMP 73 writer, both because it is in BGR order and because it may have padding 74 at the end of the line.) 75 76 HDR expects linear float data. Since the format is always 32-bit rgb(e) 77 data, alpha (if provided) is discarded, and for monochrome data it is 78 replicated across all three channels. 79 80 TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed 81 data, set the global variable 'stbi_write_tga_with_rle' to 0. 82 83 CREDITS: 84 85 PNG/BMP/TGA 86 Sean Barrett 87 HDR 88 Baldur Karlsson 89 TGA monochrome: 90 Jean-Sebastien Guay 91 misc enhancements: 92 Tim Kelsey 93 TGA RLE 94 Alan Hickman 95 initial file IO callback implementation 96 Emmanuel Julien 97 bugfixes: 98 github:Chribba 99 Guillaume Chereau 100 github:jry2 101 github:romigrou 102 Sergio Gonzalez 103 Jonas Karlsson 104 Filip Wasil 105 Thatcher Ulrich 106 github:poppolopoppo 107 Patrick Boettcher 108 109 LICENSE 110 111 See end of file for license information. 112 113 */ 114 115 #ifndef INCLUDE_STB_IMAGE_WRITE_H 116 #define INCLUDE_STB_IMAGE_WRITE_H 117 118 #ifdef __cplusplus 119 extern "C" { 120 #endif 121 122 #ifdef STB_IMAGE_WRITE_STATIC 123 #define STBIWDEF static 124 #else 125 #define STBIWDEF extern 126 extern int stbi_write_tga_with_rle; 127 #endif 128 129 #ifndef STBI_WRITE_NO_STDIO 130 STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 131 STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 132 STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 133 STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); 134 #endif 135 136 typedef void stbi_write_func(void *context, void *data, int size); 137 138 STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); 139 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 140 STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 141 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); 142 143 #ifdef __cplusplus 144 } 145 #endif 146 147 #endif//INCLUDE_STB_IMAGE_WRITE_H 148 149 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION 150 151 #ifdef _WIN32 152 #ifndef _CRT_SECURE_NO_WARNINGS 153 #define _CRT_SECURE_NO_WARNINGS 154 #endif 155 #ifndef _CRT_NONSTDC_NO_DEPRECATE 156 #define _CRT_NONSTDC_NO_DEPRECATE 157 #endif 158 #endif 159 160 #ifndef STBI_WRITE_NO_STDIO 161 #include <stdio.h> 162 #endif // STBI_WRITE_NO_STDIO 163 164 #include <stdarg.h> 165 #include <stdlib.h> 166 #include <string.h> 167 #include <math.h> 168 169 #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) 170 // ok 171 #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) 172 // ok 173 #else 174 #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." 175 #endif 176 177 #ifndef STBIW_MALLOC 178 #define STBIW_MALLOC(sz) malloc(sz) 179 #define STBIW_REALLOC(p,newsz) realloc(p,newsz) 180 #define STBIW_FREE(p) free(p) 181 #endif 182 183 #ifndef STBIW_REALLOC_SIZED 184 #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) 185 #endif 186 187 188 #ifndef STBIW_MEMMOVE 189 #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) 190 #endif 191 192 193 #ifndef STBIW_ASSERT 194 #include <assert.h> 195 #define STBIW_ASSERT(x) assert(x) 196 #endif 197 198 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) 199 200 typedef struct 201 { 202 stbi_write_func *func; 203 void *context; 204 } stbi__write_context; 205 206 // initialize a callback-based context 207 static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) 208 { 209 s->func = c; 210 s->context = context; 211 } 212 213 #ifndef STBI_WRITE_NO_STDIO 214 215 static void stbi__stdio_write(void *context, void *data, int size) 216 { 217 fwrite(data,1,size,(FILE*) context); 218 } 219 220 static int stbi__start_write_file(stbi__write_context *s, const char *filename) 221 { 222 FILE *f = fopen(filename, "wb"); 223 stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); 224 return f != NULL; 225 } 226 227 static void stbi__end_write_file(stbi__write_context *s) 228 { 229 fclose((FILE *)s->context); 230 } 231 232 #endif // !STBI_WRITE_NO_STDIO 233 234 typedef unsigned int stbiw_uint32; 235 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; 236 237 #ifdef STB_IMAGE_WRITE_STATIC 238 static int stbi_write_tga_with_rle = 1; 239 #else 240 int stbi_write_tga_with_rle = 1; 241 #endif 242 243 static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) 244 { 245 while (*fmt) { 246 switch (*fmt++) { 247 case ' ': break; 248 case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); 249 s->func(s->context,&x,1); 250 break; } 251 case '2': { int x = va_arg(v,int); 252 unsigned char b[2]; 253 b[0] = STBIW_UCHAR(x); 254 b[1] = STBIW_UCHAR(x>>8); 255 s->func(s->context,b,2); 256 break; } 257 case '4': { stbiw_uint32 x = va_arg(v,int); 258 unsigned char b[4]; 259 b[0]=STBIW_UCHAR(x); 260 b[1]=STBIW_UCHAR(x>>8); 261 b[2]=STBIW_UCHAR(x>>16); 262 b[3]=STBIW_UCHAR(x>>24); 263 s->func(s->context,b,4); 264 break; } 265 default: 266 STBIW_ASSERT(0); 267 return; 268 } 269 } 270 } 271 272 static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) 273 { 274 va_list v; 275 va_start(v, fmt); 276 stbiw__writefv(s, fmt, v); 277 va_end(v); 278 } 279 280 static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) 281 { 282 unsigned char arr[3]; 283 arr[0] = a, arr[1] = b, arr[2] = c; 284 s->func(s->context, arr, 3); 285 } 286 287 static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) 288 { 289 unsigned char bg[3] = { 255, 0, 255}, px[3]; 290 int k; 291 292 if (write_alpha < 0) 293 s->func(s->context, &d[comp - 1], 1); 294 295 switch (comp) { 296 case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case 297 case 1: 298 if (expand_mono) 299 stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp 300 else 301 s->func(s->context, d, 1); // monochrome TGA 302 break; 303 case 4: 304 if (!write_alpha) { 305 // composite against pink background 306 for (k = 0; k < 3; ++k) 307 px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; 308 stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); 309 break; 310 } 311 /* FALLTHROUGH */ 312 case 3: 313 stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); 314 break; 315 } 316 if (write_alpha > 0) 317 s->func(s->context, &d[comp - 1], 1); 318 } 319 320 static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) 321 { 322 stbiw_uint32 zero = 0; 323 int i,j, j_end; 324 325 if (y <= 0) 326 return; 327 328 if (vdir < 0) 329 j_end = -1, j = y-1; 330 else 331 j_end = y, j = 0; 332 333 for (; j != j_end; j += vdir) { 334 for (i=0; i < x; ++i) { 335 unsigned char *d = (unsigned char *) data + (j*x+i)*comp; 336 stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); 337 } 338 s->func(s->context, &zero, scanline_pad); 339 } 340 } 341 342 static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) 343 { 344 if (y < 0 || x < 0) { 345 return 0; 346 } else { 347 va_list v; 348 va_start(v, fmt); 349 stbiw__writefv(s, fmt, v); 350 va_end(v); 351 stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); 352 return 1; 353 } 354 } 355 356 static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) 357 { 358 int pad = (-x*3) & 3; 359 return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, 360 "11 4 22 4" "4 44 22 444444", 361 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header 362 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header 363 } 364 365 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) 366 { 367 stbi__write_context s; 368 stbi__start_write_callbacks(&s, func, context); 369 return stbi_write_bmp_core(&s, x, y, comp, data); 370 } 371 372 #ifndef STBI_WRITE_NO_STDIO 373 STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) 374 { 375 stbi__write_context s; 376 if (stbi__start_write_file(&s,filename)) { 377 int r = stbi_write_bmp_core(&s, x, y, comp, data); 378 stbi__end_write_file(&s); 379 return r; 380 } else 381 return 0; 382 } 383 #endif //!STBI_WRITE_NO_STDIO 384 385 static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) 386 { 387 int has_alpha = (comp == 2 || comp == 4); 388 int colorbytes = has_alpha ? comp-1 : comp; 389 int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 390 391 if (y < 0 || x < 0) 392 return 0; 393 394 if (!stbi_write_tga_with_rle) { 395 return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, 396 "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); 397 } else { 398 int i,j,k; 399 400 stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); 401 402 for (j = y - 1; j >= 0; --j) { 403 unsigned char *row = (unsigned char *) data + j * x * comp; 404 int len; 405 406 for (i = 0; i < x; i += len) { 407 unsigned char *begin = row + i * comp; 408 int diff = 1; 409 len = 1; 410 411 if (i < x - 1) { 412 ++len; 413 diff = memcmp(begin, row + (i + 1) * comp, comp); 414 if (diff) { 415 const unsigned char *prev = begin; 416 for (k = i + 2; k < x && len < 128; ++k) { 417 if (memcmp(prev, row + k * comp, comp)) { 418 prev += comp; 419 ++len; 420 } else { 421 --len; 422 break; 423 } 424 } 425 } else { 426 for (k = i + 2; k < x && len < 128; ++k) { 427 if (!memcmp(begin, row + k * comp, comp)) { 428 ++len; 429 } else { 430 break; 431 } 432 } 433 } 434 } 435 436 if (diff) { 437 unsigned char header = STBIW_UCHAR(len - 1); 438 s->func(s->context, &header, 1); 439 for (k = 0; k < len; ++k) { 440 stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); 441 } 442 } else { 443 unsigned char header = STBIW_UCHAR(len - 129); 444 s->func(s->context, &header, 1); 445 stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); 446 } 447 } 448 } 449 } 450 return 1; 451 } 452 453 int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) 454 { 455 stbi__write_context s; 456 stbi__start_write_callbacks(&s, func, context); 457 return stbi_write_tga_core(&s, x, y, comp, (void *) data); 458 } 459 460 #ifndef STBI_WRITE_NO_STDIO 461 int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) 462 { 463 stbi__write_context s; 464 if (stbi__start_write_file(&s,filename)) { 465 int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); 466 stbi__end_write_file(&s); 467 return r; 468 } else 469 return 0; 470 } 471 #endif 472 473 // ************************************************************************************************* 474 // Radiance RGBE HDR writer 475 // by Baldur Karlsson 476 477 #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) 478 479 void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) 480 { 481 int exponent; 482 float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); 483 484 if (maxcomp < 1e-32f) { 485 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; 486 } else { 487 float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; 488 489 rgbe[0] = (unsigned char)(linear[0] * normalize); 490 rgbe[1] = (unsigned char)(linear[1] * normalize); 491 rgbe[2] = (unsigned char)(linear[2] * normalize); 492 rgbe[3] = (unsigned char)(exponent + 128); 493 } 494 } 495 496 void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) 497 { 498 unsigned char lengthbyte = STBIW_UCHAR(length+128); 499 STBIW_ASSERT(length+128 <= 255); 500 s->func(s->context, &lengthbyte, 1); 501 s->func(s->context, &databyte, 1); 502 } 503 504 void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) 505 { 506 unsigned char lengthbyte = STBIW_UCHAR(length); 507 STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code 508 s->func(s->context, &lengthbyte, 1); 509 s->func(s->context, data, length); 510 } 511 512 void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) 513 { 514 unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; 515 unsigned char rgbe[4]; 516 float linear[3]; 517 int x; 518 519 scanlineheader[2] = (width&0xff00)>>8; 520 scanlineheader[3] = (width&0x00ff); 521 522 /* skip RLE for images too small or large */ 523 if (width < 8 || width >= 32768) { 524 for (x=0; x < width; x++) { 525 switch (ncomp) { 526 case 4: /* fallthrough */ 527 case 3: linear[2] = scanline[x*ncomp + 2]; 528 linear[1] = scanline[x*ncomp + 1]; 529 linear[0] = scanline[x*ncomp + 0]; 530 break; 531 default: 532 linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; 533 break; 534 } 535 stbiw__linear_to_rgbe(rgbe, linear); 536 s->func(s->context, rgbe, 4); 537 } 538 } else { 539 int c,r; 540 /* encode into scratch buffer */ 541 for (x=0; x < width; x++) { 542 switch(ncomp) { 543 case 4: /* fallthrough */ 544 case 3: linear[2] = scanline[x*ncomp + 2]; 545 linear[1] = scanline[x*ncomp + 1]; 546 linear[0] = scanline[x*ncomp + 0]; 547 break; 548 default: 549 linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; 550 break; 551 } 552 stbiw__linear_to_rgbe(rgbe, linear); 553 scratch[x + width*0] = rgbe[0]; 554 scratch[x + width*1] = rgbe[1]; 555 scratch[x + width*2] = rgbe[2]; 556 scratch[x + width*3] = rgbe[3]; 557 } 558 559 s->func(s->context, scanlineheader, 4); 560 561 /* RLE each component separately */ 562 for (c=0; c < 4; c++) { 563 unsigned char *comp = &scratch[width*c]; 564 565 x = 0; 566 while (x < width) { 567 // find first run 568 r = x; 569 while (r+2 < width) { 570 if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) 571 break; 572 ++r; 573 } 574 if (r+2 >= width) 575 r = width; 576 // dump up to first run 577 while (x < r) { 578 int len = r-x; 579 if (len > 128) len = 128; 580 stbiw__write_dump_data(s, len, &comp[x]); 581 x += len; 582 } 583 // if there's a run, output it 584 if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd 585 // find next byte after run 586 while (r < width && comp[r] == comp[x]) 587 ++r; 588 // output run up to r 589 while (x < r) { 590 int len = r-x; 591 if (len > 127) len = 127; 592 stbiw__write_run_data(s, len, comp[x]); 593 x += len; 594 } 595 } 596 } 597 } 598 } 599 } 600 601 static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) 602 { 603 if (y <= 0 || x <= 0 || data == NULL) 604 return 0; 605 else { 606 // Each component is stored separately. Allocate scratch space for full output scanline. 607 unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); 608 int i, len; 609 char buffer[128]; 610 char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; 611 s->func(s->context, header, sizeof(header)-1); 612 613 len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); 614 s->func(s->context, buffer, len); 615 616 for(i=0; i < y; i++) 617 stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x); 618 STBIW_FREE(scratch); 619 return 1; 620 } 621 } 622 623 int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) 624 { 625 stbi__write_context s; 626 stbi__start_write_callbacks(&s, func, context); 627 return stbi_write_hdr_core(&s, x, y, comp, (float *) data); 628 } 629 630 #ifndef STBI_WRITE_NO_STDIO 631 int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) 632 { 633 stbi__write_context s; 634 if (stbi__start_write_file(&s,filename)) { 635 int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); 636 stbi__end_write_file(&s); 637 return r; 638 } else 639 return 0; 640 } 641 #endif // STBI_WRITE_NO_STDIO 642 643 644 ////////////////////////////////////////////////////////////////////////////// 645 // 646 // PNG writer 647 // 648 649 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() 650 #define stbiw__sbraw(a) ((int *) (a) - 2) 651 #define stbiw__sbm(a) stbiw__sbraw(a)[0] 652 #define stbiw__sbn(a) stbiw__sbraw(a)[1] 653 654 #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) 655 #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) 656 #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) 657 658 #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) 659 #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) 660 #define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) 661 662 static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) 663 { 664 int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; 665 void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); 666 STBIW_ASSERT(p); 667 if (p) { 668 if (!*arr) ((int *) p)[1] = 0; 669 *arr = (void *) ((int *) p + 2); 670 stbiw__sbm(*arr) = m; 671 } 672 return *arr; 673 } 674 675 static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) 676 { 677 while (*bitcount >= 8) { 678 stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); 679 *bitbuffer >>= 8; 680 *bitcount -= 8; 681 } 682 return data; 683 } 684 685 static int stbiw__zlib_bitrev(int code, int codebits) 686 { 687 int res=0; 688 while (codebits--) { 689 res = (res << 1) | (code & 1); 690 code >>= 1; 691 } 692 return res; 693 } 694 695 static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) 696 { 697 int i; 698 for (i=0; i < limit && i < 258; ++i) 699 if (a[i] != b[i]) break; 700 return i; 701 } 702 703 static unsigned int stbiw__zhash(unsigned char *data) 704 { 705 stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); 706 hash ^= hash << 3; 707 hash += hash >> 5; 708 hash ^= hash << 4; 709 hash += hash >> 17; 710 hash ^= hash << 25; 711 hash += hash >> 6; 712 return hash; 713 } 714 715 #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) 716 #define stbiw__zlib_add(code,codebits) \ 717 (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) 718 #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) 719 // default huffman tables 720 #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) 721 #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) 722 #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) 723 #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) 724 #define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) 725 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) 726 727 #define stbiw__ZHASH 16384 728 729 unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) 730 { 731 static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; 732 static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; 733 static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; 734 static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; 735 unsigned int bitbuf=0; 736 int i,j, bitcount=0; 737 unsigned char *out = NULL; 738 unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**)); 739 if (quality < 5) quality = 5; 740 741 stbiw__sbpush(out, 0x78); // DEFLATE 32K window 742 stbiw__sbpush(out, 0x5e); // FLEVEL = 1 743 stbiw__zlib_add(1,1); // BFINAL = 1 744 stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman 745 746 for (i=0; i < stbiw__ZHASH; ++i) 747 hash_table[i] = NULL; 748 749 i=0; 750 while (i < data_len-3) { 751 // hash next 3 bytes of data to be compressed 752 int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; 753 unsigned char *bestloc = 0; 754 unsigned char **hlist = hash_table[h]; 755 int n = stbiw__sbcount(hlist); 756 for (j=0; j < n; ++j) { 757 if (hlist[j]-data > i-32768) { // if entry lies within window 758 int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); 759 if (d >= best) best=d,bestloc=hlist[j]; 760 } 761 } 762 // when hash table entry is too long, delete half the entries 763 if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { 764 STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); 765 stbiw__sbn(hash_table[h]) = quality; 766 } 767 stbiw__sbpush(hash_table[h],data+i); 768 769 if (bestloc) { 770 // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal 771 h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); 772 hlist = hash_table[h]; 773 n = stbiw__sbcount(hlist); 774 for (j=0; j < n; ++j) { 775 if (hlist[j]-data > i-32767) { 776 int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); 777 if (e > best) { // if next match is better, bail on current match 778 bestloc = NULL; 779 break; 780 } 781 } 782 } 783 } 784 785 if (bestloc) { 786 int d = (int) (data+i - bestloc); // distance back 787 STBIW_ASSERT(d <= 32767 && best <= 258); 788 for (j=0; best > lengthc[j+1]-1; ++j); 789 stbiw__zlib_huff(j+257); 790 if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); 791 for (j=0; d > distc[j+1]-1; ++j); 792 stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); 793 if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); 794 i += best; 795 } else { 796 stbiw__zlib_huffb(data[i]); 797 ++i; 798 } 799 } 800 // write out final bytes 801 for (;i < data_len; ++i) 802 stbiw__zlib_huffb(data[i]); 803 stbiw__zlib_huff(256); // end of block 804 // pad with 0 bits to byte boundary 805 while (bitcount) 806 stbiw__zlib_add(0,1); 807 808 for (i=0; i < stbiw__ZHASH; ++i) 809 (void) stbiw__sbfree(hash_table[i]); 810 STBIW_FREE(hash_table); 811 812 { 813 // compute adler32 on input 814 unsigned int s1=1, s2=0; 815 int blocklen = (int) (data_len % 5552); 816 j=0; 817 while (j < data_len) { 818 for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; 819 s1 %= 65521, s2 %= 65521; 820 j += blocklen; 821 blocklen = 5552; 822 } 823 stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); 824 stbiw__sbpush(out, STBIW_UCHAR(s2)); 825 stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); 826 stbiw__sbpush(out, STBIW_UCHAR(s1)); 827 } 828 *out_len = stbiw__sbn(out); 829 // make returned pointer freeable 830 STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); 831 return (unsigned char *) stbiw__sbraw(out); 832 } 833 834 static unsigned int stbiw__crc32(unsigned char *buffer, int len) 835 { 836 static unsigned int crc_table[256] = 837 { 838 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 839 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 840 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 841 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 842 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 843 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 844 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 845 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 846 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 847 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 848 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 849 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 850 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 851 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 852 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 853 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 854 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 855 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 856 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 857 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 858 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 859 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 860 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 861 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 862 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 863 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 864 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 865 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 866 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 867 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 868 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 869 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 870 }; 871 872 unsigned int crc = ~0u; 873 int i; 874 for (i=0; i < len; ++i) 875 crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; 876 return ~crc; 877 } 878 879 #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) 880 #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); 881 #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) 882 883 static void stbiw__wpcrc(unsigned char **data, int len) 884 { 885 unsigned int crc = stbiw__crc32(*data - len - 4, len+4); 886 stbiw__wp32(*data, crc); 887 } 888 889 static unsigned char stbiw__paeth(int a, int b, int c) 890 { 891 int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); 892 if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); 893 if (pb <= pc) return STBIW_UCHAR(b); 894 return STBIW_UCHAR(c); 895 } 896 897 // @OPTIMIZE: provide an option that always forces left-predict or paeth predict 898 unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) 899 { 900 int ctype[5] = { -1, 0, 4, 2, 6 }; 901 unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; 902 unsigned char *out,*o, *filt, *zlib; 903 signed char *line_buffer; 904 int i,j,k,p,zlen; 905 906 if (stride_bytes == 0) 907 stride_bytes = x * n; 908 909 filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; 910 line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } 911 for (j=0; j < y; ++j) { 912 static int mapping[] = { 0,1,2,3,4 }; 913 static int firstmap[] = { 0,1,0,5,6 }; 914 int *mymap = (j != 0) ? mapping : firstmap; 915 int best = 0, bestval = 0x7fffffff; 916 for (p=0; p < 2; ++p) { 917 for (k= p?best:0; k < 5; ++k) { // @TODO: clarity: rewrite this to go 0..5, and 'continue' the unwanted ones during 2nd pass 918 int type = mymap[k],est=0; 919 unsigned char *z = pixels + stride_bytes*j; 920 for (i=0; i < n; ++i) 921 switch (type) { 922 case 0: line_buffer[i] = z[i]; break; 923 case 1: line_buffer[i] = z[i]; break; 924 case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; 925 case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; 926 case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break; 927 case 5: line_buffer[i] = z[i]; break; 928 case 6: line_buffer[i] = z[i]; break; 929 } 930 for (i=n; i < x*n; ++i) { 931 switch (type) { 932 case 0: line_buffer[i] = z[i]; break; 933 case 1: line_buffer[i] = z[i] - z[i-n]; break; 934 case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; 935 case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; 936 case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; 937 case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; 938 case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; 939 } 940 } 941 if (p) break; 942 for (i=0; i < x*n; ++i) 943 est += abs((signed char) line_buffer[i]); 944 if (est < bestval) { bestval = est; best = k; } 945 } 946 } 947 // when we get here, best contains the filter type, and line_buffer contains the data 948 filt[j*(x*n+1)] = (unsigned char) best; 949 STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); 950 } 951 STBIW_FREE(line_buffer); 952 zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory 953 STBIW_FREE(filt); 954 if (!zlib) return 0; 955 956 // each tag requires 12 bytes of overhead 957 out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); 958 if (!out) return 0; 959 *out_len = 8 + 12+13 + 12+zlen + 12; 960 961 o=out; 962 STBIW_MEMMOVE(o,sig,8); o+= 8; 963 stbiw__wp32(o, 13); // header length 964 stbiw__wptag(o, "IHDR"); 965 stbiw__wp32(o, x); 966 stbiw__wp32(o, y); 967 *o++ = 8; 968 *o++ = STBIW_UCHAR(ctype[n]); 969 *o++ = 0; 970 *o++ = 0; 971 *o++ = 0; 972 stbiw__wpcrc(&o,13); 973 974 stbiw__wp32(o, zlen); 975 stbiw__wptag(o, "IDAT"); 976 STBIW_MEMMOVE(o, zlib, zlen); 977 o += zlen; 978 STBIW_FREE(zlib); 979 stbiw__wpcrc(&o, zlen); 980 981 stbiw__wp32(o,0); 982 stbiw__wptag(o, "IEND"); 983 stbiw__wpcrc(&o,0); 984 985 STBIW_ASSERT(o == out + *out_len); 986 987 return out; 988 } 989 990 #ifndef STBI_WRITE_NO_STDIO 991 STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) 992 { 993 FILE *f; 994 int len; 995 unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); 996 if (png == NULL) return 0; 997 f = fopen(filename, "wb"); 998 if (!f) { STBIW_FREE(png); return 0; } 999 fwrite(png, 1, len, f); 1000 fclose(f); 1001 STBIW_FREE(png); 1002 return 1; 1003 } 1004 #endif 1005 1006 STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) 1007 { 1008 int len; 1009 unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); 1010 if (png == NULL) return 0; 1011 func(context, png, len); 1012 STBIW_FREE(png); 1013 return 1; 1014 } 1015 1016 #endif // STB_IMAGE_WRITE_IMPLEMENTATION 1017 1018 /* Revision history 1019 1.04 (2017-03-03) 1020 monochrome BMP expansion 1021 1.03 ??? 1022 1.02 (2016-04-02) 1023 avoid allocating large structures on the stack 1024 1.01 (2016-01-16) 1025 STBIW_REALLOC_SIZED: support allocators with no realloc support 1026 avoid race-condition in crc initialization 1027 minor compile issues 1028 1.00 (2015-09-14) 1029 installable file IO function 1030 0.99 (2015-09-13) 1031 warning fixes; TGA rle support 1032 0.98 (2015-04-08) 1033 added STBIW_MALLOC, STBIW_ASSERT etc 1034 0.97 (2015-01-18) 1035 fixed HDR asserts, rewrote HDR rle logic 1036 0.96 (2015-01-17) 1037 add HDR output 1038 fix monochrome BMP 1039 0.95 (2014-08-17) 1040 add monochrome TGA output 1041 0.94 (2014-05-31) 1042 rename private functions to avoid conflicts with stb_image.h 1043 0.93 (2014-05-27) 1044 warning fixes 1045 0.92 (2010-08-01) 1046 casts to unsigned char to fix warnings 1047 0.91 (2010-07-17) 1048 first public release 1049 0.90 first internal release 1050 */ 1051 1052 /* 1053 ------------------------------------------------------------------------------ 1054 This software is available under 2 licenses -- choose whichever you prefer. 1055 ------------------------------------------------------------------------------ 1056 ALTERNATIVE A - MIT License 1057 Copyright (c) 2017 Sean Barrett 1058 Permission is hereby granted, free of charge, to any person obtaining a copy of 1059 this software and associated documentation files (the "Software"), to deal in 1060 the Software without restriction, including without limitation the rights to 1061 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1062 of the Software, and to permit persons to whom the Software is furnished to do 1063 so, subject to the following conditions: 1064 The above copyright notice and this permission notice shall be included in all 1065 copies or substantial portions of the Software. 1066 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1067 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1068 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1069 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1070 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1071 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1072 SOFTWARE. 1073 ------------------------------------------------------------------------------ 1074 ALTERNATIVE B - Public Domain (www.unlicense.org) 1075 This is free and unencumbered software released into the public domain. 1076 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 1077 software, either in source code form or as a compiled binary, for any purpose, 1078 commercial or non-commercial, and by any means. 1079 In jurisdictions that recognize copyright laws, the author or authors of this 1080 software dedicate any and all copyright interest in the software to the public 1081 domain. We make this dedication for the benefit of the public at large and to 1082 the detriment of our heirs and successors. We intend this dedication to be an 1083 overt act of relinquishment in perpetuity of all present and future rights to 1084 this software under copyright law. 1085 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1086 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1087 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1088 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 1089 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 1090 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 1091 ------------------------------------------------------------------------------ 1092 */