]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
initial WebP support by graphitemaster divVerent/webp
authorRudolf Polzer <divverent@xonotic.org>
Wed, 29 May 2013 17:02:33 +0000 (19:02 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Wed, 29 May 2013 17:02:33 +0000 (19:02 +0200)
cl_screen.c
cl_screen.h
gl_textures.c
image.c
image_webp.c [new file with mode: 0644]
image_webp.h [new file with mode: 0644]
makefile.inc

index 2a7af7dd5e0b15ed2eed4d40a818631e9fce1e80..5f99d57d27df57e3b0ec34702b0b633c8b0ef0dd 100644 (file)
@@ -51,6 +51,8 @@ cvar_t vid_pixelheight = {CVAR_SAVE, "vid_pixelheight", "1", "adjusts vertical f
 cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","1", "save jpeg instead of targa"};
 cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","0.9", "image quality of saved jpeg"};
 cvar_t scr_screenshot_png = {CVAR_SAVE, "scr_screenshot_png","0", "save png instead of targa"};
+cvar_t scr_screenshot_webp = {CVAR_SAVE, "scr_screenshot_webp", "0", "save webp instead of targa"};
+cvar_t scr_screenshot_webp_quality = {CVAR_SAVE, "scr_screenshot_webp_quality", "0.9", "image quality of saved webp"};
 cvar_t scr_screenshot_gammaboost = {CVAR_SAVE, "scr_screenshot_gammaboost","1", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"};
 cvar_t scr_screenshot_hwgamma = {CVAR_SAVE, "scr_screenshot_hwgamma","1", "apply the video gamma ramp to saved screenshots and videos"};
 cvar_t scr_screenshot_alpha = {CVAR_SAVE, "scr_screenshot_alpha","0", "try to write an alpha channel to screenshots (debugging feature)"};
@@ -1332,6 +1334,8 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable (&scr_screenshot_jpeg);
        Cvar_RegisterVariable (&scr_screenshot_jpeg_quality);
        Cvar_RegisterVariable (&scr_screenshot_png);
+       Cvar_RegisterVariable (&scr_screenshot_webp);
+       Cvar_RegisterVariable (&scr_screenshot_webp_quality);
        Cvar_RegisterVariable (&scr_screenshot_gammaboost);
        Cvar_RegisterVariable (&scr_screenshot_hwgamma);
        Cvar_RegisterVariable (&scr_screenshot_name_in_mapdir);
@@ -1404,6 +1408,7 @@ void SCR_ScreenShot_f (void)
        unsigned char *buffer2;
        qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
        qboolean png = (scr_screenshot_png.integer != 0) && !jpeg;
+       qboolean webp = (scr_screenshot_webp.integer != 0) && !png;
        char vabuf[1024];
 
        if (Cmd_Argc() == 2)
@@ -1415,16 +1420,25 @@ void SCR_ScreenShot_f (void)
                {
                        jpeg = true;
                        png = false;
+                       webp = false;
                }
                else if (!strcasecmp(ext, "tga"))
                {
                        jpeg = false;
                        png = false;
+                       webp = false;
                }
                else if (!strcasecmp(ext, "png"))
                {
                        jpeg = false;
                        png = true;
+                       webp = false;
+               }
+               else if (!strcasecmp(ext, "webp"))
+               {
+                       jpeg = false;
+                       png = false;
+                       webp = true;
                }
                else
                {
@@ -1454,7 +1468,7 @@ void SCR_ScreenShot_f (void)
                        return;
                }
 
-               dpsnprintf(filename, sizeof(filename), "screenshots/%s-%02d.%s", prefix_name, shotnumber100, jpeg ? "jpg" : png ? "png" : "tga");
+               dpsnprintf(filename, sizeof(filename), "screenshots/%s-%02d.%s", prefix_name, shotnumber100, jpeg ? "jpg" : png ? "png" : webp ? "webp" : "tga");
        }
        else
        {
@@ -1485,7 +1499,7 @@ void SCR_ScreenShot_f (void)
                        return;
                }
 
-               dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : png ? "png" : "tga");
+               dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : png ? "png" : webp ? "webp" : "tga");
 
                shotnumber++;
        }
index faf906b2fb1af62855eb3ece8a78afde992bba39..8d7a165cf4801e664521888cf4be5bb57c4277c2 100644 (file)
@@ -12,6 +12,8 @@ extern cvar_t vid_pixelheight;
 extern cvar_t scr_screenshot_jpeg;
 extern cvar_t scr_screenshot_jpeg_quality;
 extern cvar_t scr_screenshot_png;
+extern cvar_t scr_screenshot_webp;
+extern cvar_t scr_screenshot_webp_quality;
 extern cvar_t scr_screenshot_gammaboost;
 extern cvar_t scr_screenshot_name;
 
index 2dd11ebf52f6d9ade26f4491a018dd0c8ba9dac5..18ee3720898c1f0e2b02391cf8d6f5909f2931a5 100644 (file)
@@ -7,6 +7,7 @@ extern LPDIRECT3DDEVICE9 vid_d3d9dev;
 #include "image.h"
 #include "jpeg.h"
 #include "image_png.h"
+#include "image_webp.h"
 #include "intoverflow.h"
 #include "dpsoftrast.h"
 
@@ -795,6 +796,8 @@ static void r_textures_start(void)
                Cvar_SetValueQuick (&scr_screenshot_jpeg, 0);
        if (! PNG_OpenLibrary ())
                Cvar_SetValueQuick (&scr_screenshot_png, 0);
+       if (! WEBP_OpenLibrary ())
+               Cvar_SetValueQuick (&scr_screenshot_webp, 0);
 }
 
 static void r_textures_shutdown(void)
@@ -802,6 +805,8 @@ static void r_textures_shutdown(void)
        rtexturepool_t *temp;
 
        JPEG_CloseLibrary ();
+       PNG_CloseLibrary ();
+       WEBP_CloseLibrary ();
 
        while(gltexturepoolchain)
        {
diff --git a/image.c b/image.c
index 366e80dd8380c16211b0e2f617f074846127b0c8..1470462067535b98aae51b87cfad376815678e53 100644 (file)
--- a/image.c
+++ b/image.c
@@ -3,6 +3,7 @@
 #include "image.h"
 #include "jpeg.h"
 #include "image_png.h"
+#include "image_webp.h"
 #include "r_shadow.h"
 
 int            image_width;
@@ -881,29 +882,32 @@ imageformat_t imageformats_dq[] =
 
 imageformat_t imageformats_textures[] =
 {
-       {"%s.tga", LoadTGA_BGRA},
-       {"%s.png", PNG_LoadImage_BGRA},
-       {"%s.jpg", JPEG_LoadImage_BGRA},
-       {"%s.pcx", LoadPCX_BGRA},
-       {"%s.wal", LoadWAL_BGRA},
+       {"%s.tga",  LoadTGA_BGRA},
+       {"%s.png",  PNG_LoadImage_BGRA},
+       {"%s.jpg",  JPEG_LoadImage_BGRA},
+       {"%s.pcx",  LoadPCX_BGRA},
+       {"%s.wal",  LoadWAL_BGRA},
+       {"%s.webp", WEBP_LoadImage_BGRA},
        {NULL, NULL}
 };
 
 imageformat_t imageformats_gfx[] =
 {
-       {"%s.tga", LoadTGA_BGRA},
-       {"%s.png", PNG_LoadImage_BGRA},
-       {"%s.jpg", JPEG_LoadImage_BGRA},
-       {"%s.pcx", LoadPCX_BGRA},
+       {"%s.tga",  LoadTGA_BGRA},
+       {"%s.png",  PNG_LoadImage_BGRA},
+       {"%s.jpg",  JPEG_LoadImage_BGRA},
+       {"%s.pcx",  LoadPCX_BGRA},
+       {"%s.webp", WEBP_LoadImage_BGRA},
        {NULL, NULL}
 };
 
 imageformat_t imageformats_other[] =
 {
-       {"%s.tga", LoadTGA_BGRA},
-       {"%s.png", PNG_LoadImage_BGRA},
-       {"%s.jpg", JPEG_LoadImage_BGRA},
-       {"%s.pcx", LoadPCX_BGRA},
+       {"%s.tga",  LoadTGA_BGRA},
+       {"%s.png",  PNG_LoadImage_BGRA},
+       {"%s.jpg",  JPEG_LoadImage_BGRA},
+       {"%s.pcx",  LoadPCX_BGRA},
+       {"%s.webp", WEBP_LoadImage_BGRA},
        {NULL, NULL}
 };
 
diff --git a/image_webp.c b/image_webp.c
new file mode 100644 (file)
index 0000000..bd86ceb
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+       Copyright (C) 2013 Dale "graphitemaster" Weiler
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       of the License, or (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+       See the GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to:
+
+               Free Software Foundation, Inc.
+               59 Temple Place - Suite 330
+               Boston, MA  02111-1307, USA
+
+       (comment)
+       * I Dale Weiler allow this code to be relicensed if required.
+       * The GPL is just for compatability with darkplaces. If in the
+       * distant future this code needs to be relicensed for what ever
+       * reason, I herby allow it, no questions asked. Consider this
+       * public domain.
+       (endcomment)
+*/
+
+#include "quakedef.h"
+#include "image.h"
+#include "image_webp.h"
+
+static int            (*qwebp_get_info)          (const unsigned char *, size_t, int *, int *);
+static unsigned char *(*qwebp_decode_bgra_into)  (const unsigned char *, size_t, unsigned char *, size_t, int);
+static size_t         (*qwebp_encode_rgb)        (const unsigned char *, int, int, int, float, unsigned char **);
+static size_t         (*qwebp_encode_rgba)       (const unsigned char *, int, int, int, float, unsigned char **);
+
+static dllfunction_t webpfuncs[] =
+{
+       {"WebPGetInfo",         (void **) &qwebp_get_info},
+       {"WebPDecodeBGRAInto",  (void **) &qwebp_decode_bgra_into},
+       {"WebPEncodeRGB",       (void **) &qwebp_encode_rgb},
+       {"WebPEncodeRGBA",      (void **) &qwebp_encode_rgba},
+       {NULL, NULL}
+};
+
+dllhandle_t webp_dll = NULL;
+
+qboolean WEBP_OpenLibrary (void)
+{
+
+       // anything older than 2 doesn't have WebPGetInfo
+       const char* dllnames [] =
+       {
+#if WIN32
+               "libwebp-4.dll", // always search newest version
+               "libwebp-3.dll",
+               "libwebp-2.dll", // this one ships with SDL2
+               "libwebp_a.dll", // this one only ships with old SDL releases
+#elif defined(MACOSX)
+               "libwebp.dylib", // no versions for OSX
+#else
+               "libwebp.so.4",
+               "libwebp.so.3",
+               "libwebp.so.2",
+               "libwebp.so.0",
+               "libwebp.so",
+#endif
+               NULL
+       };
+
+       if (webp_dll)
+               return true;
+
+       if(!Sys_LoadLibrary (dllnames, &webp_dll, webpfuncs))
+               return false;
+
+       return true;
+}
+
+void WEBP_CloseLibrary (void)
+{
+       Sys_UnloadLibrary (&webp_dll);
+}
+
+unsigned char *WEBP_LoadImage_BGRA (const unsigned char *raw, int filesize, int *miplevel)
+{
+       unsigned char *data = NULL;
+
+       if (!webp_dll)
+               return NULL;
+
+       if (!qwebp_get_info(raw, filesize, &image_width, &image_height))
+               return NULL;
+
+       if ((data = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4)))
+       {
+               if (!qwebp_decode_bgra_into(raw, filesize, data, 4 * image_height, 4))
+               {
+                       Con_Printf("WEBP_LoadImage : failed decode\n");
+                       Mem_Free(data);
+                       return NULL;
+               }
+               return data;
+       }
+       
+       Con_Printf("WEBP_LoadImage : not enough memory\n");
+       return NULL;
+}
+
+
+qboolean WEBP_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data)
+{
+       qfile_t       *file   = NULL;
+       unsigned char *memory = NULL;
+       unsigned int   wrote  = 0;
+       
+       size_t (*encode)(const unsigned char *, int, int, int, float, unsigned char **) = (has_alpha)
+               ? qwebp_encode_rgba
+               : qwebp_encode_rgb;
+               
+
+       if (!(wrote = encode(data, width, height, 4, scr_screenshot_webp_quality.value * 100, &memory)))
+               return false;
+
+
+       if (!(file = FS_OpenRealFile(filename, "wb", true)))
+       {
+               free(memory);
+               return false;
+       }
+
+       FS_Write(file, memory, wrote);
+       FS_Close(file);
+
+       free(memory);
+       return true;
+}
diff --git a/image_webp.h b/image_webp.h
new file mode 100644 (file)
index 0000000..7b17d52
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+       Copyright (C) 2013  Dale "graphitemaster" Weiler
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       of the License, or (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+       See the GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to:
+
+               Free Software Foundation, Inc.
+               59 Temple Place - Suite 330
+               Boston, MA  02111-1307, USA
+
+       (comment)
+       * I Dale Weiler allow this code to be relicensed if required.
+       * The GPL is just for compatability with darkplaces. If in the
+       * distant future this code needs to be relicensed for what ever
+       * reason, I herby allow it, no questions asked. Consider this
+       * public domain.
+       (endcomment)
+*/
+
+#ifndef WEBP_H
+#define WEBP_H
+
+qboolean WEBP_OpenLibrary (void);
+void WEBP_CloseLibrary (void);
+unsigned char* WEBP_LoadImage_BGRA (const unsigned char *f, int filesize, int *miplevel);
+qboolean WEBP_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data);
+
+#endif
+
index fe1eabe12a8421255e80ce5bd51dc6ba2bd0bf9c..7ad855e26daab68f35e0dcb8f9779e2d5e508713 100644 (file)
@@ -133,6 +133,7 @@ OBJ_COMMON= \
        host_cmd.o \
        image.o \
        image_png.o \
+       image_webp.o \
        jpeg.o \
        keys.o \
        lhnet.o \