Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
555 jrf 1
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
2
   writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
3
                            no warranty implied; use at your own risk
4
 
5
 
6
ABOUT:
7
 
8
   Implementation of the library for writing images to C stdio. It could be
9
   adapted to write to memory or a general streaming interface; let me know.
10
 
11
   The PNG output is not optimal; it is 20-50% larger than the file
12
   written by a decent optimizing implementation. This library is designed
13
   for source code compactness and simplicitly, not optimal image file size
14
   or run-time performance.
15
 
16
USAGE:
17
 
18
   There are three functions, one for each image file format:
19
 
20
     int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
21
     int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
22
     int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
23
 
24
   Each function returns 0 on failure and non-0 on success.
25
 
26
   The functions create an image file defined by the parameters. The image
27
   is a rectangle of pixels stored from left-to-right, top-to-bottom.
28
   Each pixel contains 'comp' channels of data stored interleaved with 8-bits
29
   per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
30
   monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
31
   The *data pointer points to the first byte of the top-left-most pixel.
32
   For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
33
   a row of pixels to the first byte of the next row of pixels.
34
 
35
   PNG creates output files with the same number of components as the input.
36
   The BMP and TGA formats expand Y to RGB in the file format. BMP does not
37
   output alpha.
38
 
39
   PNG supports writing rectangles of data even when the bytes storing rows of
40
   data are not consecutive in memory (e.g. sub-rectangles of a larger image),
41
   by supplying the stride between the beginning of adjacent rows. The other
42
   formats do not. (Thus you cannot write a native-format BMP through the BMP
43
   writer, both because it is in BGR order and because it may have padding
44
   at the end of the line.)
45
*/
46
 
47
#include <stdarg.h>
48
#include <stdlib.h>
49
#include <stdio.h>
50
#include <string.h>
51
#include <assert.h>
52
 
53
typedef unsigned int stbiw_uint32;
54
typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
55
 
56
static void writefv(FILE *f, const char *fmt, va_list v)
57
{
58
   while (*fmt) {
59
      switch (*fmt++) {
60
         case ' ': break;
61
         case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
62
         case '2': { int x = va_arg(v,int); unsigned char b[2];
63
                     b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
64
                     fwrite(b,2,1,f); break; }
65
         case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
66
                     b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
67
                     b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
68
                     fwrite(b,4,1,f); break; }
69
         default:
70
            assert(0);
71
            return;
72
      }
73
   }
74
}
75
 
76
static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
77
{
78
   unsigned char arr[3];
79
   arr[0] = a, arr[1] = b, arr[2] = c;
80
   fwrite(arr, 3, 1, f);
81
}
82
 
83
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad)
84
{
85
   unsigned char bg[3] = { 255, 0, 255}, px[3];
86
   stbiw_uint32 zero = 0;
87
   int i,j,k, j_end;
88
 
89
   if (y <= 0)
90
      return;
91
 
92
   if (vdir < 0) 
93
      j_end = -1, j = y-1;
94
   else
95
      j_end =  y, j = 0;
96
 
97
   for (; j != j_end; j += vdir) {
98
      for (i=0; i < x; ++i) {
99
         unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
100
         if (write_alpha < 0)
101
            fwrite(&d[comp-1], 1, 1, f);
102
         switch (comp) {
103
            case 1:
104
            case 2: write3(f, d[0],d[0],d[0]);
105
                    break;
106
            case 4:
107
               if (!write_alpha) {
108
                  // composite against pink background
109
                  for (k=0; k < 3; ++k)
110
                     px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
111
                  write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
112
                  break;
113
               }
114
               /* FALLTHROUGH */
115
            case 3:
116
               write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
117
               break;
118
         }
119
         if (write_alpha > 0)
120
            fwrite(&d[comp-1], 1, 1, f);
121
      }
122
      fwrite(&zero,scanline_pad,1,f);
123
   }
124
}
125
 
126
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...)
127
{
128
   FILE *f;
129
   if (y < 0 || x < 0) return 0;
130
   f = fopen(filename, "wb");
131
   if (f) {
132
      va_list v;
133
      va_start(v, fmt);
134
      writefv(f, fmt, v);
135
      va_end(v);
136
      write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
137
      fclose(f);
138
   }
139
   return f != NULL;
140
}
141
 
142
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
143
{
144
   int pad = (-x*3) & 3;
145
   return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad,
146
           "11 4 22 4" "4 44 22 444444",
147
           'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40,  // file header
148
            40, x,y, 1,24, 0,0,0,0,0,0);             // bitmap header
149
}
150
 
151
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
152
{
153
   int has_alpha = !(comp & 1);
154
   return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
155
                  "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
156
}
157
 
158
// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size()
159
#define stbi__sbraw(a) ((int *) (a) - 2)
160
#define stbi__sbm(a)   stbi__sbraw(a)[0]
161
#define stbi__sbn(a)   stbi__sbraw(a)[1]
162
 
163
#define stbi__sbneedgrow(a,n)  ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a))
164
#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0)
165
#define stbi__sbgrow(a,n)  stbi__sbgrowf((void **) &(a), (n), sizeof(*(a)))
166
 
167
#define stbi__sbpush(a, v)      (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v))
168
#define stbi__sbcount(a)        ((a) ? stbi__sbn(a) : 0)
169
#define stbi__sbfree(a)         ((a) ? free(stbi__sbraw(a)),0 : 0)
170
 
171
static void *stbi__sbgrowf(void **arr, int increment, int itemsize)
172
{
173
   int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1;
174
   void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
175
   assert(p);
176
   if (p) {
177
      if (!*arr) ((int *) p)[1] = 0;
178
      *arr = (void *) ((int *) p + 2);
179
      stbi__sbm(*arr) = m;
180
   }
181
   return *arr;
182
}
183
 
184
static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
185
{
186
   while (*bitcount >= 8) {
187
      stbi__sbpush(data, (unsigned char) *bitbuffer);
188
      *bitbuffer >>= 8;
189
      *bitcount -= 8;
190
   }
191
   return data;
192
}
193
 
194
static int stbi__zlib_bitrev(int code, int codebits)
195
{
196
   int res=0;
197
   while (codebits--) {
198
      res = (res << 1) | (code & 1);
199
      code >>= 1;
200
   }
201
   return res;
202
}
203
 
204
static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit)
205
{
206
   int i;
207
   for (i=0; i < limit && i < 258; ++i)
208
      if (a[i] != b[i]) break;
209
   return i;
210
}
211
 
212
static unsigned int stbi__zhash(unsigned char *data)
213
{
214
   stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
215
   hash ^= hash << 3;
216
   hash += hash >> 5;
217
   hash ^= hash << 4;
218
   hash += hash >> 17;
219
   hash ^= hash << 25;
220
   hash += hash >> 6;
221
   return hash;
222
}
223
 
224
#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount))
225
#define stbi__zlib_add(code,codebits) \
226
      (bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush())
227
#define stbi__zlib_huffa(b,c)  stbi__zlib_add(stbi__zlib_bitrev(b,c),c)
228
// default huffman tables
229
#define stbi__zlib_huff1(n)  stbi__zlib_huffa(0x30 + (n), 8)
230
#define stbi__zlib_huff2(n)  stbi__zlib_huffa(0x190 + (n)-144, 9)
231
#define stbi__zlib_huff3(n)  stbi__zlib_huffa(0 + (n)-256,7)
232
#define stbi__zlib_huff4(n)  stbi__zlib_huffa(0xc0 + (n)-280,8)
233
#define stbi__zlib_huff(n)  ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n))
234
#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n))
235
 
236
#define stbi__ZHASH   16384
237
 
238
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
239
{
240
   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 };
241
   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 };
242
   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 };
243
   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 };
244
   unsigned int bitbuf=0;
245
   int i,j, bitcount=0;
246
   unsigned char *out = NULL;
247
   unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack!
248
   if (quality < 5) quality = 5;
249
 
250
   stbi__sbpush(out, 0x78);   // DEFLATE 32K window
251
   stbi__sbpush(out, 0x5e);   // FLEVEL = 1
252
   stbi__zlib_add(1,1);  // BFINAL = 1
253
   stbi__zlib_add(1,2);  // BTYPE = 1 -- fixed huffman
254
 
255
   for (i=0; i < stbi__ZHASH; ++i)
256
      hash_table[i] = NULL;
257
 
258
   i=0;
259
   while (i < data_len-3) {
260
      // hash next 3 bytes of data to be compressed 
261
      int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3;
262
      unsigned char *bestloc = 0;
263
      unsigned char **hlist = hash_table[h];
264
      int n = stbi__sbcount(hlist);
265
      for (j=0; j < n; ++j) {
266
         if (hlist[j]-data > i-32768) { // if entry lies within window
267
            int d = stbi__zlib_countm(hlist[j], data+i, data_len-i);
268
            if (d >= best) best=d,bestloc=hlist[j];
269
         }
270
      }
271
      // when hash table entry is too long, delete half the entries
272
      if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) {
273
         memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
274
         stbi__sbn(hash_table[h]) = quality;
275
      }
276
      stbi__sbpush(hash_table[h],data+i);
277
 
278
      if (bestloc) {
279
         // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
280
         h = stbi__zhash(data+i+1)&(stbi__ZHASH-1);
281
         hlist = hash_table[h];
282
         n = stbi__sbcount(hlist);
283
         for (j=0; j < n; ++j) {
284
            if (hlist[j]-data > i-32767) {
285
               int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1);
286
               if (e > best) { // if next match is better, bail on current match
287
                  bestloc = NULL;
288
                  break;
289
               }
290
            }
291
         }
292
      }
293
 
294
      if (bestloc) {
295
         int d = data+i - bestloc; // distance back
296
         assert(d <= 32767 && best <= 258);
297
         for (j=0; best > lengthc[j+1]-1; ++j);
298
         stbi__zlib_huff(j+257);
299
         if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]);
300
         for (j=0; d > distc[j+1]-1; ++j);
301
         stbi__zlib_add(stbi__zlib_bitrev(j,5),5);
302
         if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]);
303
         i += best;
304
      } else {
305
         stbi__zlib_huffb(data[i]);
306
         ++i;
307
      }
308
   }
309
   // write out final bytes
310
   for (;i < data_len; ++i)
311
      stbi__zlib_huffb(data[i]);
312
   stbi__zlib_huff(256); // end of block
313
   // pad with 0 bits to byte boundary
314
   while (bitcount)
315
      stbi__zlib_add(0,1);
316
 
317
   for (i=0; i < stbi__ZHASH; ++i)
318
      (void) stbi__sbfree(hash_table[i]);
319
 
320
   {
321
      // compute adler32 on input
322
      unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
323
      int j=0;
324
      while (j < data_len) {
325
         for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
326
         s1 %= 65521, s2 %= 65521;
327
         j += blocklen;
328
         blocklen = 5552;
329
      }
330
      stbi__sbpush(out, (unsigned char) (s2 >> 8));
331
      stbi__sbpush(out, (unsigned char) s2);
332
      stbi__sbpush(out, (unsigned char) (s1 >> 8));
333
      stbi__sbpush(out, (unsigned char) s1);
334
   }
335
   *out_len = stbi__sbn(out);
336
   // make returned pointer freeable
337
   memmove(stbi__sbraw(out), out, *out_len);
338
   return (unsigned char *) stbi__sbraw(out);
339
}
340
 
341
unsigned int stbi__crc32(unsigned char *buffer, int len)
342
{
343
   static unsigned int crc_table[256];
344
   unsigned int crc = ~0u;
345
   int i,j;
346
   if (crc_table[1] == 0)
347
      for(i=0; i < 256; i++)
348
         for (crc_table[i]=i, j=0; j < 8; ++j)
349
            crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
350
   for (i=0; i < len; ++i)
351
      crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
352
   return ~crc;
353
}
354
 
355
#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
356
#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
357
#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
358
 
359
static void stbi__wpcrc(unsigned char **data, int len)
360
{
361
   unsigned int crc = stbi__crc32(*data - len - 4, len+4);
362
   stbi__wp32(*data, crc);
363
}
364
 
365
static unsigned char stbi__paeth(int a, int b, int c)
366
{
367
   int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
368
   if (pa <= pb && pa <= pc) return (unsigned char) a;
369
   if (pb <= pc) return (unsigned char) b;
370
   return (unsigned char) c;
371
}
372
 
373
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
374
{
375
   int ctype[5] = { -1, 0, 4, 2, 6 };
376
   unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
377
   unsigned char *out,*o, *filt, *zlib;
378
   signed char *line_buffer;
379
   int i,j,k,p,zlen;
380
 
381
   if (stride_bytes == 0)
382
      stride_bytes = x * n;
383
 
384
   filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
385
   line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
386
   for (j=0; j < y; ++j) {
387
      static int mapping[] = { 0,1,2,3,4 };
388
      static int firstmap[] = { 0,1,0,5,6 };
389
      int *mymap = j ? mapping : firstmap;
390
      int best = 0, bestval = 0x7fffffff;
391
      for (p=0; p < 2; ++p) {
392
         for (k= p?best:0; k < 5; ++k) {
393
            int type = mymap[k],est=0;
394
            unsigned char *z = pixels + stride_bytes*j;
395
            for (i=0; i < n; ++i)
396
               switch (type) {
397
                  case 0: line_buffer[i] = z[i]; break;
398
                  case 1: line_buffer[i] = z[i]; break;
399
                  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
400
                  case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
401
                  case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
402
                  case 5: line_buffer[i] = z[i]; break;
403
                  case 6: line_buffer[i] = z[i]; break;
404
               }
405
            for (i=n; i < x*n; ++i) {
406
               switch (type) {
407
                  case 0: line_buffer[i] = z[i]; break;
408
                  case 1: line_buffer[i] = z[i] - z[i-n]; break;
409
                  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
410
                  case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
411
                  case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
412
                  case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
413
                  case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break;
414
               }
415
            }
416
            if (p) break;
417
            for (i=0; i < x*n; ++i)
418
               est += abs((signed char) line_buffer[i]);
419
            if (est < bestval) { bestval = est; best = k; }
420
         }
421
      }
422
      // when we get here, best contains the filter type, and line_buffer contains the data
423
      filt[j*(x*n+1)] = (unsigned char) best;
424
      memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
425
   }
426
   free(line_buffer);
427
   zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
428
   free(filt);
429
   if (!zlib) return 0;
430
 
431
   // each tag requires 12 bytes of overhead
432
   out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12); 
433
   if (!out) return 0;
434
   *out_len = 8 + 12+13 + 12+zlen + 12;
435
 
436
   o=out;
437
   memcpy(o,sig,8); o+= 8;
438
   stbi__wp32(o, 13); // header length
439
   stbi__wptag(o, "IHDR");
440
   stbi__wp32(o, x);
441
   stbi__wp32(o, y);
442
   *o++ = 8;
443
   *o++ = (unsigned char) ctype[n];
444
   *o++ = 0;
445
   *o++ = 0;
446
   *o++ = 0;
447
   stbi__wpcrc(&o,13);
448
 
449
   stbi__wp32(o, zlen);
450
   stbi__wptag(o, "IDAT");
451
   memcpy(o, zlib, zlen); o += zlen; free(zlib);
452
   stbi__wpcrc(&o, zlen);
453
 
454
   stbi__wp32(o,0);
455
   stbi__wptag(o, "IEND");
456
   stbi__wpcrc(&o,0);
457
 
458
   assert(o == out + *out_len);
459
 
460
   return out;
461
}
462
 
463
int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
464
{
465
   FILE *f;
466
   int len;
467
   unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
468
   if (!png) return 0;
469
   f = fopen(filename, "wb");
470
   if (!f) { free(png); return 0; }
471
   fwrite(png, 1, len, f);
472
   fclose(f);
473
   free(png);
474
   return 1;
475
}