MCPcopy Create free account
hub / github.com/assaultcube/AC / save_png

Function save_png

source/src/main.cpp:255–344  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

253}
254
255int save_png(const char *filename, SDL_Surface *image)
256{
257 uchar *data = (uchar *)image->pixels;
258 int iw = image->w, ih = image->h, pitch = image->pitch;
259
260 stream *f = openfile(filename, "wb");
261 if(!f) { conoutf("could not write to %s", filename); return -1; }
262 const char *scores = asciiscores(true);
263
264 uchar signature[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
265 f->write(signature, sizeof(signature));
266
267 struct pngihdr
268 {
269 uint width, height;
270 uchar bitdepth, colortype, compress, filter, interlace;
271 } ihdr = { bigswap<uint>(iw), bigswap<uint>(ih), 8, 2, 0, 0, 0 };
272 writepngchunk(f, "IHDR", (uchar *)&ihdr, 13);
273
274 int idat = f->tell();
275 uint len = 0;
276 f->write("\0\0\0\0IDAT", 8);
277 uint crc = crc32(0, Z_NULL, 0);
278 crc = crc32(crc, (const Bytef *)"IDAT", 4);
279
280 z_stream z;
281 z.zalloc = NULL;
282 z.zfree = NULL;
283 z.opaque = NULL;
284
285 if(deflateInit(&z, pngcompress) != Z_OK)
286 goto error;
287
288 uchar buf[1<<12];
289 z.next_out = (Bytef *)buf;
290 z.avail_out = sizeof(buf);
291
292 loopi(ih)
293 {
294 uchar filter = 0;
295 loopj(2)
296 {
297 z.next_in = j ? (Bytef *)data + i*pitch : (Bytef *)&filter;
298 z.avail_in = j ? iw*3 : 1;
299 while(z.avail_in > 0)
300 {
301 if(deflate(&z, Z_NO_FLUSH) != Z_OK) goto cleanuperror;
302 #define FLUSHZ do { \
303 int flush = sizeof(buf) - z.avail_out; \
304 crc = crc32(crc, buf, flush); \
305 len += flush; \
306 f->write(buf, flush); \
307 z.next_out = (Bytef *)buf; \
308 z.avail_out = sizeof(buf); \
309 } while(0)
310 FLUSHZ;
311 }
312 }

Callers 1

mapscreenshotFunction · 0.85

Calls 7

openfileFunction · 0.85
asciiscoresFunction · 0.85
writepngchunkFunction · 0.85
conoutfFunction · 0.70
writeMethod · 0.45
tellMethod · 0.45
seekMethod · 0.45

Tested by

no test coverage detected