common/videolink: cleanup/minor tweaks
use ptrdiff prevline offset in hqx filters to facilitate use of lea. use endptr rathern than loop ctr in rgb2yuv to avoid gcc/x86 rmw spill. avoid reloading rhs input pixel after storing lhs output in rgb2yuv (no restrict keyword in c++98). fix hypothetical component overflow in hq2x blend9.
This commit is contained in:
parent
7a0cf00a3c
commit
d44f804f03
160
common/videolink/rgb32conv.cpp
Executable file → Normal file
160
common/videolink/rgb32conv.cpp
Executable file → Normal file
@ -17,9 +17,9 @@
|
|||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "rgb32conv.h"
|
#include "rgb32conv.h"
|
||||||
#include "videolink.h"
|
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "gbint.h"
|
#include "gbint.h"
|
||||||
|
#include "videolink.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -34,6 +34,13 @@ static bool isBigEndian() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Rgb32ToUyvy {
|
class Rgb32ToUyvy {
|
||||||
|
public:
|
||||||
|
Rgb32ToUyvy();
|
||||||
|
void operator()(gambatte::uint_least32_t *d, std::ptrdiff_t dstPitch,
|
||||||
|
gambatte::uint_least32_t const *s, std::ptrdiff_t srcPitch,
|
||||||
|
unsigned w, unsigned h);
|
||||||
|
|
||||||
|
private:
|
||||||
struct CacheUnit {
|
struct CacheUnit {
|
||||||
gambatte::uint_least32_t rgb32;
|
gambatte::uint_least32_t rgb32;
|
||||||
gambatte::uint_least32_t uyvy;
|
gambatte::uint_least32_t uyvy;
|
||||||
@ -41,78 +48,80 @@ class Rgb32ToUyvy {
|
|||||||
|
|
||||||
enum { cache_size = 0x100 };
|
enum { cache_size = 0x100 };
|
||||||
enum { cache_mask = cache_size - 1 };
|
enum { cache_mask = cache_size - 1 };
|
||||||
|
CacheUnit cache_[cache_size];
|
||||||
CacheUnit cache[cache_size];
|
|
||||||
|
|
||||||
public:
|
|
||||||
Rgb32ToUyvy();
|
|
||||||
void operator()(const gambatte::uint_least32_t *s, gambatte::uint_least32_t *d,
|
|
||||||
unsigned w, unsigned h, std::ptrdiff_t srcPitch, std::ptrdiff_t dstPitch);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Rgb32ToUyvy::Rgb32ToUyvy() {
|
Rgb32ToUyvy::Rgb32ToUyvy() {
|
||||||
if (isBigEndian()) {
|
if (isBigEndian()) {
|
||||||
CacheUnit c = { 0, 128ul << 24 | 16ul << 16 | 128 << 8 | 16 };
|
CacheUnit c = { 0, 128ul << 24 | 16ul << 16 | 128u << 8 | 16 };
|
||||||
std::fill(cache, cache + cache_size, c);
|
std::fill(cache_, cache_ + cache_size, c);
|
||||||
} else {
|
} else {
|
||||||
CacheUnit c = { 0, 16ul << 24 | 128ul << 16 | 16 << 8 | 128 };
|
CacheUnit c = { 0, 16ul << 24 | 128ul << 16 | 16 << 8 | 128 };
|
||||||
std::fill(cache, cache + cache_size, c);
|
std::fill(cache_, cache_ + cache_size, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rgb32ToUyvy::operator()(const gambatte::uint_least32_t *s, gambatte::uint_least32_t *d,
|
void Rgb32ToUyvy::operator()(gambatte::uint_least32_t *dst,
|
||||||
const unsigned w, unsigned h, const std::ptrdiff_t s_pitch, const std::ptrdiff_t d_pitch)
|
std::ptrdiff_t const dstPitch,
|
||||||
|
gambatte::uint_least32_t const *src,
|
||||||
|
std::ptrdiff_t const srcPitch,
|
||||||
|
unsigned const w,
|
||||||
|
unsigned h)
|
||||||
{
|
{
|
||||||
while (h--) {
|
while (h--) {
|
||||||
unsigned n = w >> 1;
|
gambatte::uint_least32_t *d = dst;
|
||||||
|
gambatte::uint_least32_t const *s = src;
|
||||||
do {
|
gambatte::uint_least32_t const *const sEnd = s + w - 1;
|
||||||
if ((cache[s[0] & cache_mask].rgb32 - s[0]) | (cache[s[1] & cache_mask].rgb32 - s[1])) {
|
while (s < sEnd) {
|
||||||
cache[s[0] & cache_mask].rgb32 = s[0];
|
if ((cache_[s[0] & cache_mask].rgb32 - s[0]) | (cache_[s[1] & cache_mask].rgb32 - s[1])) {
|
||||||
cache[s[1] & cache_mask].rgb32 = s[1];
|
cache_[s[0] & cache_mask].rgb32 = s[0];
|
||||||
|
cache_[s[1] & cache_mask].rgb32 = s[1];
|
||||||
const unsigned long r = (s[0] >> 16 & 0x000000FF) | (s[1] & 0x00FF0000);
|
|
||||||
const unsigned long g = (s[0] >> 8 & 0x000000FF) | (s[1] << 8 & 0x00FF0000);
|
|
||||||
const unsigned long b = (s[0] & 0x000000FF) | (s[1] << 16 & 0x00FF0000);
|
|
||||||
|
|
||||||
const unsigned long y = r * 66 + g * 129 + b * 25 + ( 16 * 256 + 128) * 0x00010001ul;
|
|
||||||
const unsigned long u = b * 112 - r * 38 - g * 74 + (128 * 256 + 128) * 0x00010001ul;
|
|
||||||
const unsigned long v = r * 112 - g * 94 - b * 18 + (128 * 256 + 128) * 0x00010001ul;
|
|
||||||
|
|
||||||
|
unsigned long const r = (s[0] >> 16 & 0x000000FF) | (s[1] & 0x00FF0000);
|
||||||
|
unsigned long const g = (s[0] >> 8 & 0x000000FF) | (s[1] << 8 & 0x00FF0000);
|
||||||
|
unsigned long const b = (s[0] & 0x000000FF) | (s[1] << 16 & 0x00FF0000);
|
||||||
|
unsigned long const y = r * 66 + g * 129 + b * 25 + ( 16 * 256 + 128) * 0x00010001ul;
|
||||||
|
unsigned long const u = b * 112 - r * 38 - g * 74 + (128 * 256 + 128) * 0x00010001ul;
|
||||||
|
unsigned long const v = r * 112 - g * 94 - b * 18 + (128 * 256 + 128) * 0x00010001ul;
|
||||||
if (isBigEndian()) {
|
if (isBigEndian()) {
|
||||||
cache[s[0] & cache_mask].uyvy = (u << 16 & 0xFF000000)
|
cache_[s[0] & cache_mask].uyvy = (u << 16 & 0xFF000000)
|
||||||
| (y << 8 & 0x00FF0000)
|
| (y << 8 & 0x00FF0000)
|
||||||
| (v & 0x0000FF00)
|
| (v & 0x0000FF00)
|
||||||
| (y >> 8 & 0x000000FF);
|
| (y >> 8 & 0x000000FF);
|
||||||
cache[s[1] & cache_mask].uyvy = (u & 0xFF000000)
|
cache_[s[1] & cache_mask].uyvy = (u & 0xFF000000)
|
||||||
| (y >> 8 & 0x00FF0000)
|
| (y >> 8 & 0x00FF0000)
|
||||||
| (v >> 16 & 0x0000FF00)
|
| (v >> 16 & 0x0000FF00)
|
||||||
| y >> 24 ;
|
| y >> 24 ;
|
||||||
} else {
|
} else {
|
||||||
cache[s[0] & cache_mask].uyvy = (y << 16 & 0xFF000000)
|
cache_[s[0] & cache_mask].uyvy = (y << 16 & 0xFF000000)
|
||||||
| (v << 8 & 0x00FF0000)
|
| (v << 8 & 0x00FF0000)
|
||||||
| (y & 0x0000FF00)
|
| (y & 0x0000FF00)
|
||||||
| (u >> 8 & 0x000000FF);
|
| (u >> 8 & 0x000000FF);
|
||||||
cache[s[1] & cache_mask].uyvy = (y & 0xFF000000)
|
cache_[s[1] & cache_mask].uyvy = (y & 0xFF000000)
|
||||||
| (v >> 8 & 0x00FF0000)
|
| (v >> 8 & 0x00FF0000)
|
||||||
| (y >> 16 & 0x0000FF00)
|
| (y >> 16 & 0x0000FF00)
|
||||||
| u >> 24 ;
|
| u >> 24 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d[0] = cache[s[0] & cache_mask].uyvy;
|
gambatte::uint_least32_t const s0 = s[0], s1 = s[1];
|
||||||
d[1] = cache[s[1] & cache_mask].uyvy;
|
d[0] = cache_[s0 & cache_mask].uyvy;
|
||||||
|
d[1] = cache_[s1 & cache_mask].uyvy;
|
||||||
s += 2;
|
s += 2;
|
||||||
d += 2;
|
d += 2;
|
||||||
} while (--n);
|
}
|
||||||
|
|
||||||
s += s_pitch - static_cast<std::ptrdiff_t>(w);
|
src += srcPitch;
|
||||||
d += d_pitch - static_cast<std::ptrdiff_t>(w);
|
dst += dstPitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rgb32ToRgb16(const gambatte::uint_least32_t *s, gambatte::uint_least16_t *d,
|
static void rgb32ToRgb16(gambatte::uint_least16_t *d,
|
||||||
const unsigned w, unsigned h, const std::ptrdiff_t srcPitch, const std::ptrdiff_t dstPitch)
|
std::ptrdiff_t const dstPitch,
|
||||||
|
gambatte::uint_least32_t const *s,
|
||||||
|
std::ptrdiff_t const srcPitch,
|
||||||
|
unsigned const w,
|
||||||
|
unsigned h)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
std::ptrdiff_t i = -static_cast<std::ptrdiff_t>(w);
|
std::ptrdiff_t i = -static_cast<std::ptrdiff_t>(w);
|
||||||
@ -129,51 +138,58 @@ static void rgb32ToRgb16(const gambatte::uint_least32_t *s, gambatte::uint_least
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Rgb32ToUyvyLink : public VideoLink {
|
class Rgb32ToUyvyLink : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> inbuf_;
|
|
||||||
Rgb32ToUyvy rgb32ToUyvy;
|
|
||||||
const unsigned width_;
|
|
||||||
const unsigned height_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Rgb32ToUyvyLink(unsigned width, unsigned height)
|
Rgb32ToUyvyLink(unsigned width, unsigned height)
|
||||||
: inbuf_(static_cast<std::size_t>(width) * height),
|
: inbuf_(static_cast<std::size_t>(width) * height)
|
||||||
width_(width),
|
, width_(width)
|
||||||
height_(height)
|
, height_(height)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* inBuf() const { return inbuf_; }
|
virtual void * inBuf() const { return inbuf_; }
|
||||||
virtual std::ptrdiff_t inPitch() const { return width_; }
|
virtual std::ptrdiff_t inPitch() const { return width_; }
|
||||||
|
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch) {
|
virtual void draw(void *dst, std::ptrdiff_t dstPitch) {
|
||||||
rgb32ToUyvy(inbuf_, static_cast<gambatte::uint_least32_t*>(dst), width_, height_, inPitch(), dstpitch);
|
rgb32ToUyvy_(static_cast<gambatte::uint_least32_t *>(dst), dstPitch,
|
||||||
|
inbuf_, width_, width_, height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SimpleArray<gambatte::uint_least32_t> const inbuf_;
|
||||||
|
Rgb32ToUyvy rgb32ToUyvy_;
|
||||||
|
unsigned const width_;
|
||||||
|
unsigned const height_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Rgb32ToRgb16Link : public VideoLink {
|
class Rgb32ToRgb16Link : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> inbuf_;
|
|
||||||
const unsigned width_;
|
|
||||||
const unsigned height_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Rgb32ToRgb16Link(unsigned width, unsigned height)
|
Rgb32ToRgb16Link(unsigned width, unsigned height)
|
||||||
: inbuf_(static_cast<std::size_t>(width) * height),
|
: inbuf_(static_cast<std::size_t>(width) * height)
|
||||||
width_(width),
|
, width_(width)
|
||||||
height_(height)
|
, height_(height)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* inBuf() const { return inbuf_; }
|
virtual void * inBuf() const { return inbuf_; }
|
||||||
virtual std::ptrdiff_t inPitch() const { return width_; }
|
virtual std::ptrdiff_t inPitch() const { return width_; }
|
||||||
|
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch) {
|
virtual void draw(void *dst, std::ptrdiff_t dstPitch) {
|
||||||
rgb32ToRgb16(inbuf_, static_cast<gambatte::uint_least16_t*>(dst), width_, height_, inPitch(), dstpitch);
|
if (!inbuf_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rgb32ToRgb16(static_cast<gambatte::uint_least16_t *>(dst), dstPitch,
|
||||||
|
inbuf_, width_, width_, height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SimpleArray<gambatte::uint_least32_t> const inbuf_;
|
||||||
|
unsigned const width_;
|
||||||
|
unsigned const height_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
VideoLink* Rgb32Conv::create(PixelFormat pf, unsigned width, unsigned height) {
|
VideoLink * Rgb32Conv::create(PixelFormat pf, unsigned width, unsigned height) {
|
||||||
switch (pf) {
|
switch (pf) {
|
||||||
case RGB16: return new Rgb32ToRgb16Link(width, height);
|
case RGB16: return new Rgb32ToRgb16Link(width, height);
|
||||||
case UYVY: return new Rgb32ToUyvyLink(width, height);
|
case UYVY: return new Rgb32ToUyvyLink(width, height);
|
||||||
|
2
common/videolink/rgb32conv.h
Executable file → Normal file
2
common/videolink/rgb32conv.h
Executable file → Normal file
@ -24,7 +24,7 @@ class VideoLink;
|
|||||||
class Rgb32Conv {
|
class Rgb32Conv {
|
||||||
public:
|
public:
|
||||||
enum PixelFormat { RGB32, RGB16, UYVY };
|
enum PixelFormat { RGB32, RGB16, UYVY };
|
||||||
static VideoLink* create(PixelFormat pf, unsigned width, unsigned height);
|
static VideoLink * create(PixelFormat pf, unsigned width, unsigned height);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
14
common/videolink/vfilterinfo.cpp
Executable file → Normal file
14
common/videolink/vfilterinfo.cpp
Executable file → Normal file
@ -23,26 +23,26 @@
|
|||||||
#include "vfilters/maxsthq2x.h"
|
#include "vfilters/maxsthq2x.h"
|
||||||
#include "vfilters/maxsthq3x.h"
|
#include "vfilters/maxsthq3x.h"
|
||||||
|
|
||||||
static VideoLink* createNone() { return 0; }
|
static VideoLink * createNone() { return 0; }
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static VideoLink* createT() { return new T; }
|
static VideoLink * createT() { return new T; }
|
||||||
|
|
||||||
#define VFINFO(handle, Type) { handle, Type::OUT_WIDTH, Type::OUT_HEIGHT, createT<Type> }
|
#define VFINFO(handle, Type) { handle, Type::out_width, Type::out_height, createT<Type> }
|
||||||
|
|
||||||
static const VfilterInfo vfinfos[] = {
|
static VfilterInfo const vfinfos[] = {
|
||||||
{ "None", VfilterInfo::IN_WIDTH, VfilterInfo::IN_HEIGHT, createNone },
|
{ "None", VfilterInfo::in_width, VfilterInfo::in_height, createNone },
|
||||||
VFINFO("Bicubic Catmull-Rom spline 2x", Catrom2x),
|
VFINFO("Bicubic Catmull-Rom spline 2x", Catrom2x),
|
||||||
VFINFO("Bicubic Catmull-Rom spline 3x", Catrom3x),
|
VFINFO("Bicubic Catmull-Rom spline 3x", Catrom3x),
|
||||||
VFINFO("Kreed's 2xSaI", Kreed2xSaI),
|
VFINFO("Kreed's 2xSaI", Kreed2xSaI),
|
||||||
VFINFO("MaxSt's hq2x", MaxStHq2x),
|
VFINFO("MaxSt's hq2x", MaxStHq2x),
|
||||||
VFINFO("MaxSt's hq3x", MaxStHq3x)
|
VFINFO("MaxSt's hq3x", MaxStHq3x),
|
||||||
};
|
};
|
||||||
|
|
||||||
std::size_t VfilterInfo::numVfilters() {
|
std::size_t VfilterInfo::numVfilters() {
|
||||||
return sizeof vfinfos / sizeof vfinfos[0];
|
return sizeof vfinfos / sizeof vfinfos[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const VfilterInfo& VfilterInfo::get(std::size_t n) {
|
VfilterInfo const & VfilterInfo::get(std::size_t n) {
|
||||||
return vfinfos[n];
|
return vfinfos[n];
|
||||||
}
|
}
|
||||||
|
10
common/videolink/vfilterinfo.h
Executable file → Normal file
10
common/videolink/vfilterinfo.h
Executable file → Normal file
@ -24,15 +24,15 @@
|
|||||||
class VideoLink;
|
class VideoLink;
|
||||||
|
|
||||||
struct VfilterInfo {
|
struct VfilterInfo {
|
||||||
enum { IN_WIDTH = 160 };
|
enum { in_width = 160 };
|
||||||
enum { IN_HEIGHT = 144 };
|
enum { in_height = 144 };
|
||||||
|
|
||||||
const char *handle;
|
char const *handle;
|
||||||
unsigned outWidth;
|
unsigned outWidth;
|
||||||
unsigned outHeight;
|
unsigned outHeight;
|
||||||
VideoLink* (*create)();
|
VideoLink * (*create)();
|
||||||
|
|
||||||
static const VfilterInfo& get(std::size_t n);
|
static VfilterInfo const & get(std::size_t n);
|
||||||
static std::size_t numVfilters();
|
static std::size_t numVfilters();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
68
common/videolink/vfilters/catrom2x.cpp
Executable file → Normal file
68
common/videolink/vfilters/catrom2x.cpp
Executable file → Normal file
@ -21,26 +21,24 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum { WIDTH = VfilterInfo::IN_WIDTH };
|
enum { in_width = VfilterInfo::in_width };
|
||||||
enum { HEIGHT = VfilterInfo::IN_HEIGHT };
|
enum { in_height = VfilterInfo::in_height };
|
||||||
enum { PITCH = WIDTH + 3 };
|
enum { in_pitch = in_width + 3 };
|
||||||
|
|
||||||
struct Colorsum {
|
struct Colorsum {
|
||||||
gambatte::uint_least32_t r, g, b;
|
gambatte::uint_least32_t r, g, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums) {
|
static void mergeColumns(gambatte::uint_least32_t *dest, Colorsum const *sums) {
|
||||||
unsigned w = WIDTH;
|
for (unsigned w = in_width; w--;) {
|
||||||
|
|
||||||
while (w--) {
|
|
||||||
{
|
{
|
||||||
gambatte::uint_least32_t rsum = sums[1].r;
|
gambatte::uint_least32_t rsum = sums[1].r;
|
||||||
gambatte::uint_least32_t gsum = sums[1].g;
|
gambatte::uint_least32_t gsum = sums[1].g;
|
||||||
gambatte::uint_least32_t bsum = sums[1].b;
|
gambatte::uint_least32_t bsum = sums[1].b;
|
||||||
|
|
||||||
if (rsum & 0x80000000) rsum = 0;
|
if (rsum >= 0x80000000) rsum = 0;
|
||||||
if (gsum & 0x80000000) gsum = 0;
|
if (gsum >= 0x80000000) gsum = 0;
|
||||||
if (bsum & 0x80000000) bsum = 0;
|
if (bsum >= 0x80000000) bsum = 0;
|
||||||
|
|
||||||
rsum <<= 12;
|
rsum <<= 12;
|
||||||
rsum += 0x008000;
|
rsum += 0x008000;
|
||||||
@ -73,9 +71,9 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
gsum -= sums[3].g;
|
gsum -= sums[3].g;
|
||||||
bsum -= sums[3].b;
|
bsum -= sums[3].b;
|
||||||
|
|
||||||
if (rsum & 0x80000000) rsum = 0;
|
if (rsum >= 0x80000000) rsum = 0;
|
||||||
if (gsum & 0x80000000) gsum = 0;
|
if (gsum >= 0x80000000) gsum = 0;
|
||||||
if (bsum & 0x80000000) bsum = 0;
|
if (bsum >= 0x80000000) bsum = 0;
|
||||||
|
|
||||||
rsum <<= 8;
|
rsum <<= 8;
|
||||||
rsum += 0x008000;
|
rsum += 0x008000;
|
||||||
@ -95,15 +93,16 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch, const gambatte::uint_least32_t *sline) {
|
static void filter(gambatte::uint_least32_t *dline,
|
||||||
Colorsum sums[PITCH];
|
std::ptrdiff_t const pitch,
|
||||||
|
gambatte::uint_least32_t const *sline)
|
||||||
for (unsigned h = HEIGHT; h--;) {
|
{
|
||||||
|
Colorsum sums[in_pitch];
|
||||||
|
for (unsigned h = in_height; h--;) {
|
||||||
{
|
{
|
||||||
const gambatte::uint_least32_t *s = sline;
|
gambatte::uint_least32_t const *s = sline;
|
||||||
Colorsum *sum = sums;
|
Colorsum *sum = sums;
|
||||||
unsigned n = PITCH;
|
unsigned n = in_pitch;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
unsigned long pixel = *s;
|
unsigned long pixel = *s;
|
||||||
sum->r = pixel >> 12 & 0x000FF0 ;
|
sum->r = pixel >> 12 & 0x000FF0 ;
|
||||||
@ -116,31 +115,30 @@ static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_columns(dline, sums);
|
mergeColumns(dline, sums);
|
||||||
dline += pitch;
|
dline += pitch;
|
||||||
|
|
||||||
{
|
{
|
||||||
const gambatte::uint_least32_t *s = sline;
|
gambatte::uint_least32_t const *s = sline;
|
||||||
Colorsum *sum = sums;
|
Colorsum *sum = sums;
|
||||||
unsigned n = PITCH;
|
unsigned n = in_pitch;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
unsigned long pixel = *s;
|
unsigned long pixel = *s;
|
||||||
unsigned long rsum = (pixel >> 16) * 9;
|
unsigned long rsum = (pixel >> 16) * 9;
|
||||||
unsigned long gsum = (pixel & 0x00FF00) * 9;
|
unsigned long gsum = (pixel & 0x00FF00) * 9;
|
||||||
unsigned long bsum = (pixel & 0x0000FF) * 9;
|
unsigned long bsum = (pixel & 0x0000FF) * 9;
|
||||||
|
|
||||||
pixel = s[-1*PITCH];
|
pixel = s[-1 * in_pitch];
|
||||||
rsum -= pixel >> 16;
|
rsum -= pixel >> 16;
|
||||||
gsum -= pixel & 0x00FF00;
|
gsum -= pixel & 0x00FF00;
|
||||||
bsum -= pixel & 0x0000FF;
|
bsum -= pixel & 0x0000FF;
|
||||||
|
|
||||||
pixel = s[1*PITCH];
|
pixel = s[1 * in_pitch];
|
||||||
rsum += (pixel >> 16) * 9;
|
rsum += (pixel >> 16) * 9;
|
||||||
gsum += (pixel & 0x00FF00) * 9;
|
gsum += (pixel & 0x00FF00) * 9;
|
||||||
bsum += (pixel & 0x0000FF) * 9;
|
bsum += (pixel & 0x0000FF) * 9;
|
||||||
|
|
||||||
pixel = s[2*PITCH];
|
pixel = s[2 * in_pitch];
|
||||||
rsum -= pixel >> 16;
|
rsum -= pixel >> 16;
|
||||||
gsum -= pixel & 0x00FF00;
|
gsum -= pixel & 0x00FF00;
|
||||||
bsum -= pixel & 0x0000FF;
|
bsum -= pixel & 0x0000FF;
|
||||||
@ -154,28 +152,28 @@ static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_columns(dline, sums);
|
mergeColumns(dline, sums);
|
||||||
dline += pitch;
|
dline += pitch;
|
||||||
sline += PITCH;
|
sline += in_pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
Catrom2x::Catrom2x()
|
Catrom2x::Catrom2x()
|
||||||
: buffer_((HEIGHT + 3UL) * PITCH)
|
: buffer_((in_height + 3UL) * in_pitch)
|
||||||
{
|
{
|
||||||
std::fill_n(buffer_.get(), buffer_.size(), 0);
|
std::fill_n(buffer_.get(), buffer_.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Catrom2x::inBuf() const {
|
void * Catrom2x::inBuf() const {
|
||||||
return buffer_ + PITCH + 1;
|
return buffer_ + in_pitch + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ptrdiff_t Catrom2x::inPitch() const {
|
std::ptrdiff_t Catrom2x::inPitch() const {
|
||||||
return PITCH;
|
return in_pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Catrom2x::draw(void *const dbuffer, const std::ptrdiff_t pitch) {
|
void Catrom2x::draw(void *dbuffer, std::ptrdiff_t pitch) {
|
||||||
::filter(static_cast<gambatte::uint_least32_t*>(dbuffer), pitch, buffer_ + PITCH);
|
::filter(static_cast<gambatte::uint_least32_t *>(dbuffer), pitch, buffer_ + in_pitch);
|
||||||
}
|
}
|
||||||
|
10
common/videolink/vfilters/catrom2x.h
Executable file → Normal file
10
common/videolink/vfilters/catrom2x.h
Executable file → Normal file
@ -25,15 +25,17 @@
|
|||||||
#include "gbint.h"
|
#include "gbint.h"
|
||||||
|
|
||||||
class Catrom2x : public VideoLink {
|
class Catrom2x : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> buffer_;
|
|
||||||
public:
|
public:
|
||||||
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 2 };
|
enum { out_width = VfilterInfo::in_width * 2 };
|
||||||
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 2 };
|
enum { out_height = VfilterInfo::in_height * 2 };
|
||||||
|
|
||||||
Catrom2x();
|
Catrom2x();
|
||||||
virtual void* inBuf() const;
|
virtual void * inBuf() const;
|
||||||
virtual std::ptrdiff_t inPitch() const;
|
virtual std::ptrdiff_t inPitch() const;
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Array<gambatte::uint_least32_t> const buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
126
common/videolink/vfilters/catrom3x.cpp
Executable file → Normal file
126
common/videolink/vfilters/catrom3x.cpp
Executable file → Normal file
@ -21,50 +21,48 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum { WIDTH = VfilterInfo::IN_WIDTH };
|
enum { in_width = VfilterInfo::in_width };
|
||||||
enum { HEIGHT = VfilterInfo::IN_HEIGHT };
|
enum { in_height = VfilterInfo::in_height };
|
||||||
enum { PITCH = WIDTH + 3 };
|
enum { in_pitch = in_width + 3 };
|
||||||
|
|
||||||
struct Colorsum {
|
struct Colorsum {
|
||||||
gambatte::uint_least32_t r, g, b;
|
gambatte::uint_least32_t r, g, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums) {
|
static void mergeColumns(gambatte::uint_least32_t *dest, Colorsum const *sums) {
|
||||||
unsigned w = WIDTH;
|
for (unsigned w = in_width; w--;) {
|
||||||
|
|
||||||
while (w--) {
|
|
||||||
{
|
{
|
||||||
gambatte::uint_least32_t rsum = sums[1].r;
|
gambatte::uint_least32_t rsum = sums[1].r;
|
||||||
gambatte::uint_least32_t gsum = sums[1].g;
|
gambatte::uint_least32_t gsum = sums[1].g;
|
||||||
gambatte::uint_least32_t bsum = sums[1].b;
|
gambatte::uint_least32_t bsum = sums[1].b;
|
||||||
|
|
||||||
if (rsum & 0x80000000)
|
if (rsum >= 0x80000000) {
|
||||||
rsum = 0;
|
rsum = 0;
|
||||||
else if (rsum > 6869)
|
} else if (rsum > 6869) {
|
||||||
rsum = 0xFF0000;
|
rsum = 0xFF0000;
|
||||||
else {
|
} else {
|
||||||
rsum *= 607;
|
rsum *= 607;
|
||||||
rsum <<= 2;
|
rsum <<= 2;
|
||||||
rsum += 0x008000;
|
rsum += 0x008000;
|
||||||
rsum &= 0xFF0000;
|
rsum &= 0xFF0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gsum & 0x80000000)
|
if (gsum >= 0x80000000) {
|
||||||
gsum = 0;
|
gsum = 0;
|
||||||
else if (gsum > 1758567)
|
} else if (gsum > 1758567) {
|
||||||
gsum = 0xFF00;
|
gsum = 0xFF00;
|
||||||
else {
|
} else {
|
||||||
gsum *= 607;
|
gsum *= 607;
|
||||||
gsum >>= 14;
|
gsum >>= 14;
|
||||||
gsum += 0x000080;
|
gsum += 0x000080;
|
||||||
gsum &= 0x00FF00;
|
gsum &= 0x00FF00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bsum & 0x80000000)
|
if (bsum >= 0x80000000) {
|
||||||
bsum = 0;
|
bsum = 0;
|
||||||
else if (bsum > 6869)
|
} else if (bsum > 6869) {
|
||||||
bsum = 0xFF;
|
bsum = 0xFF;
|
||||||
else {
|
} else {
|
||||||
bsum *= 607;
|
bsum *= 607;
|
||||||
bsum += 8192;
|
bsum += 8192;
|
||||||
bsum >>= 14;
|
bsum >>= 14;
|
||||||
@ -103,22 +101,22 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
gsum -= sums[3].g;
|
gsum -= sums[3].g;
|
||||||
bsum -= sums[3].b;
|
bsum -= sums[3].b;
|
||||||
|
|
||||||
if (rsum & 0x80000000)
|
if (rsum >= 0x80000000) {
|
||||||
rsum = 0;
|
rsum = 0;
|
||||||
else if (rsum > 185578)
|
} else if (rsum > 185578) {
|
||||||
rsum = 0xFF0000;
|
rsum = 0xFF0000;
|
||||||
else {
|
} else {
|
||||||
rsum *= 719;
|
rsum *= 719;
|
||||||
rsum >>= 3;
|
rsum >>= 3;
|
||||||
rsum += 0x008000;
|
rsum += 0x008000;
|
||||||
rsum &= 0xFF0000;
|
rsum &= 0xFF0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gsum & 0x80000000)
|
if (gsum >= 0x80000000) {
|
||||||
gsum = 0;
|
gsum = 0;
|
||||||
else if (gsum > 47508223)
|
} else if (gsum > 47508223) {
|
||||||
gsum = 0x00FF00;
|
gsum = 0x00FF00;
|
||||||
else {
|
} else {
|
||||||
gsum >>= 8;
|
gsum >>= 8;
|
||||||
gsum *= 719;
|
gsum *= 719;
|
||||||
gsum >>= 11;
|
gsum >>= 11;
|
||||||
@ -126,11 +124,11 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
gsum &= 0x00FF00;
|
gsum &= 0x00FF00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bsum & 0x80000000)
|
if (bsum >= 0x80000000) {
|
||||||
bsum = 0;
|
bsum = 0;
|
||||||
else if (bsum > 185578)
|
} else if (bsum > 185578) {
|
||||||
bsum = 0x0000FF;
|
bsum = 0x0000FF;
|
||||||
else {
|
} else {
|
||||||
bsum *= 719;
|
bsum *= 719;
|
||||||
bsum += 0x040000;
|
bsum += 0x040000;
|
||||||
bsum >>= 19;
|
bsum >>= 19;
|
||||||
@ -169,22 +167,22 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
gsum -= sums[3].g << 1;
|
gsum -= sums[3].g << 1;
|
||||||
bsum -= sums[3].b << 1;
|
bsum -= sums[3].b << 1;
|
||||||
|
|
||||||
if (rsum & 0x80000000)
|
if (rsum >= 0x80000000) {
|
||||||
rsum = 0;
|
rsum = 0;
|
||||||
else if (rsum > 185578)
|
} else if (rsum > 185578) {
|
||||||
rsum = 0xFF0000;
|
rsum = 0xFF0000;
|
||||||
else {
|
} else {
|
||||||
rsum *= 719;
|
rsum *= 719;
|
||||||
rsum >>= 3;
|
rsum >>= 3;
|
||||||
rsum += 0x008000;
|
rsum += 0x008000;
|
||||||
rsum &= 0xFF0000;
|
rsum &= 0xFF0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gsum & 0x80000000)
|
if (gsum >= 0x80000000) {
|
||||||
gsum = 0;
|
gsum = 0;
|
||||||
else if (gsum > 47508223)
|
} else if (gsum > 47508223) {
|
||||||
gsum = 0xFF00;
|
gsum = 0xFF00;
|
||||||
else {
|
} else {
|
||||||
gsum >>= 8;
|
gsum >>= 8;
|
||||||
gsum *= 719;
|
gsum *= 719;
|
||||||
gsum >>= 11;
|
gsum >>= 11;
|
||||||
@ -192,11 +190,11 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
gsum &= 0x00FF00;
|
gsum &= 0x00FF00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bsum & 0x80000000)
|
if (bsum >= 0x80000000) {
|
||||||
bsum = 0;
|
bsum = 0;
|
||||||
else if (bsum > 185578)
|
} else if (bsum > 185578) {
|
||||||
bsum = 0x0000FF;
|
bsum = 0x0000FF;
|
||||||
else {
|
} else {
|
||||||
bsum *= 719;
|
bsum *= 719;
|
||||||
bsum += 0x040000;
|
bsum += 0x040000;
|
||||||
bsum >>= 19;
|
bsum >>= 19;
|
||||||
@ -218,21 +216,23 @@ static void merge_columns(gambatte::uint_least32_t *dest, const Colorsum *sums)
|
|||||||
|
|
||||||
*dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum;
|
*dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum;
|
||||||
}
|
}
|
||||||
|
|
||||||
++sums;
|
++sums;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch, const gambatte::uint_least32_t *sline) {
|
static void filter(gambatte::uint_least32_t *dline,
|
||||||
Colorsum sums[PITCH];
|
std::ptrdiff_t const pitch,
|
||||||
|
gambatte::uint_least32_t const *sline)
|
||||||
for (unsigned h = HEIGHT; h--;) {
|
{
|
||||||
|
Colorsum sums[in_pitch];
|
||||||
|
for (unsigned h = in_height; h--;) {
|
||||||
{
|
{
|
||||||
const gambatte::uint_least32_t *s = sline;
|
gambatte::uint_least32_t const *s = sline;
|
||||||
Colorsum *sum = sums;
|
Colorsum *sum = sums;
|
||||||
unsigned n = PITCH;
|
unsigned n = in_pitch;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
const unsigned long pixel = *s;
|
unsigned long const pixel = *s;
|
||||||
sum->r = (pixel >> 16) * 27;
|
sum->r = (pixel >> 16) * 27;
|
||||||
sum->g = (pixel & 0x00FF00) * 27;
|
sum->g = (pixel & 0x00FF00) * 27;
|
||||||
sum->b = (pixel & 0x0000FF) * 27;
|
sum->b = (pixel & 0x0000FF) * 27;
|
||||||
@ -242,32 +242,31 @@ static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_columns(dline, sums);
|
mergeColumns(dline, sums);
|
||||||
dline += pitch;
|
dline += pitch;
|
||||||
|
|
||||||
{
|
{
|
||||||
const gambatte::uint_least32_t *s = sline;
|
gambatte::uint_least32_t const *s = sline;
|
||||||
Colorsum *sum = sums;
|
Colorsum *sum = sums;
|
||||||
unsigned n = PITCH;
|
unsigned n = in_pitch;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
unsigned long pixel = *s;
|
unsigned long pixel = *s;
|
||||||
unsigned long rsum = (pixel >> 16) * 21;
|
unsigned long rsum = (pixel >> 16) * 21;
|
||||||
unsigned long gsum = (pixel & 0x00FF00) * 21;
|
unsigned long gsum = (pixel & 0x00FF00) * 21;
|
||||||
unsigned long bsum = (pixel & 0x0000FF) * 21;
|
unsigned long bsum = (pixel & 0x0000FF) * 21;
|
||||||
|
|
||||||
pixel = s[-1 * PITCH];
|
pixel = s[-1 * in_pitch];
|
||||||
rsum -= (pixel >> 16) << 1;
|
rsum -= (pixel >> 16) << 1;
|
||||||
pixel <<= 1;
|
pixel <<= 1;
|
||||||
gsum -= pixel & 0x01FE00;
|
gsum -= pixel & 0x01FE00;
|
||||||
bsum -= pixel & 0x0001FE;
|
bsum -= pixel & 0x0001FE;
|
||||||
|
|
||||||
pixel = s[1 * PITCH];
|
pixel = s[1 * in_pitch];
|
||||||
rsum += (pixel >> 16) * 9;
|
rsum += (pixel >> 16) * 9;
|
||||||
gsum += (pixel & 0x00FF00) * 9;
|
gsum += (pixel & 0x00FF00) * 9;
|
||||||
bsum += (pixel & 0x0000FF) * 9;
|
bsum += (pixel & 0x0000FF) * 9;
|
||||||
|
|
||||||
pixel = s[2 * PITCH];
|
pixel = s[2 * in_pitch];
|
||||||
rsum -= pixel >> 16;
|
rsum -= pixel >> 16;
|
||||||
gsum -= pixel & 0x00FF00;
|
gsum -= pixel & 0x00FF00;
|
||||||
bsum -= pixel & 0x0000FF;
|
bsum -= pixel & 0x0000FF;
|
||||||
@ -281,31 +280,30 @@ static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_columns(dline, sums);
|
mergeColumns(dline, sums);
|
||||||
dline += pitch;
|
dline += pitch;
|
||||||
|
|
||||||
{
|
{
|
||||||
const gambatte::uint_least32_t *s = sline;
|
gambatte::uint_least32_t const *s = sline;
|
||||||
Colorsum *sum = sums;
|
Colorsum *sum = sums;
|
||||||
unsigned n = PITCH;
|
unsigned n = in_pitch;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
unsigned long pixel = *s;
|
unsigned long pixel = *s;
|
||||||
unsigned long rsum = (pixel >> 16) * 9;
|
unsigned long rsum = (pixel >> 16) * 9;
|
||||||
unsigned long gsum = (pixel & 0x00FF00) * 9;
|
unsigned long gsum = (pixel & 0x00FF00) * 9;
|
||||||
unsigned long bsum = (pixel & 0x0000FF) * 9;
|
unsigned long bsum = (pixel & 0x0000FF) * 9;
|
||||||
|
|
||||||
pixel = s[-1 * PITCH];
|
pixel = s[-1 * in_pitch];
|
||||||
rsum -= pixel >> 16;
|
rsum -= pixel >> 16;
|
||||||
gsum -= pixel & 0x00FF00;
|
gsum -= pixel & 0x00FF00;
|
||||||
bsum -= pixel & 0x0000FF;
|
bsum -= pixel & 0x0000FF;
|
||||||
|
|
||||||
pixel = s[1 * PITCH];
|
pixel = s[1 * in_pitch];
|
||||||
rsum += (pixel >> 16) * 21;
|
rsum += (pixel >> 16) * 21;
|
||||||
gsum += (pixel & 0x00FF00) * 21;
|
gsum += (pixel & 0x00FF00) * 21;
|
||||||
bsum += (pixel & 0x0000FF) * 21;
|
bsum += (pixel & 0x0000FF) * 21;
|
||||||
|
|
||||||
pixel = s[2 * PITCH];
|
pixel = s[2 * in_pitch];
|
||||||
rsum -= (pixel >> 16) << 1;
|
rsum -= (pixel >> 16) << 1;
|
||||||
pixel <<= 1;
|
pixel <<= 1;
|
||||||
gsum -= pixel & 0x01FE00;
|
gsum -= pixel & 0x01FE00;
|
||||||
@ -320,28 +318,28 @@ static void filter(gambatte::uint_least32_t *dline, const std::ptrdiff_t pitch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_columns(dline, sums);
|
mergeColumns(dline, sums);
|
||||||
dline += pitch;
|
dline += pitch;
|
||||||
sline += PITCH;
|
sline += in_pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
Catrom3x::Catrom3x()
|
Catrom3x::Catrom3x()
|
||||||
: buffer_((HEIGHT + 3UL) * PITCH)
|
: buffer_((in_height + 3UL) * in_pitch)
|
||||||
{
|
{
|
||||||
std::fill_n(buffer_.get(), buffer_.size(), 0);
|
std::fill_n(buffer_.get(), buffer_.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Catrom3x::inBuf() const {
|
void * Catrom3x::inBuf() const {
|
||||||
return buffer_ + PITCH + 1;
|
return buffer_ + in_pitch + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ptrdiff_t Catrom3x::inPitch() const {
|
std::ptrdiff_t Catrom3x::inPitch() const {
|
||||||
return PITCH;
|
return in_pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Catrom3x::draw(void *const dbuffer, const std::ptrdiff_t pitch) {
|
void Catrom3x::draw(void *dbuffer, std::ptrdiff_t pitch) {
|
||||||
::filter(static_cast<gambatte::uint_least32_t*>(dbuffer), pitch, buffer_ + PITCH);
|
::filter(static_cast<gambatte::uint_least32_t *>(dbuffer), pitch, buffer_ + in_pitch);
|
||||||
}
|
}
|
||||||
|
10
common/videolink/vfilters/catrom3x.h
Executable file → Normal file
10
common/videolink/vfilters/catrom3x.h
Executable file → Normal file
@ -25,15 +25,17 @@
|
|||||||
#include "gbint.h"
|
#include "gbint.h"
|
||||||
|
|
||||||
class Catrom3x : public VideoLink {
|
class Catrom3x : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> buffer_;
|
|
||||||
public:
|
public:
|
||||||
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 3 };
|
enum { out_width = VfilterInfo::in_width * 3 };
|
||||||
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 3 };
|
enum { out_height = VfilterInfo::in_height * 3 };
|
||||||
|
|
||||||
Catrom3x();
|
Catrom3x();
|
||||||
virtual void* inBuf() const;
|
virtual void * inBuf() const;
|
||||||
virtual std::ptrdiff_t inPitch() const;
|
virtual std::ptrdiff_t inPitch() const;
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Array<gambatte::uint_least32_t> const buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
203
common/videolink/vfilters/kreed2xsai.cpp
Executable file → Normal file
203
common/videolink/vfilters/kreed2xsai.cpp
Executable file → Normal file
@ -23,7 +23,11 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static inline int getResult1(const unsigned long a, const unsigned long b, const unsigned long c, const unsigned long d) {
|
static int getResult1(unsigned long const a,
|
||||||
|
unsigned long const b,
|
||||||
|
unsigned long const c,
|
||||||
|
unsigned long const d)
|
||||||
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@ -35,13 +39,16 @@ static inline int getResult1(const unsigned long a, const unsigned long b, const
|
|||||||
else if (b == d) ++y;
|
else if (b == d) ++y;
|
||||||
|
|
||||||
if (x <= 1) ++r;
|
if (x <= 1) ++r;
|
||||||
|
|
||||||
if (y <= 1) --r;
|
if (y <= 1) --r;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int getResult2(const unsigned long a, const unsigned long b, const unsigned long c, const unsigned long d) {
|
static int getResult2(unsigned long const a,
|
||||||
|
unsigned long const b,
|
||||||
|
unsigned long const c,
|
||||||
|
unsigned long const d)
|
||||||
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@ -53,122 +60,111 @@ static inline int getResult2(const unsigned long a, const unsigned long b, const
|
|||||||
else if (b == d) ++y;
|
else if (b == d) ++y;
|
||||||
|
|
||||||
if (x <= 1) --r;
|
if (x <= 1) --r;
|
||||||
|
|
||||||
if (y <= 1) ++r;
|
if (y <= 1) ++r;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long interpolate(const unsigned long a, const unsigned long b) {
|
static unsigned long interpolate(unsigned long a, unsigned long b) {
|
||||||
return (a + b - ((a ^ b) & 0x010101)) >> 1;
|
return (a + b - ((a ^ b) & 0x010101)) >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long qInterpolate(const unsigned long a, const unsigned long b,
|
static unsigned long qInterpolate(unsigned long const a,
|
||||||
const unsigned long c, const unsigned long d) {
|
unsigned long const b,
|
||||||
const unsigned long lowBits = ((a & 0x030303) + (b & 0x030303) + (c & 0x030303) + (d & 0x030303)) & 0x030303;
|
unsigned long const c,
|
||||||
|
unsigned long const d)
|
||||||
|
{
|
||||||
|
unsigned long lowBits = ((a & 0x030303)
|
||||||
|
+ (b & 0x030303)
|
||||||
|
+ (c & 0x030303)
|
||||||
|
+ (d & 0x030303)) & 0x030303;
|
||||||
return (a + b + c + d - lowBits) >> 2;
|
return (a + b + c + d - lowBits) >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::ptrdiff_t srcPitch, unsigned width, unsigned height>
|
template<std::ptrdiff_t srcPitch, unsigned width, unsigned height>
|
||||||
static void filter(gambatte::uint_least32_t *dstPtr, const std::ptrdiff_t dstPitch,
|
static void filter(gambatte::uint_least32_t *dstPtr,
|
||||||
const gambatte::uint_least32_t *srcPtr)
|
std::ptrdiff_t const dstPitch,
|
||||||
|
gambatte::uint_least32_t const *srcPtr)
|
||||||
{
|
{
|
||||||
unsigned h = height;
|
for (unsigned h = height; h--;) {
|
||||||
|
gambatte::uint_least32_t const *bP = srcPtr;
|
||||||
while (h--) {
|
|
||||||
const gambatte::uint_least32_t *bP = srcPtr;
|
|
||||||
gambatte::uint_least32_t *dP = dstPtr;
|
gambatte::uint_least32_t *dP = dstPtr;
|
||||||
|
for (unsigned w = width; w--;) {
|
||||||
|
unsigned long colorA, colorB, colorC, colorD,
|
||||||
|
colorE, colorF, colorG, colorH,
|
||||||
|
colorI, colorJ, colorK, colorL,
|
||||||
|
colorM, colorN, colorO/*, colorP*/;
|
||||||
|
|
||||||
for (unsigned finish = width; finish--;) {
|
//---------------------------------------
|
||||||
register unsigned long colorA, colorB;
|
// Map of the pixels: I|E F|J
|
||||||
unsigned long colorC, colorD,
|
// G|A B|K
|
||||||
colorE, colorF, colorG, colorH,
|
// H|C D|L
|
||||||
colorI, colorJ, colorK, colorL,
|
// M|N O|P
|
||||||
|
|
||||||
colorM, colorN, colorO, colorP;
|
|
||||||
unsigned long product, product1, product2;
|
|
||||||
|
|
||||||
//---------------------------------------
|
|
||||||
// Map of the pixels: I|E F|J
|
|
||||||
// G|A B|K
|
|
||||||
// H|C D|L
|
|
||||||
// M|N O|P
|
|
||||||
colorI = *(bP - srcPitch - 1);
|
colorI = *(bP - srcPitch - 1);
|
||||||
colorE = *(bP - srcPitch);
|
colorE = *(bP - srcPitch );
|
||||||
colorF = *(bP - srcPitch + 1);
|
colorF = *(bP - srcPitch + 1);
|
||||||
colorJ = *(bP - srcPitch + 2);
|
colorJ = *(bP - srcPitch + 2);
|
||||||
|
|
||||||
colorG = *(bP - 1);
|
colorG = *(bP - 1);
|
||||||
colorA = *(bP);
|
colorA = *(bP );
|
||||||
colorB = *(bP + 1);
|
colorB = *(bP + 1);
|
||||||
colorK = *(bP + 2);
|
colorK = *(bP + 2);
|
||||||
|
|
||||||
colorH = *(bP + srcPitch - 1);
|
colorH = *(bP + srcPitch - 1);
|
||||||
colorC = *(bP + srcPitch);
|
colorC = *(bP + srcPitch );
|
||||||
colorD = *(bP + srcPitch + 1);
|
colorD = *(bP + srcPitch + 1);
|
||||||
colorL = *(bP + srcPitch + 2);
|
colorL = *(bP + srcPitch + 2);
|
||||||
|
|
||||||
colorM = *(bP + srcPitch * 2 - 1);
|
colorM = *(bP + srcPitch * 2 - 1);
|
||||||
colorN = *(bP + srcPitch * 2);
|
colorN = *(bP + srcPitch * 2 );
|
||||||
colorO = *(bP + srcPitch * 2 + 1);
|
colorO = *(bP + srcPitch * 2 + 1);
|
||||||
colorP = *(bP + srcPitch * 2 + 2);
|
// colorP = *(bP + srcPitch * 2 + 2);
|
||||||
|
|
||||||
|
unsigned long product0, product1, product2;
|
||||||
if (colorA == colorD && colorB != colorC) {
|
if (colorA == colorD && colorB != colorC) {
|
||||||
if ((colorA == colorE && colorB == colorL) ||
|
product0 = (colorA == colorE && colorB == colorL)
|
||||||
(colorA == colorC && colorA == colorF
|
|| (colorA == colorC && colorA == colorF
|
||||||
&& colorB != colorE && colorB == colorJ)) {
|
&& colorB != colorE && colorB == colorJ)
|
||||||
product = colorA;
|
? colorA
|
||||||
} else {
|
: interpolate(colorA, colorB);
|
||||||
product = interpolate(colorA, colorB);
|
product1 = (colorA == colorG && colorC == colorO)
|
||||||
}
|
|| (colorA == colorB && colorA == colorH
|
||||||
|
&& colorG != colorC && colorC == colorM)
|
||||||
if ((colorA == colorG && colorC == colorO) ||
|
? colorA
|
||||||
(colorA == colorB && colorA == colorH
|
: interpolate(colorA, colorC);
|
||||||
&& colorG != colorC && colorC == colorM)) {
|
|
||||||
product1 = colorA;
|
|
||||||
} else {
|
|
||||||
product1 = interpolate(colorA, colorC);
|
|
||||||
}
|
|
||||||
product2 = colorA;
|
product2 = colorA;
|
||||||
} else if (colorB == colorC && colorA != colorD) {
|
} else if (colorB == colorC && colorA != colorD) {
|
||||||
if ((colorB == colorF && colorA == colorH) ||
|
product0 = (colorB == colorF && colorA == colorH)
|
||||||
(colorB == colorE && colorB == colorD
|
|| (colorB == colorE && colorB == colorD
|
||||||
&& colorA != colorF && colorA == colorI)) {
|
&& colorA != colorF && colorA == colorI)
|
||||||
product = colorB;
|
? colorB
|
||||||
} else {
|
: interpolate(colorA, colorB);
|
||||||
product = interpolate(colorA, colorB);
|
product1 = (colorC == colorH && colorA == colorF)
|
||||||
}
|
|| (colorC == colorG && colorC == colorD
|
||||||
|
&& colorA != colorH && colorA == colorI)
|
||||||
if ((colorC == colorH && colorA == colorF) ||
|
? colorC
|
||||||
(colorC == colorG && colorC == colorD
|
: interpolate(colorA, colorC);
|
||||||
&& colorA != colorH && colorA == colorI)) {
|
|
||||||
product1 = colorC;
|
|
||||||
} else {
|
|
||||||
product1 = interpolate(colorA, colorC);
|
|
||||||
}
|
|
||||||
product2 = colorB;
|
product2 = colorB;
|
||||||
} else if (colorA == colorD && colorB == colorC) {
|
} else if (colorA == colorD && colorB == colorC) {
|
||||||
if (colorA == colorB) {
|
if (colorA == colorB) {
|
||||||
product = colorA;
|
product0 = colorA;
|
||||||
product1 = colorA;
|
product1 = colorA;
|
||||||
product2 = colorA;
|
product2 = colorA;
|
||||||
} else {
|
} else {
|
||||||
register int r = 0;
|
product0 = interpolate(colorA, colorB);
|
||||||
|
|
||||||
product1 = interpolate(colorA, colorC);
|
product1 = interpolate(colorA, colorC);
|
||||||
product = interpolate(colorA, colorB);
|
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
r += getResult1(colorA, colorB, colorG, colorE);
|
r += getResult1(colorA, colorB, colorG, colorE);
|
||||||
r += getResult2(colorB, colorA, colorK, colorF);
|
r += getResult2(colorB, colorA, colorK, colorF);
|
||||||
r += getResult2(colorB, colorA, colorH, colorN);
|
r += getResult2(colorB, colorA, colorH, colorN);
|
||||||
r += getResult1(colorA, colorB, colorL, colorO);
|
r += getResult1(colorA, colorB, colorL, colorO);
|
||||||
|
if (r > 0) {
|
||||||
if (r > 0)
|
|
||||||
product2 = colorA;
|
product2 = colorA;
|
||||||
else if (r < 0)
|
} else if (r < 0) {
|
||||||
product2 = colorB;
|
product2 = colorB;
|
||||||
else {
|
} else {
|
||||||
product2 = qInterpolate(colorA, colorB, colorC, colorD);
|
product2 = qInterpolate(colorA, colorB, colorC, colorD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,32 +172,32 @@ static void filter(gambatte::uint_least32_t *dstPtr, const std::ptrdiff_t dstPit
|
|||||||
product2 = qInterpolate(colorA, colorB, colorC, colorD);
|
product2 = qInterpolate(colorA, colorB, colorC, colorD);
|
||||||
|
|
||||||
if (colorA == colorC && colorA == colorF
|
if (colorA == colorC && colorA == colorF
|
||||||
&& colorB != colorE && colorB == colorJ) {
|
&& colorB != colorE && colorB == colorJ) {
|
||||||
product = colorA;
|
product0 = colorA;
|
||||||
} else if (colorB == colorE && colorB == colorD
|
} else if (colorB == colorE && colorB == colorD
|
||||||
&& colorA != colorF && colorA == colorI) {
|
&& colorA != colorF && colorA == colorI) {
|
||||||
product = colorB;
|
product0 = colorB;
|
||||||
} else {
|
} else {
|
||||||
product = interpolate(colorA, colorB);
|
product0 = interpolate(colorA, colorB);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorA == colorB && colorA == colorH
|
if (colorA == colorB && colorA == colorH
|
||||||
&& colorG != colorC && colorC == colorM) {
|
&& colorG != colorC && colorC == colorM) {
|
||||||
product1 = colorA;
|
product1 = colorA;
|
||||||
} else if (colorC == colorG && colorC == colorD
|
} else if (colorC == colorG && colorC == colorD
|
||||||
&& colorA != colorH && colorA == colorI) {
|
&& colorA != colorH && colorA == colorI) {
|
||||||
product1 = colorC;
|
product1 = colorC;
|
||||||
} else {
|
} else {
|
||||||
product1 = interpolate(colorA, colorC);
|
product1 = interpolate(colorA, colorC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*dP = colorA;
|
|
||||||
*(dP + 1) = product;
|
|
||||||
*(dP + dstPitch) = product1;
|
|
||||||
*(dP + dstPitch + 1) = product2;
|
|
||||||
|
|
||||||
++bP;
|
*(dP ) = colorA;
|
||||||
|
*(dP + 1) = product0;
|
||||||
|
*(dP + dstPitch ) = product1;
|
||||||
|
*(dP + dstPitch + 1) = product2;
|
||||||
dP += 2;
|
dP += 2;
|
||||||
|
++bP;
|
||||||
}
|
}
|
||||||
|
|
||||||
srcPtr += srcPitch;
|
srcPtr += srcPitch;
|
||||||
@ -209,28 +205,29 @@ static void filter(gambatte::uint_least32_t *dstPtr, const std::ptrdiff_t dstPit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { WIDTH = VfilterInfo::IN_WIDTH };
|
enum { in_width = VfilterInfo::in_width };
|
||||||
enum { HEIGHT = VfilterInfo::IN_HEIGHT };
|
enum { in_height = VfilterInfo::in_height };
|
||||||
enum { PITCH = WIDTH + 3 };
|
enum { in_pitch = in_width + 3 };
|
||||||
enum { BUF_SIZE = (HEIGHT + 3) * PITCH };
|
enum { buf_size = (in_height + 3ul) * in_pitch };
|
||||||
enum { BUF_OFFSET = PITCH + 1 };
|
enum { buf_offset = in_pitch + 1 };
|
||||||
|
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
Kreed2xSaI::Kreed2xSaI()
|
Kreed2xSaI::Kreed2xSaI()
|
||||||
: buffer_(BUF_SIZE)
|
: buffer_(buf_size)
|
||||||
{
|
{
|
||||||
std::fill_n(buffer_.get(), buffer_.size(), 0);
|
std::fill_n(buffer_.get(), buffer_.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Kreed2xSaI::inBuf() const {
|
void * Kreed2xSaI::inBuf() const {
|
||||||
return buffer_ + BUF_OFFSET;
|
return buffer_ + buf_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ptrdiff_t Kreed2xSaI::inPitch() const {
|
std::ptrdiff_t Kreed2xSaI::inPitch() const {
|
||||||
return PITCH;
|
return in_pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kreed2xSaI::draw(void *const dbuffer, const std::ptrdiff_t pitch) {
|
void Kreed2xSaI::draw(void *dbuffer, std::ptrdiff_t dpitch) {
|
||||||
::filter<PITCH, WIDTH, HEIGHT>(static_cast<gambatte::uint_least32_t*>(dbuffer), pitch, buffer_ + BUF_OFFSET);
|
::filter<in_pitch, in_width, in_height>(static_cast<gambatte::uint_least32_t *>(dbuffer),
|
||||||
|
dpitch, buffer_ + buf_offset);
|
||||||
}
|
}
|
||||||
|
10
common/videolink/vfilters/kreed2xsai.h
Executable file → Normal file
10
common/videolink/vfilters/kreed2xsai.h
Executable file → Normal file
@ -25,15 +25,17 @@
|
|||||||
#include "gbint.h"
|
#include "gbint.h"
|
||||||
|
|
||||||
class Kreed2xSaI : public VideoLink {
|
class Kreed2xSaI : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> buffer_;
|
|
||||||
public:
|
public:
|
||||||
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 2 };
|
enum { out_width = VfilterInfo::in_width * 2 };
|
||||||
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 2 };
|
enum { out_height = VfilterInfo::in_height * 2 };
|
||||||
|
|
||||||
Kreed2xSaI();
|
Kreed2xSaI();
|
||||||
virtual void* inBuf() const;
|
virtual void * inBuf() const;
|
||||||
virtual std::ptrdiff_t inPitch() const;
|
virtual std::ptrdiff_t inPitch() const;
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Array<gambatte::uint_least32_t> const buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1102
common/videolink/vfilters/maxsthq2x.cpp
Executable file → Normal file
1102
common/videolink/vfilters/maxsthq2x.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
10
common/videolink/vfilters/maxsthq2x.h
Executable file → Normal file
10
common/videolink/vfilters/maxsthq2x.h
Executable file → Normal file
@ -25,15 +25,17 @@
|
|||||||
#include "gbint.h"
|
#include "gbint.h"
|
||||||
|
|
||||||
class MaxStHq2x : public VideoLink {
|
class MaxStHq2x : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> buffer_;
|
|
||||||
public:
|
public:
|
||||||
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 2 };
|
enum { out_width = VfilterInfo::in_width * 2 };
|
||||||
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 2 };
|
enum { out_height = VfilterInfo::in_height * 2 };
|
||||||
|
|
||||||
MaxStHq2x();
|
MaxStHq2x();
|
||||||
virtual void* inBuf() const;
|
virtual void * inBuf() const;
|
||||||
virtual std::ptrdiff_t inPitch() const;
|
virtual std::ptrdiff_t inPitch() const;
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SimpleArray<gambatte::uint_least32_t> const buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1082
common/videolink/vfilters/maxsthq3x.cpp
Executable file → Normal file
1082
common/videolink/vfilters/maxsthq3x.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
10
common/videolink/vfilters/maxsthq3x.h
Executable file → Normal file
10
common/videolink/vfilters/maxsthq3x.h
Executable file → Normal file
@ -25,15 +25,17 @@
|
|||||||
#include "gbint.h"
|
#include "gbint.h"
|
||||||
|
|
||||||
class MaxStHq3x : public VideoLink {
|
class MaxStHq3x : public VideoLink {
|
||||||
const Array<gambatte::uint_least32_t> buffer_;
|
|
||||||
public:
|
public:
|
||||||
enum { OUT_WIDTH = VfilterInfo::IN_WIDTH * 3 };
|
enum { out_width = VfilterInfo::in_width * 3 };
|
||||||
enum { OUT_HEIGHT = VfilterInfo::IN_HEIGHT * 3 };
|
enum { out_height = VfilterInfo::in_height * 3 };
|
||||||
|
|
||||||
MaxStHq3x();
|
MaxStHq3x();
|
||||||
virtual void* inBuf() const;
|
virtual void * inBuf() const;
|
||||||
virtual std::ptrdiff_t inPitch() const;
|
virtual std::ptrdiff_t inPitch() const;
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
virtual void draw(void *dst, std::ptrdiff_t dstpitch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SimpleArray<gambatte::uint_least32_t> const buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
2
common/videolink/videolink.h
Executable file → Normal file
2
common/videolink/videolink.h
Executable file → Normal file
@ -24,7 +24,7 @@
|
|||||||
class VideoLink {
|
class VideoLink {
|
||||||
public:
|
public:
|
||||||
virtual ~VideoLink() {}
|
virtual ~VideoLink() {}
|
||||||
virtual void* inBuf() const = 0;
|
virtual void * inBuf() const = 0;
|
||||||
virtual std::ptrdiff_t inPitch() const = 0;
|
virtual std::ptrdiff_t inPitch() const = 0;
|
||||||
virtual void draw(void *dst, std::ptrdiff_t dstpitch) = 0;
|
virtual void draw(void *dst, std::ptrdiff_t dstpitch) = 0;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user