screenshot.c
changeset 430 75820dedf4f1
parent 410 8de2aaf20800
child 507 8aa8100b0b22
--- a/screenshot.c	Mon Nov 15 12:15:03 2004 +0000
+++ b/screenshot.c	Mon Nov 15 19:25:59 2004 +0000
@@ -4,6 +4,7 @@
 #include "viewport.h"
 #include "player.h"
 #include "gui.h"
+#include "screenshot.h"
 
 // called by the ScreenShot proc to generate screenshot lines.
 typedef void ScreenshotCallback(void *userdata, byte *buf, uint y, uint pitch, uint n);
@@ -13,7 +14,6 @@
 	const char *name;
 	const char *extension;
 	ScreenshotHandlerProc *proc;
-	byte id;
 } ScreenshotFormat;
 
 //************************************************
@@ -89,7 +89,7 @@
 	bih.clrimp = 0;
 
 	// convert the palette to the windows format
-	for(i=0; i!=256; i++) {
+	for (i = 0; i != 256; i++) {
 		rq[i].red = *palette++;
 		rq[i].green = *palette++;
 		rq[i].blue = *palette++;
@@ -97,15 +97,19 @@
 	}
 
 	// write file header and info header and palette
-	fwrite(&bfh, 1, sizeof(bfh), f);
-	fwrite(&bih, 1, sizeof(bih), f);
-	fwrite(rq, 1, sizeof(rq), f);
+	if (fwrite(&bfh, sizeof(bfh), 1, f) != 1) return false;
+	if (fwrite(&bih, sizeof(bih), 1, f) != 1) return false;
+	if (fwrite(rq, sizeof(rq), 1, f) != 1) return false;
 
 	// use by default 64k temp memory
 	maxlines = clamp(65536 / padw, 16, 128);
 
 	// now generate the bitmap bits
-	buff = (byte*)alloca(padw * maxlines); // by default generate 128 lines at a time.
+	buff = malloc(padw * maxlines); // by default generate 128 lines at a time.
+	if (buff == NULL) {
+		fclose(f);
+		return false;
+	}
 	memset(buff, 0, padw * maxlines); // zero the buffer to have the padding bytes set to 0
 
 	// start at the bottom, since bitmaps are stored bottom up.
@@ -119,9 +123,14 @@
 
 		// write each line
 		while (n)
-			fwrite(buff + (--n) * padw, 1, padw, f);
-	} while (h);
+			if (fwrite(buff + (--n) * padw, padw, 1, f) != 1) {
+				free(buff);
+				fclose(f);
+				return false;
+			}
+	} while (h != 0);
 
+	free(buff);
 	fclose(f);
 
 	return true;
@@ -135,7 +144,7 @@
 
 static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
 {
-	DEBUG(misc, 0) ("ERROR(libpng): %s - %s\n", message,(char *)png_get_error_ptr(png_ptr));
+	DEBUG(misc, 0) ("ERROR(libpng): %s - %s\n", message, (char *)png_get_error_ptr(png_ptr));
 	longjmp(png_ptr->jmpbuf, 1);
 }
 
@@ -161,15 +170,15 @@
 	f = fopen(name, "wb");
 	if (f == NULL) return false;
 
-	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (char *) name, png_my_error, png_my_warning);
+	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (char *)name, png_my_error, png_my_warning);
 
-	if (!png_ptr) {
+	if (png_ptr == NULL) {
 		fclose(f);
 		return false;
 	}
 
 	info_ptr = png_create_info_struct(png_ptr);
-	if (!info_ptr) {
+	if (info_ptr == NULL) {
 		png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
 		fclose(f);
 		return false;
@@ -185,15 +194,15 @@
 
 	png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
 
-	png_set_IHDR(png_ptr, info_ptr, w, h, pixelformat, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
-		PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+	png_set_IHDR(png_ptr, info_ptr, w, h, pixelformat, PNG_COLOR_TYPE_PALETTE,
+		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 
 	// convert the palette to the .PNG format.
 	{
     // avoids "might be clobbered" warning of argument "palette"
 		const byte *pal = palette;
 
-		for(i=0; i!=256; i++) {
+		for (i = 0; i != 256; i++) {
 			rq[i].red = *pal++;
 			rq[i].green = *pal++;
 			rq[i].blue = *pal++;
@@ -208,7 +217,12 @@
 	maxlines = clamp(65536 / w, 16, 128);
 
 	// now generate the bitmap bits
-	buff = (byte*)alloca(w * maxlines); // by default generate 128 lines at a time.
+	buff = malloc(w * maxlines); // by default generate 128 lines at a time.
+	if (buff == NULL) {
+		png_destroy_write_struct(&png_ptr, &info_ptr);
+		fclose(f);
+		return false;
+	}
 	memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0
 
 	y = 0;
@@ -221,13 +235,14 @@
 		y += n;
 
 		// write them to png
-		for(i=0; i!=n; i++)
+		for (i = 0; i != n; i++)
 			png_write_row(png_ptr, buff + i * w);
 	} while (y != h);
 
 	png_write_end(png_ptr, info_ptr);
 	png_destroy_write_struct(&png_ptr, &info_ptr);
 
+	free(buff);
 	fclose(f);
 	return true;
 }
@@ -278,8 +293,8 @@
 	pcx.version = 5;
 	pcx.rle = 1;
 	pcx.bpp = 8;
-	pcx.xmax = TO_LE16(w-1);
-	pcx.ymax = TO_LE16(h-1);
+	pcx.xmax = TO_LE16(w - 1);
+	pcx.ymax = TO_LE16(h - 1);
 	pcx.hdpi = TO_LE16(320);
 	pcx.vdpi = TO_LE16(320);
 
@@ -289,53 +304,86 @@
 	pcx.height = TO_LE16(h);
 
 	// write pcx header
-	fwrite(&pcx, sizeof(pcx), 1, f);
+	if (fwrite(&pcx, sizeof(pcx), 1, f) != 1) {
+		fclose(f);
+		return false;
+	}
 
 	// use by default 64k temp memory
 	maxlines = clamp(65536 / w, 16, 128);
 
 	// now generate the bitmap bits
-	buff = (byte*)alloca(w * maxlines);				// by default generate 128 lines at a time.
-	memset(buff, 0, w * maxlines);			// zero the buffer to have the padding bytes set to 0
+	buff = malloc(w * maxlines); // by default generate 128 lines at a time.
+	if (buff == NULL) {
+		fclose(f);
+		return false;
+	}
+	memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0
 
 	y = 0;
 	do {
 		// determine # lines to write
-		uint n = min(h - y, maxlines), i;
+		uint n = min(h - y, maxlines);
+		uint i;
 
 		// render the pixels into the buffer
 		callb(userdata, buff, y, w, n);
 		y += n;
 
 		// write them to pcx
-		for(i=0; i!=n; i++) {
+		for (i = 0; i != n; i++) {
 			int runcount = 1;
 			byte *bufp = buff + i * w;
 			byte runchar = buff[0];
-			uint left = w - 1;
+			uint left;
 
 			// for each pixel...
-			while (left) {
+			for (left = w - 1; left > 0; --left) {
 				byte ch = *bufp++;
 				if (ch != runchar || runcount >= 0x3f) {
-					if (runcount > 1 || (runchar & 0xC0) == 0xC0) fputc(0xC0 | runcount, f);
-					fputc(runchar,f);
+					if (runcount > 1 || (runchar & 0xC0) == 0xC0)
+						if (fputc(0xC0 | runcount, f) == EOF) {
+							free(buff);
+							fclose(f);
+							return false;
+						}
+					if (fputc(runchar, f) == EOF) {
+						free(buff);
+						fclose(f);
+						return false;
+					}
 					runcount = 0;
 					runchar = ch;
 				}
 				runcount++;
-				left--;
 			}
 
 			// write remaining bytes..
-			if (runcount > 1 || (runchar & 0xC0) == 0xC0) fputc(0xC0 | runcount, f);
-			fputc(runchar,f);
+			if (runcount > 1 || (runchar & 0xC0) == 0xC0)
+				if (fputc(0xC0 | runcount, f) == EOF) {
+					free(buff);
+					fclose(f);
+					return false;
+				}
+			if (fputc(runchar, f) == EOF) {
+				free(buff);
+				fclose(f);
+				return false;
+			}
 		}
 	} while (y != h);
 
+	free(buff);
+
 	// write 8-bit color palette
-	fputc(12, f);
-	fwrite(palette, 256*3, 1, f);
+	if (fputc(12, f) == EOF) {
+		fclose(f);
+		return false;
+	}
+	if (fwrite(palette, 256 * 3, 1, f) != 1) {
+		fclose(f);
+		return false;
+	}
 	fclose(f);
 
 	return true;
@@ -353,11 +401,14 @@
 	{"PCX", "pcx", &MakePCXImage},
 };
 
-void InitializeScreenshotFormats()
+void InitializeScreenshotFormats(void)
 {
-	int i,j;
-	for (i=0,j=0; i!=lengthof(_screenshot_formats); i++)
-		if (!strcmp(_screenshot_format_name, _screenshot_formats[i].extension)) { j=i; break; }
+	int i, j;
+	for (i = 0, j = 0; i != lengthof(_screenshot_formats); i++)
+		if (!strcmp(_screenshot_format_name, _screenshot_formats[i].extension)) {
+			j = i;
+			break;
+		}
 	_cur_screenshot_format = j;
 	_num_screenshot_formats = lengthof(_screenshot_formats);
 }
@@ -376,16 +427,13 @@
 // screenshot generator that dumps the current video buffer
 static void CurrentScreenCallback(void *userdata, byte *buf, uint y, uint pitch, uint n)
 {
-	for (; n > 0; --n)
-	{
+	for (; n > 0; --n) {
 		memcpy(buf, _screen.dst_ptr + y * _screen.pitch, _screen.width);
 		++y;
 		buf += pitch;
 	}
 }
 
-extern void ViewportDoDraw(ViewPort *vp, int left, int top, int right, int bottom);
-
 // generate a large piece of the world
 static void LargeWorldCallback(void *userdata, byte *buf, uint y, uint pitch, uint n)
 {
@@ -413,7 +461,7 @@
 			((left - wx - vp->left) << vp->zoom) + vp->virtual_left,
 			((y - vp->top) << vp->zoom) + vp->virtual_top,
 			((left - vp->left) << vp->zoom) + vp->virtual_left,
-			(((y+n) - vp->top) << vp->zoom) + vp->virtual_top
+			(((y + n) - vp->top) << vp->zoom) + vp->virtual_top
 		);
 	}
 
@@ -440,7 +488,7 @@
 	base[0] = '.'; strcpy(base + 1, ext);
 
 	serial = 0;
-	for(;;) {
+	for (;;) {
 		snprintf(filename, sizeof(filename), "%s%s", _path.personal_dir, _screenshot_name);
 		if (!FileExists(filename))
 			break;
@@ -450,9 +498,7 @@
 	return filename;
 }
 
-extern byte _cur_palette[768];
-
-bool MakeScreenshot()
+bool MakeScreenshot(void)
 {
 	const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format;
 	return sf->proc(MakeScreenshotName(sf->extension), CurrentScreenCallback, NULL, _screen.width, _screen.height, 8, _cur_palette);