Add BC7 support. It's incredibly slow - ~60 seconds to compress a 512x512 image, on a Core i7 - but it works.

- Added AVPCL compressor to projects and got it building with VC9 and VC10.
- Removed unused command line interface & file read/write code from AVPCL.
- Convert AVPCL to use NV vector math lib, asserts, etc.
- Convert AVPCL to use double instead of float.
- Added 4x4 symmetric eigensolver, for AVPCL; it's based on the existing 3x3 one, but I had to rewrite the Householder reduction stage.  As with ZOH, using the eigensolver (instead of SVD) gives a ~25% speedup without significantly affecting RMSE.
- Encapsulate ZOH and AVPCL stuff into their own namespaces to keep everything separate.
- Added some missing vector operators to the nvmath lib.
This commit is contained in:
nathaniel.reed@gmail.com
2013-12-07 02:17:08 +00:00
parent f2fa0517b5
commit ab316deeaa
86 changed files with 2944 additions and 11081 deletions

View File

@ -13,95 +13,87 @@ See the License for the specific language governing permissions and limitations
#ifndef _AVPCL_H
#define _AVPCL_H
#include <string>
#include <assert.h>
#include "tile.h"
#include "bits.h"
using namespace std;
#define EXTERNAL_RELEASE 1 // define this if we're releasing this code externally
#define DISABLE_EXHAUSTIVE 1 // define this if you don't want to spend a lot of time on exhaustive compression
#define USE_ZOH_INTERP 1 // use zoh interpolator, otherwise use exact avpcl interpolators
#define USE_ZOH_INTERP_ROUNDED 1 // use the rounded versions!
#define NREGIONS_TWO 2
#define NREGIONS_THREE 3
#define DBL_MAX (1.0e37) // doesn't have to be really dblmax, just bigger than any possible squared error
namespace AVPCL {
class AVPCL
static const int NREGIONS_TWO = 2;
static const int NREGIONS_THREE = 3;
static const int BLOCKSIZE=16;
static const int BITSIZE=128;
// global flags
extern bool flag_premult;
extern bool flag_nonuniform;
extern bool flag_nonuniform_ati;
// global mode
extern bool mode_rgb; // true if image had constant alpha = 255
void compress(const Tile &t, char *block);
void decompress(const char *block, Tile &t);
float compress_mode0(const Tile &t, char *block);
void decompress_mode0(const char *block, Tile &t);
float compress_mode1(const Tile &t, char *block);
void decompress_mode1(const char *block, Tile &t);
float compress_mode2(const Tile &t, char *block);
void decompress_mode2(const char *block, Tile &t);
float compress_mode3(const Tile &t, char *block);
void decompress_mode3(const char *block, Tile &t);
float compress_mode4(const Tile &t, char *block);
void decompress_mode4(const char *block, Tile &t);
float compress_mode5(const Tile &t, char *block);
void decompress_mode5(const char *block, Tile &t);
float compress_mode6(const Tile &t, char *block);
void decompress_mode6(const char *block, Tile &t);
float compress_mode7(const Tile &t, char *block);
void decompress_mode7(const char *block, Tile &t);
inline int getmode(Bits &in)
{
public:
static const int BLOCKSIZE=16;
static const int BITSIZE=128;
int mode = 0;
// global flags
static bool flag_premult;
static bool flag_nonuniform;
static bool flag_nonuniform_ati;
if (in.read(1)) mode = 0;
else if (in.read(1)) mode = 1;
else if (in.read(1)) mode = 2;
else if (in.read(1)) mode = 3;
else if (in.read(1)) mode = 4;
else if (in.read(1)) mode = 5;
else if (in.read(1)) mode = 6;
else if (in.read(1)) mode = 7;
else mode = 8; // reserved
return mode;
}
inline int getmode(const char *block)
{
int bits = block[0], mode = 0;
// global mode
static bool mode_rgb; // true if image had constant alpha = 255
if (bits & 1) mode = 0;
else if ((bits&3) == 2) mode = 1;
else if ((bits&7) == 4) mode = 2;
else if ((bits & 0xF) == 8) mode = 3;
else if ((bits & 0x1F) == 16) mode = 4;
else if ((bits & 0x3F) == 32) mode = 5;
else if ((bits & 0x7F) == 64) mode = 6;
else if ((bits & 0xFF) == 128) mode = 7;
else mode = 8; // reserved
return mode;
}
static void compress(string inf, string zohf, string errf);
static void decompress(string zohf, string outf);
static void compress(const Tile &t, char *block, FILE *errfile);
static void decompress(const char *block, Tile &t);
}
static double compress_mode0(const Tile &t, char *block);
static void decompress_mode0(const char *block, Tile &t);
static double compress_mode1(const Tile &t, char *block);
static void decompress_mode1(const char *block, Tile &t);
static double compress_mode2(const Tile &t, char *block);
static void decompress_mode2(const char *block, Tile &t);
static double compress_mode3(const Tile &t, char *block);
static void decompress_mode3(const char *block, Tile &t);
static double compress_mode4(const Tile &t, char *block);
static void decompress_mode4(const char *block, Tile &t);
static double compress_mode5(const Tile &t, char *block);
static void decompress_mode5(const char *block, Tile &t);
static double compress_mode6(const Tile &t, char *block);
static void decompress_mode6(const char *block, Tile &t);
static double compress_mode7(const Tile &t, char *block);
static void decompress_mode7(const char *block, Tile &t);
static int getmode(Bits &in)
{
int mode = 0;
if (in.read(1)) mode = 0;
else if (in.read(1)) mode = 1;
else if (in.read(1)) mode = 2;
else if (in.read(1)) mode = 3;
else if (in.read(1)) mode = 4;
else if (in.read(1)) mode = 5;
else if (in.read(1)) mode = 6;
else if (in.read(1)) mode = 7;
else mode = 8; // reserved
return mode;
}
static int getmode(const char *block)
{
int bits = block[0], mode = 0;
if (bits & 1) mode = 0;
else if ((bits&3) == 2) mode = 1;
else if ((bits&7) == 4) mode = 2;
else if ((bits & 0xF) == 8) mode = 3;
else if ((bits & 0x1F) == 16) mode = 4;
else if ((bits & 0x3F) == 32) mode = 5;
else if ((bits & 0x7F) == 64) mode = 6;
else if ((bits & 0xFF) == 128) mode = 7;
else mode = 8; // reserved
return mode;
}
};
#endif
#endif