|  |  | @ -24,11 +24,12 @@ ABOUT: | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | USAGE: |  |  |  | USAGE: | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |    There are three functions, one for each image file format: |  |  |  |    There are four functions, one for each image file format: | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |      int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); |  |  |  |      int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); | 
			
		
	
		
		
			
				
					
					|  |  |  |      int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); |  |  |  |      int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); | 
			
		
	
		
		
			
				
					
					|  |  |  |      int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); |  |  |  |      int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      int stbi_write_hdr(char const *filename, int w, int h, int comp, const void *data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |    Each function returns 0 on failure and non-0 on success. |  |  |  |    Each function returns 0 on failure and non-0 on success. | 
			
		
	
		
		
			
				
					
					|  |  |  |    
 |  |  |  |    
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -51,6 +52,10 @@ USAGE: | 
			
		
	
		
		
			
				
					
					|  |  |  |    formats do not. (Thus you cannot write a native-format BMP through the BMP |  |  |  |    formats do not. (Thus you cannot write a native-format BMP through the BMP | 
			
		
	
		
		
			
				
					
					|  |  |  |    writer, both because it is in BGR order and because it may have padding |  |  |  |    writer, both because it is in BGR order and because it may have padding | 
			
		
	
		
		
			
				
					
					|  |  |  |    at the end of the line.) |  |  |  |    at the end of the line.) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    HDR expects linear float data. Since the format is always 32-bit rgb(e) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    data, alpha (if provided) is discarded, and for monochrome data it is | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    replicated across all three channels. | 
			
		
	
		
		
			
				
					
					|  |  |  | */ |  |  |  | */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #ifndef INCLUDE_STB_IMAGE_WRITE_H |  |  |  | #ifndef INCLUDE_STB_IMAGE_WRITE_H | 
			
		
	
	
		
		
			
				
					|  |  | @ -63,6 +68,7 @@ extern "C" { | 
			
		
	
		
		
			
				
					
					|  |  |  | extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); |  |  |  | extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); | 
			
		
	
		
		
			
				
					
					|  |  |  | extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); |  |  |  | extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); | 
			
		
	
		
		
			
				
					
					|  |  |  | extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); |  |  |  | extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | extern int stbi_write_hdr(char const *filename, int w, int h, int comp, const void *data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #ifdef __cplusplus |  |  |  | #ifdef __cplusplus | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | @ -185,6 +191,159 @@ int stbi_write_tga(char const *filename, int x, int y, int comp, const void *dat | 
			
		
	
		
		
			
				
					
					|  |  |  |                   "111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8); |  |  |  |                   "111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // *************************************************************************************************
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Radiance RGBE HDR writer
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // originally by Baldur Karlsson
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #define stbiw__max(a, b)  ((a) > (b) ? (a) : (b)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    int exponent; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    if (maxcomp < 1e-32) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       maxcomp = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       rgbe[0] = (unsigned char)(linear[0] * maxcomp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       rgbe[1] = (unsigned char)(linear[1] * maxcomp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       rgbe[2] = (unsigned char)(linear[2] * maxcomp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       rgbe[3] = (unsigned char)(exponent + 128); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void stbiw__write_rle_data(FILE *f, int length, unsigned char databyte) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    unsigned char lengthbyte = 0x80 | (unsigned char)(length & 0x7f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    fwrite(&lengthbyte, 1, 1, f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    fwrite(&databyte, 1, 1, f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void stbiw__write_nonrle_data(FILE *f, int length, unsigned char *data) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    unsigned char lengthbyte = (unsigned char )(length & 0xff); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    fwrite(&lengthbyte, 1, 1, f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    fwrite(data, length, 1, f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scratch, float *scanline) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    unsigned char rgbe[4]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    float linear[3]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    int x; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    scanlineheader[2] = (width&0xff00)>>8; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    scanlineheader[3] = (width&0x00ff); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    /* skip RLE for images too small or large */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    if (width < 8 || width >= 32768) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for (x=0; x < width; x++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          switch (comp) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 4: /* fallthrough */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 3: linear[2] = scanline[x*comp + 2]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     linear[1] = scanline[x*comp + 1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     linear[0] = scanline[x*comp + 0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 2: /* fallthrough */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          stbiw__linear_to_rgbe(rgbe, linear); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          fwrite(rgbe, 4, 1, f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       /* encode into scratch buffer */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for (x=0; x < width; x++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          switch(comp) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 4: /* fallthrough */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 3: linear[2] = scanline[x*comp + 2]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     linear[1] = scanline[x*comp + 1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     linear[0] = scanline[x*comp + 0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 2: /* fallthrough */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          stbiw__linear_to_rgbe(rgbe, linear); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          scratch[x + width*0] = rgbe[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          scratch[x + width*1] = rgbe[1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          scratch[x + width*2] = rgbe[2]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          scratch[x + width*3] = rgbe[3]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       fwrite(scanlineheader, 4, 1, f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       /* RLE each component separately */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for (x=0; x < 4; x++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          unsigned char *comp = &scratch[width*x]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          int runstart = 0, head = 0, rlerun = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          while (head < width) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             head++; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (head - runstart == 127 && rlerun == 1) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                // max length RLE run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                stbiw__write_rle_data(f, head - runstart, comp[runstart]); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                rlerun = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                runstart = head; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else if (head - runstart == 128 && rlerun == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                // max length non-RLE run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                stbiw__write_nonrle_data(f, head - runstart, comp+runstart); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                rlerun = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                runstart = head; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else if (comp[head] != comp[head-1] && rlerun == 1) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                // end of RLE run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                stbiw__write_rle_data(f, head - runstart, comp[runstart]); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                rlerun = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                runstart = head; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                // continue accumulating RLE run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                if (rlerun == 1) continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                // see if we can start an RLE run, at least 3 bytes same
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                if (rlerun == 0 && head - runstart >= 2 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     && comp[head] == comp[head-1] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     && comp[head] == comp[head-2]) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                   // found a run. Flush non-run (if there is anything) and then start an RLE run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                   if (head - runstart > 2) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                      stbiw__write_nonrle_data(f, head-2 - runstart, comp+runstart); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                   rlerun = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                   runstart = head-2; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          // flush remaining sequence (if any)
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          if      (rlerun == 1)         stbiw__write_rle_data(f, head - runstart, comp[runstart]); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          else if (head - runstart > 0) stbiw__write_nonrle_data(f, head - runstart, comp+runstart); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | int stbi_write_hdr(char const *filename, int x, int y, int comp, const void *data) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    int i; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    FILE *f; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    unsigned char *scratch; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    if (y <= 0 || x <= 0) return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    f = fopen(filename, "wb"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    if (f) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       float *scanline = (float *)data; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       /* Each component is stored separately. Allocate scratch space for full output scanline. */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       scratch = (unsigned char *) malloc(x*4); if (!scanline) { fclose(f); return 0; } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       fprintf(f, "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       fprintf(f, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for(i=0; i < y; i++) stbiw__write_hdr_scanline(f, x, comp, scratch, scanline + comp*i*x); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       free(scratch); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       fclose(f); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |    return f != NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
 |  |  |  | // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define stbiw__sbraw(a) ((int *) (a) - 2) |  |  |  | #define stbiw__sbraw(a) ((int *) (a) - 2) | 
			
		
	
		
		
			
				
					
					|  |  |  | #define stbiw__sbm(a)   stbiw__sbraw(a)[0] |  |  |  | #define stbiw__sbm(a)   stbiw__sbraw(a)[0] | 
			
		
	
	
		
		
			
				
					|  |  | 
 |