mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-02 14:01:26 +00:00
SCR_ScreenShot_f: change default format to png, using stb_image_write
Add optional format and quality args to "screenshot" command, can specify tga, png, jpg git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1465 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
10ed2c85dc
commit
4a02827fe6
4 changed files with 1604 additions and 7 deletions
|
@ -757,6 +757,14 @@ SCREEN SHOTS
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
static void SCR_ScreenShot_Usage (void)
|
||||
{
|
||||
Con_Printf ("usage: screenshot <format> <quality>\n");
|
||||
Con_Printf (" format must be \"png\" or \"tga\" or \"jpg\"\n");
|
||||
Con_Printf (" quality must be 1-100\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_ScreenShot_f -- johnfitz -- rewritten to use Image_WriteTGA
|
||||
|
@ -765,15 +773,44 @@ SCR_ScreenShot_f -- johnfitz -- rewritten to use Image_WriteTGA
|
|||
void SCR_ScreenShot_f (void)
|
||||
{
|
||||
byte *buffer;
|
||||
char tganame[16]; //johnfitz -- was [80]
|
||||
char ext[4];
|
||||
char imagename[16]; //johnfitz -- was [80]
|
||||
char checkname[MAX_OSPATH];
|
||||
int i;
|
||||
int i, quality;
|
||||
qboolean ok;
|
||||
|
||||
Q_strncpy (ext, "png", sizeof(ext));
|
||||
|
||||
if (Cmd_Argc () >= 2)
|
||||
{
|
||||
const char *requested_ext = Cmd_Argv (1);
|
||||
|
||||
if (!q_strcasecmp ("png", requested_ext)
|
||||
|| !q_strcasecmp ("tga", requested_ext)
|
||||
|| !q_strcasecmp ("jpg", requested_ext))
|
||||
Q_strncpy (ext, requested_ext, sizeof(ext));
|
||||
else
|
||||
{
|
||||
SCR_ScreenShot_Usage ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// read quality as the 3rd param (only used for JPG)
|
||||
quality = 90;
|
||||
if (Cmd_Argc () >= 3)
|
||||
quality = Q_atoi (Cmd_Argv(2));
|
||||
if (quality < 1 || quality > 100)
|
||||
{
|
||||
SCR_ScreenShot_Usage ();
|
||||
return;
|
||||
}
|
||||
|
||||
// find a file name to save it to
|
||||
for (i=0; i<10000; i++)
|
||||
{
|
||||
q_snprintf (tganame, sizeof(tganame), "spasm%04i.tga", i); // "fitz%04i.tga"
|
||||
q_snprintf (checkname, sizeof(checkname), "%s/%s", com_gamedir, tganame);
|
||||
q_snprintf (imagename, sizeof(imagename), "spasm%04i.%s", i, ext); // "fitz%04i.tga"
|
||||
q_snprintf (checkname, sizeof(checkname), "%s/%s", com_gamedir, imagename);
|
||||
if (Sys_FileTime(checkname) == -1)
|
||||
break; // file doesn't exist
|
||||
}
|
||||
|
@ -794,10 +831,19 @@ void SCR_ScreenShot_f (void)
|
|||
glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
// now write the file
|
||||
if (Image_WriteTGA (tganame, buffer, glwidth, glheight, 24, false))
|
||||
Con_Printf ("Wrote %s\n", tganame);
|
||||
if (!q_strncasecmp (ext, "png", sizeof(ext)))
|
||||
ok = Image_WritePNG (imagename, buffer, glwidth, glheight, 24, false);
|
||||
else if (!q_strncasecmp (ext, "tga", sizeof(ext)))
|
||||
ok = Image_WriteTGA (imagename, buffer, glwidth, glheight, 24, false);
|
||||
else if (!q_strncasecmp (ext, "jpg", sizeof(ext)))
|
||||
ok = Image_WriteJPG (imagename, buffer, glwidth, glheight, 24, quality, false);
|
||||
else
|
||||
Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
|
||||
ok = false;
|
||||
|
||||
if (ok)
|
||||
Con_Printf ("Wrote %s\n", imagename);
|
||||
else
|
||||
Con_Printf ("SCR_ScreenShot_f: Couldn't create %s\n", imagename);
|
||||
|
||||
free (buffer);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
|
||||
static char loadfilename[MAX_OSPATH]; //file scope so that error messages can use it
|
||||
|
||||
typedef struct stdio_buffer_s {
|
||||
|
@ -467,3 +470,91 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height)
|
|||
*height = h;
|
||||
return data;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//
|
||||
// STB_IMAGE_WRITE
|
||||
//
|
||||
//==============================================================================
|
||||
|
||||
static byte *CopyFlipped(byte *data, int width, int height, int bpp)
|
||||
{
|
||||
int y, rowsize;
|
||||
byte *flipped;
|
||||
|
||||
rowsize = width * (bpp / 8);
|
||||
flipped = (byte *) malloc(height * rowsize);
|
||||
if (!flipped)
|
||||
return NULL;
|
||||
|
||||
for (y=0; y<height; y++)
|
||||
{
|
||||
memcpy(&flipped[y * rowsize], &data[(height - 1 - y) * rowsize], rowsize);
|
||||
}
|
||||
return flipped;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
format_png,
|
||||
format_jpg
|
||||
} imageformat_t;
|
||||
|
||||
/*
|
||||
============
|
||||
Image_WriteSTB -- writes using stb_image_write
|
||||
|
||||
returns true if successful
|
||||
============
|
||||
*/
|
||||
static qboolean
|
||||
Image_WriteSTB (const char *name, byte *data, int width, int height, int bpp, imageformat_t format, int quality, qboolean upsidedown)
|
||||
{
|
||||
unsigned error;
|
||||
char pathname[MAX_OSPATH];
|
||||
byte *flipped;
|
||||
int bytes_per_pixel;
|
||||
|
||||
if (!(bpp == 32 || bpp == 24))
|
||||
Sys_Error ("bpp not 24 or 32");
|
||||
|
||||
bytes_per_pixel = bpp / 8;
|
||||
|
||||
Sys_mkdir (com_gamedir); //if we've switched to a nonexistant gamedir, create it now so we don't crash
|
||||
q_snprintf (pathname, sizeof(pathname), "%s/%s", com_gamedir, name);
|
||||
|
||||
if (!upsidedown)
|
||||
{
|
||||
flipped = CopyFlipped (data, width, height, bpp);
|
||||
if (!flipped)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
flipped = data;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case format_png:
|
||||
error = stbi_write_png (pathname, width, height, bytes_per_pixel, flipped, width * bytes_per_pixel);
|
||||
break;
|
||||
case format_jpg:
|
||||
error = stbi_write_jpg (pathname, width, height, bytes_per_pixel, flipped, quality);
|
||||
break;
|
||||
default:
|
||||
Sys_Error ("invalid format");
|
||||
}
|
||||
|
||||
if (!upsidedown)
|
||||
free (flipped);
|
||||
|
||||
return (error != 0);
|
||||
}
|
||||
|
||||
qboolean Image_WritePNG (const char *name, byte *data, int width, int height, int bpp, qboolean upsidedown)
|
||||
{
|
||||
return Image_WriteSTB (name, data, width, height, bpp, format_png, 0, upsidedown);
|
||||
}
|
||||
|
||||
qboolean Image_WriteJPG (const char *name, byte *data, int width, int height, int bpp, int quality, qboolean upsidedown)
|
||||
{
|
||||
return Image_WriteSTB (name, data, width, height, bpp, format_jpg, quality, upsidedown);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height);
|
|||
byte *Image_LoadImage (const char *name, int *width, int *height);
|
||||
|
||||
qboolean Image_WriteTGA (const char *name, byte *data, int width, int height, int bpp, qboolean upsidedown);
|
||||
qboolean Image_WritePNG (const char *name, byte *data, int width, int height, int bpp, qboolean upsidedown);
|
||||
qboolean Image_WriteJPG (const char *name, byte *data, int width, int height, int bpp, int quality, qboolean upsidedown);
|
||||
|
||||
#endif /* __GL_IMAGE_H */
|
||||
|
||||
|
|
1458
Quake/stb_image_write.h
Normal file
1458
Quake/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue