forked from mia/Aegisub
Reworking of video frame interface, into more general RGB(A) image interface
Originally committed to SVN as r1485.
This commit is contained in:
parent
43149f9276
commit
2699972427
5 changed files with 205 additions and 107 deletions
|
@ -24,6 +24,9 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Must be included before <windows.h>, otherwise some macros from <windows.h> get in the way
|
||||||
|
#include "video_frame.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
@ -95,11 +98,11 @@ public:
|
||||||
try {
|
try {
|
||||||
switch (vi.pixel_type) {
|
switch (vi.pixel_type) {
|
||||||
case VideoInfo::CS_BGR24: {
|
case VideoInfo::CS_BGR24: {
|
||||||
OverLuaVideoFrameBGR *frame = new OverLuaVideoFrameBGR(vi.width, vi.height, stride, plane);
|
ImageBGR *frame = new ImageBGR(vi.width, vi.height, stride, plane);
|
||||||
script->RenderFrameRGB(*frame, frametime);
|
script->RenderFrameRGB(*frame, frametime);
|
||||||
} break;
|
} break;
|
||||||
case VideoInfo::CS_BGR32: {
|
case VideoInfo::CS_BGR32: {
|
||||||
OverLuaVideoFrameBGRX *frame = new OverLuaVideoFrameBGRX(vi.width, vi.height, stride, plane);
|
ImageBGRX *frame = new ImageBGRX(vi.width, vi.height, stride, plane);
|
||||||
script->RenderFrameRGB(*frame, frametime);
|
script->RenderFrameRGB(*frame, frametime);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// CSRI interface is unmaintained for now
|
||||||
|
#if 0
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
|
@ -112,22 +115,22 @@ CSRIAPI void csri_render(csri_inst *inst, struct csri_frame *frame, double time)
|
||||||
// check for correct pixfmt
|
// check for correct pixfmt
|
||||||
if (frame->pixfmt != inst->frame_format.pixfmt) return;
|
if (frame->pixfmt != inst->frame_format.pixfmt) return;
|
||||||
|
|
||||||
OverLuaFrameAggregate *olframe = 0;
|
BaseImageAggregate *olframe = 0;
|
||||||
switch (frame->pixfmt) {
|
switch (frame->pixfmt) {
|
||||||
#define HANDLE_RGB_FORMAT(fmtname, Rpos, Gpos, Bpos, PixelWidth) \
|
#define HANDLE_RGB_FORMAT(fmtname, PixFmt) \
|
||||||
case fmtname: \
|
case fmtname: \
|
||||||
olframe = new OverLuaFrameAggregateImpl<Rpos,Gpos,Bpos,PixelWidth>(inst->frame_format.width, inst->frame_format.height, frame->strides[0], frame->planes[0]); \
|
olframe = new BaseImageAggregateImpl<PixelFormat:: ## PixFmt>(inst->frame_format.width, inst->frame_format.height, frame->strides[0], frame->planes[0]); \
|
||||||
break;
|
break;
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_RGBA, 0, 1, 2, 4)
|
HANDLE_RGB_FORMAT(CSRI_F_RGBA, RGBA)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_ARGB, 1, 2, 3, 4)
|
HANDLE_RGB_FORMAT(CSRI_F_ARGB, ARGB)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_BGRA, 2, 1, 0, 4)
|
HANDLE_RGB_FORMAT(CSRI_F_BGRA, BGRA)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_ABGR, 3, 2, 1, 4)
|
HANDLE_RGB_FORMAT(CSRI_F_ABGR, ABGR)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_RGB_, 0, 1, 2, 4)
|
HANDLE_RGB_FORMAT(CSRI_F_RGB_, RGBX)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F__RGB, 1, 2, 3, 4)
|
HANDLE_RGB_FORMAT(CSRI_F__RGB, XRGB)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_BGR_, 2, 1, 0, 4)
|
HANDLE_RGB_FORMAT(CSRI_F_BGR_, BGRX)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F__BGR, 3, 2, 1, 4)
|
HANDLE_RGB_FORMAT(CSRI_F__BGR, XBGR)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_RGB, 0, 1, 2, 3)
|
HANDLE_RGB_FORMAT(CSRI_F_RGB, RGB)
|
||||||
HANDLE_RGB_FORMAT(CSRI_F_BGR, 2, 1, 0, 3)
|
HANDLE_RGB_FORMAT(CSRI_F_BGR, BGR)
|
||||||
default: break; // what, we don't support this!
|
default: break; // what, we don't support this!
|
||||||
#undef HANDLE_RGB_FORMAT
|
#undef HANDLE_RGB_FORMAT
|
||||||
}
|
}
|
||||||
|
@ -200,3 +203,5 @@ CSRIAPI csri_rend *csri_renderer_next(csri_rend *prev)
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -105,7 +105,7 @@ OverLuaScript::~OverLuaScript()
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverLuaScript::RenderFrameRGB(OverLuaFrameAggregate &frame, double time)
|
void OverLuaScript::RenderFrameRGB(BaseImageAggregate &frame, double time)
|
||||||
{
|
{
|
||||||
lua_getglobal(L, "render_frame");
|
lua_getglobal(L, "render_frame");
|
||||||
frame.CreateLuaObject(L);
|
frame.CreateLuaObject(L);
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
OverLuaScript(const void *data, size_t length, const char *_datastring = 0);
|
OverLuaScript(const void *data, size_t length, const char *_datastring = 0);
|
||||||
virtual ~OverLuaScript();
|
virtual ~OverLuaScript();
|
||||||
|
|
||||||
void RenderFrameRGB(OverLuaFrameAggregate &frame, double time);
|
void RenderFrameRGB(BaseImageAggregate &frame, double time);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,63 +28,159 @@
|
||||||
#define VIDEO_FRAME_H
|
#define VIDEO_FRAME_H
|
||||||
|
|
||||||
#include "../lua51/src/lua.h"
|
#include "../lua51/src/lua.h"
|
||||||
|
#include "../lua51/src/lauxlib.h"
|
||||||
#include "cairo_wrap.h"
|
#include "cairo_wrap.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
|
|
||||||
// Forward
|
|
||||||
class OverLuaFrameAggregate;
|
|
||||||
|
|
||||||
// store a colour value
|
// Forward
|
||||||
struct RGBPixel {
|
class BaseImageAggregate;
|
||||||
unsigned char r, g, b;
|
|
||||||
RGBPixel(unsigned char R, unsigned char G, unsigned char B) : r(R), g(G), b(B) { }
|
|
||||||
|
// Supported pixel formats
|
||||||
|
namespace PixelFormat {
|
||||||
|
// A constant value with a fake assignment operator
|
||||||
|
template <class T, T v>
|
||||||
|
struct NopAssigningConstant {
|
||||||
|
operator T() { return v; }
|
||||||
|
void operator = (const T &n) { }
|
||||||
|
};
|
||||||
|
typedef NopAssigningConstant<uint8_t,255> ROA; // "read only alpha"
|
||||||
|
|
||||||
|
// 24 bit formats
|
||||||
|
struct RGB {
|
||||||
|
uint8_t r, g, b;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline ROA A() const { return ROA(); }
|
||||||
|
RGB() : r(0), g(0), b(0) { }
|
||||||
|
template <class PixFmt> RGB(const PixFmt &src) { r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct BGR {
|
||||||
|
uint8_t b, g, r;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline ROA A() const { return ROA(); }
|
||||||
|
BGR() : r(0), g(0), b(0) { }
|
||||||
|
template <class PixFmt> BGR(const PixFmt &src) { r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 32 bit alpha-less formats
|
||||||
|
struct RGBX {
|
||||||
|
uint8_t r, g, b, x;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline ROA A() const { return ROA(); }
|
||||||
|
RGBX() : r(0), g(0), b(0) { }
|
||||||
|
template <class PixFmt> RGBX(const PixFmt &src) { r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct BGRX {
|
||||||
|
uint8_t b, g, r, x;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline ROA A() const { return ROA(); }
|
||||||
|
BGRX() : r(0), g(0), b(0) { }
|
||||||
|
template <class PixFmt> BGRX(const PixFmt &src) { r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct XRGB {
|
||||||
|
uint8_t x, r, g, b;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline ROA A() const { return ROA(); }
|
||||||
|
XRGB() : r(0), g(0), b(0) { }
|
||||||
|
template <class PixFmt> XRGB(const PixFmt &src) { r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct XBGR {
|
||||||
|
uint8_t x, b, g, r;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline ROA A() const { return ROA(); }
|
||||||
|
XBGR() : r(0), g(0), b(0) { }
|
||||||
|
template <class PixFmt> XBGR(const PixFmt &src) { r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 32 bit with alpha
|
||||||
|
struct RGBA {
|
||||||
|
uint8_t r, g, b, a;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline uint8_t &A() { return a; } inline uint8_t A() const { return a; }
|
||||||
|
RGBA() : r(0), g(0), b(0), a(0) { }
|
||||||
|
template <class PixFmt> RGBA(const PixFmt &src) { a = src.A(); r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct BGRA {
|
||||||
|
uint8_t b, g, r, a;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline uint8_t &A() { return a; } inline uint8_t A() const { return a; }
|
||||||
|
BGRA() : r(0), g(0), b(0), a(0) { }
|
||||||
|
template <class PixFmt> BGRA(const PixFmt &src) { a = src.A(); r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct ARGB {
|
||||||
|
uint8_t a, r, g, b;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline uint8_t &A() { return a; } inline uint8_t A() const { return a; }
|
||||||
|
ARGB() : r(0), g(0), b(0), a(0) { }
|
||||||
|
template <class PixFmt> ARGB(const PixFmt &src) { a = src.A(); r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
|
struct ABGR {
|
||||||
|
uint8_t a, b, g, r;
|
||||||
|
inline uint8_t &R() { return r; } inline uint8_t R() const { return r; }
|
||||||
|
inline uint8_t &G() { return g; } inline uint8_t G() const { return g; }
|
||||||
|
inline uint8_t &B() { return b; } inline uint8_t B() const { return b; }
|
||||||
|
inline uint8_t &A() { return a; } inline uint8_t A() const { return a; }
|
||||||
|
ABGR() : r(0), g(0), b(0), a(0) { }
|
||||||
|
template <class PixFmt> ABGR(const PixFmt &src) { a = src.A(); r = src.R(); g = src.G(); b = src.B(); }
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Support any interleaved RGB format with 8 bit per channel
|
// Support any interleaved RGB format with 8 bit per channel
|
||||||
// You usually don't want to instance this class directly,
|
// You usually don't want to instance this class directly,
|
||||||
// look at OverLuaFrameAggregate defined below
|
// look at OverLuaFrameAggregate defined below
|
||||||
template<ptrdiff_t Rpos, ptrdiff_t Gpos, ptrdiff_t Bpos, ptrdiff_t PixelWidth>
|
template<class PixFmt>
|
||||||
class OverLuaVideoFrame {
|
class BaseImage {
|
||||||
public:
|
public:
|
||||||
typedef OverLuaVideoFrame<Rpos,Gpos,Bpos,PixelWidth> MyType;
|
typedef BaseImage<PixFmt> MyType;
|
||||||
|
|
||||||
// video properties
|
// video properties
|
||||||
unsigned width;
|
int width;
|
||||||
unsigned height;
|
int height;
|
||||||
ptrdiff_t stride;
|
ptrdiff_t stride;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
// read a pixel value
|
// Access a pixel value
|
||||||
inline const RGBPixel GetPixel(unsigned x, unsigned y)
|
inline const PixFmt &Pixel(int x, int y) const
|
||||||
{
|
{
|
||||||
RGBPixel res(0, 0, 0);
|
return *((PixFmt*)(data + y*stride) + x)
|
||||||
unsigned char *ptr = data + y*stride + x*PixelWidth;
|
|
||||||
res.r = ptr[Rpos];
|
|
||||||
res.g = ptr[Gpos];
|
|
||||||
res.b = ptr[Bpos];
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write a pixel value
|
inline PixFmt &Pixel(int x, int y)
|
||||||
inline void SetPixel(unsigned x, unsigned y, const RGBPixel &val)
|
|
||||||
{
|
{
|
||||||
unsigned char *ptr = data + y*stride + x*PixelWidth;
|
return *((PixFmt*)(data + y*stride) + x);
|
||||||
ptr[Rpos] = val.r;
|
|
||||||
ptr[Gpos] = val.g;
|
|
||||||
ptr[Bpos] = val.b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OverLuaVideoFrame(unsigned _width, unsigned _height, ptrdiff_t _stride, unsigned char *_data)
|
BaseImage(unsigned _width, unsigned _height, ptrdiff_t _stride, unsigned char *_data)
|
||||||
: width(_width), height(_height), stride(_stride), data(_data)
|
: width(_width), height(_height), stride(_stride), data(_data)
|
||||||
{
|
{
|
||||||
owndata = false;
|
owndata = false;
|
||||||
// nothing further to init
|
// nothing further to init
|
||||||
}
|
}
|
||||||
|
|
||||||
OverLuaVideoFrame(const MyType &src, bool copydata = false)
|
BaseImage(const MyType &src, bool copydata = false)
|
||||||
{
|
{
|
||||||
width = src.width;
|
width = src.width;
|
||||||
height = src.height;
|
height = src.height;
|
||||||
|
@ -98,14 +194,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~OverLuaVideoFrame()
|
~BaseImage()
|
||||||
{
|
{
|
||||||
if (owndata)
|
if (owndata)
|
||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// should never be called more than once on the same C++ object
|
// should never be called more than once on the same C++ object
|
||||||
void CreateLuaObject(lua_State *L, OverLuaFrameAggregate *aggregate = 0)
|
void CreateLuaObject(lua_State *L, BaseImageAggregate *aggregate = 0)
|
||||||
{
|
{
|
||||||
// create userdata object
|
// create userdata object
|
||||||
MyType **ud = (MyType**)lua_newuserdata(L, sizeof(MyType*));
|
MyType **ud = (MyType**)lua_newuserdata(L, sizeof(MyType*));
|
||||||
|
@ -123,7 +219,7 @@ public:
|
||||||
lua_setfield(L, -2, "__gc");
|
lua_setfield(L, -2, "__gc");
|
||||||
if (aggregate) {
|
if (aggregate) {
|
||||||
lua_pushlightuserdata(L, aggregate);
|
lua_pushlightuserdata(L, aggregate);
|
||||||
lua_setfield(L, -2, "videoframe");
|
lua_setfield(L, -2, "image");
|
||||||
}
|
}
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
}
|
}
|
||||||
|
@ -142,32 +238,32 @@ private:
|
||||||
if (lua_isnumber(L, 2)) {
|
if (lua_isnumber(L, 2)) {
|
||||||
if (lua_istable(L, 3)) {
|
if (lua_istable(L, 3)) {
|
||||||
int n = (int)lua_tointeger(L, 2);
|
int n = (int)lua_tointeger(L, 2);
|
||||||
unsigned x = n % (*ud)->width;
|
int x = n % (*ud)->width;
|
||||||
unsigned y = n / (*ud)->width;
|
int y = n / (*ud)->width;
|
||||||
if (x < 0 || y < 0 || x >= (*ud)->width || y >= (*ud)->height) return 0;
|
if (x < 0 || y < 0 || x >= (*ud)->width || y >= (*ud)->height) return 0;
|
||||||
|
|
||||||
// read first three entries from table
|
// read first three entries from table
|
||||||
RGBPixel color(0,0,0);
|
PixFmt color;
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
if (!lua_next(L, 3)) goto badtable;
|
if (!lua_next(L, 3)) goto badtable;
|
||||||
if (!lua_isnumber(L, -1)) goto badtable;
|
if (!lua_isnumber(L, -1)) goto badtable;
|
||||||
color.r = (unsigned char)lua_tointeger(L, -1);
|
color.R() = (unsigned char)lua_tointeger(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (!lua_next(L, 3)) goto badtable;
|
if (!lua_next(L, 3)) goto badtable;
|
||||||
if (!lua_isnumber(L, -1)) goto badtable;
|
if (!lua_isnumber(L, -1)) goto badtable;
|
||||||
color.g = (unsigned char)lua_tointeger(L, -1);
|
color.G() = (unsigned char)lua_tointeger(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (!lua_next(L, 3)) goto badtable;
|
if (!lua_next(L, 3)) goto badtable;
|
||||||
if (!lua_isnumber(L, -1)) goto badtable;
|
if (!lua_isnumber(L, -1)) goto badtable;
|
||||||
color.b = (unsigned char)lua_tointeger(L, -1);
|
color.B() = (unsigned char)lua_tointeger(L, -1);
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
|
||||||
(*ud)->SetPixel(x, y, color);
|
(*ud)->Pixel(x, y) = color;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
badtable:
|
badtable:
|
||||||
lua_pushliteral(L, "Value set into video frame pixel must be a table with at least 3 entries");
|
lua_pushliteral(L, "Value set into image pixel must be a table with at least 3 entries");
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +297,7 @@ badtable:
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_pushcclosure(L, lua_overlay_cairo_surface, 1);
|
lua_pushcclosure(L, lua_overlay_cairo_surface, 1);
|
||||||
} else {
|
} else {
|
||||||
lua_pushfstring(L, "Undefined field name in video frame: %s", fieldname);
|
lua_pushfstring(L, "Undefined field name in image: %s", fieldname);
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +305,7 @@ badtable:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushfstring(L, "Unhandled field type indexing video frame: %s", lua_typename(L, lua_type(L, 2)));
|
lua_pushfstring(L, "Unhandled field type indexing image: %s", lua_typename(L, lua_type(L, 2)));
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -221,19 +317,19 @@ badtable:
|
||||||
// third arg = y
|
// third arg = y
|
||||||
MyType **ud = (MyType**)lua_touserdata(L, 1);
|
MyType **ud = (MyType**)lua_touserdata(L, 1);
|
||||||
|
|
||||||
unsigned x = luaL_checkint(L, 2);
|
int x = luaL_checkint(L, 2);
|
||||||
unsigned y = luaL_checkint(L, 3);
|
int y = luaL_checkint(L, 3);
|
||||||
|
|
||||||
RGBPixel color(0,0,0);
|
|
||||||
if (x < 0 || y < 0 || x >= (*ud)->width || y >= (*ud)->height) {
|
if (x < 0 || y < 0 || x >= (*ud)->width || y >= (*ud)->height) {
|
||||||
// already black, leave it
|
lua_pushinteger(L, 0);
|
||||||
|
lua_pushinteger(L, 0);
|
||||||
|
lua_pushinteger(L, 0);
|
||||||
} else {
|
} else {
|
||||||
// get it
|
const PixFmt &p = (*ud)->Pixel(x, y);
|
||||||
color = (*ud)->GetPixel(x, y);
|
lua_pushinteger(L, p.r);
|
||||||
|
lua_pushinteger(L, p.g);
|
||||||
|
lua_pushinteger(L, p.b);
|
||||||
}
|
}
|
||||||
lua_pushinteger(L, color.r);
|
|
||||||
lua_pushinteger(L, color.g);
|
|
||||||
lua_pushinteger(L, color.b);
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,12 +370,11 @@ badtable:
|
||||||
int width = (*ud)->width;
|
int width = (*ud)->width;
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
uint32_t *opix = (uint32_t*)(surfdata + y*surfstride);
|
PixFmt *ipix = (PixFmt*)((*ud)->data + y*((*ud)->stride));
|
||||||
|
PixelFormat::XBGR *opix = (PixelFormat::XBGR*)(surfdata + y*surfstride);
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
// Hoping this will get optimised at least a bit by the compiler
|
// Hoping this will get optimised at least a bit by the compiler
|
||||||
RGBPixel ipix = (*ud)->GetPixel(x, y);
|
*opix++ = PixelFormat::XBGR(*ipix++);
|
||||||
*opix = ipix.r << 16 | ipix.g << 8 | ipix.b;
|
|
||||||
opix++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cairo_surface_mark_dirty(surf);
|
cairo_surface_mark_dirty(surf);
|
||||||
|
@ -338,17 +433,16 @@ badtable:
|
||||||
int lines_to_compose = (slines_to_compose<flines_to_compose)?slines_to_compose:flines_to_compose;
|
int lines_to_compose = (slines_to_compose<flines_to_compose)?slines_to_compose:flines_to_compose;
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (int composition_line = 0; composition_line < lines_to_compose; composition_line++) {
|
for (int composition_line = 0; composition_line < lines_to_compose; composition_line++) {
|
||||||
uint32_t *sline = (uint32_t*)(sdata + composition_line*sstride);
|
PixelFormat::ARGB *sline = (PixelFormat::ARGB*)(sdata + composition_line*sstride);
|
||||||
int fx = xpos;
|
int fx = xpos;
|
||||||
int sx = 0;
|
int sx = 0;
|
||||||
if (fx < 0) fx = 0, sx = -xpos;
|
if (fx < 0) fx = 0, sx = -xpos;
|
||||||
for ( ; sx < swidth && fx < fwidth; fx++, sx++) {
|
for ( ; sx < swidth && fx < fwidth; fx++, sx++) {
|
||||||
RGBPixel pix = (*ud)->GetPixel(fx, fy+composition_line);
|
PixFmt &pix = (*ud)->Pixel(fx, fy+composition_line);
|
||||||
unsigned char a = 0xff - ((sline[sx] & 0xff000000) >> 24);
|
unsigned char a = 0xff - sline[sx].A();
|
||||||
pix.r = ((sline[sx] & 0x00ff0000) >> 16) + a*pix.r/255;
|
pix.R() = sline[sx].R() + a*pix.R()/255;
|
||||||
pix.g = ((sline[sx] & 0x0000ff00) >> 8) + a*pix.g/255;
|
pix.G() = sline[sx].G() + a*pix.G()/255;
|
||||||
pix.b = (sline[sx] & 0x000000ff) + a*pix.b/255;
|
pix.B() = sline[sx].B() + a*pix.B()/255;
|
||||||
(*ud)->SetPixel(fx, fy+composition_line, pix);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,16 +455,12 @@ badtable:
|
||||||
int lines_to_compose = (slines_to_compose<flines_to_compose)?slines_to_compose:flines_to_compose;
|
int lines_to_compose = (slines_to_compose<flines_to_compose)?slines_to_compose:flines_to_compose;
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (int composition_line = 0; composition_line < lines_to_compose; composition_line++) {
|
for (int composition_line = 0; composition_line < lines_to_compose; composition_line++) {
|
||||||
uint32_t *sline = (uint32_t*)(sdata + composition_line*sstride);
|
PixelFormat::XRGB *sline = (PixelFormat::XRGB*)(sdata + composition_line*sstride);
|
||||||
int fx = xpos;
|
int fx = xpos;
|
||||||
int sx = 0;
|
int sx = 0;
|
||||||
if (fx < 0) fx = 0, sx = -xpos;
|
if (fx < 0) fx = 0, sx = -xpos;
|
||||||
for ( ; sx < swidth && fx < fwidth; fx++, sx++) {
|
for ( ; sx < swidth && fx < fwidth; fx++, sx++) {
|
||||||
RGBPixel pix(
|
sline[sx] = PixelFormat::XRGB((*ud)->Pixel(fx, fy+composition_line));
|
||||||
(sline[sx] & 0x00ff0000) >> 16,
|
|
||||||
(sline[sx] & 0x0000ff00) >> 8,
|
|
||||||
sline[sx] & 0x000000ff);
|
|
||||||
(*ud)->SetPixel(fx, fy+composition_line, pix);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,45 +499,45 @@ badtable:
|
||||||
// in the C++ code. It nicely hides all templatyness away into various implementations.
|
// in the C++ code. It nicely hides all templatyness away into various implementations.
|
||||||
// This could probably have been designed better. Shame on me.
|
// This could probably have been designed better. Shame on me.
|
||||||
|
|
||||||
class OverLuaFrameAggregate {
|
class BaseImageAggregate {
|
||||||
public:
|
public:
|
||||||
virtual RGBPixel GetPixel(unsigned x, unsigned y) = 0;
|
virtual PixelFormat::ARGB GetPixel(int x, int y) = 0;
|
||||||
virtual void SetPixel(unsigned x, unsigned y, const RGBPixel &val) = 0;
|
virtual void SetPixel(int x, int y, const PixelFormat::ARGB &val) = 0;
|
||||||
virtual unsigned GetWidth() = 0;
|
virtual unsigned GetWidth() = 0;
|
||||||
virtual unsigned GetHeight() = 0;
|
virtual unsigned GetHeight() = 0;
|
||||||
virtual void CreateLuaObject(lua_State *L) = 0;
|
virtual void CreateLuaObject(lua_State *L) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <ptrdiff_t Rpos, ptrdiff_t Gpos, ptrdiff_t Bpos, ptrdiff_t PixelWidth>
|
template <class PixFmt>
|
||||||
class OverLuaFrameAggregateImpl : public OverLuaFrameAggregate {
|
class BaseImageAggregateImpl : public BaseImageAggregate {
|
||||||
public:
|
public:
|
||||||
typedef OverLuaVideoFrame<Rpos, Gpos, Bpos, PixelWidth> VideoFrameType;
|
typedef BaseImage<PixFmt> ImageType;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VideoFrameType *frame;
|
ImageType *frame;
|
||||||
bool ownframe;
|
bool ownframe;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OverLuaFrameAggregateImpl(unsigned _width, unsigned _height, ptrdiff_t _stride, unsigned char *_data)
|
BaseImageAggregateImpl(unsigned _width, unsigned _height, ptrdiff_t _stride, unsigned char *_data)
|
||||||
{
|
{
|
||||||
frame = new VideoFrameType(_width, _height, _stride, _data);
|
frame = new ImageType(_width, _height, _stride, _data);
|
||||||
ownframe = true;
|
ownframe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OverLuaFrameAggregateImpl(VideoFrameType *_frame)
|
BaseImageAggregateImpl(ImageType *_frame)
|
||||||
{
|
{
|
||||||
frame = _frame;
|
frame = _frame;
|
||||||
ownframe = false;
|
ownframe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBPixel GetPixel(unsigned x, unsigned y)
|
PixelFormat::ARGB GetPixel(int x, int y)
|
||||||
{
|
{
|
||||||
return frame->GetPixel(x, y);
|
return PixelFormat::ARGB(frame->Pixel(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPixel(unsigned x, unsigned y, const RGBPixel &val)
|
void SetPixel(int x, int y, const PixelFormat::ARGB &val)
|
||||||
{
|
{
|
||||||
frame->SetPixel(x, y, val);
|
frame->Pixel(x, y) = PixFmt(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned GetWidth()
|
unsigned GetWidth()
|
||||||
|
@ -468,15 +558,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// All common, sensible formats
|
// All common, sensible formats
|
||||||
typedef OverLuaFrameAggregateImpl<2, 1, 0, 3> OverLuaVideoFrameBGR;
|
typedef BaseImageAggregateImpl<PixelFormat::RGB> ImageRGB;
|
||||||
typedef OverLuaFrameAggregateImpl<2, 1, 0, 4> OverLuaVideoFrameBGRX;
|
typedef BaseImageAggregateImpl<PixelFormat::BGR> ImageBGR;
|
||||||
typedef OverLuaFrameAggregateImpl<2, 1, 0, 4> OverLuaVideoFrameBGRA;
|
typedef BaseImageAggregateImpl<PixelFormat::RGBX> ImageRGBX;
|
||||||
typedef OverLuaFrameAggregateImpl<0, 1, 2, 3> OverLuaVideoFrameRGB;
|
typedef BaseImageAggregateImpl<PixelFormat::BGRX> ImageBGRX;
|
||||||
typedef OverLuaFrameAggregateImpl<0, 1, 2, 4> OverLuaVideoFrameRGBX;
|
typedef BaseImageAggregateImpl<PixelFormat::XRGB> ImageXRGB;
|
||||||
typedef OverLuaFrameAggregateImpl<0, 1, 2, 4> OverLuaVideoFrameRGBA;
|
typedef BaseImageAggregateImpl<PixelFormat::XBGR> ImageXBGR;
|
||||||
typedef OverLuaFrameAggregateImpl<1, 2, 3, 4> OverLuaVideoFrameXRGB;
|
typedef BaseImageAggregateImpl<PixelFormat::RGBA> ImageRGBA;
|
||||||
typedef OverLuaFrameAggregateImpl<1, 2, 3, 4> OverLuaVideoFrameARGB;
|
typedef BaseImageAggregateImpl<PixelFormat::BGRA> ImageBGRA;
|
||||||
typedef OverLuaFrameAggregateImpl<3, 2, 1, 4> OverLuaVideoFrameXBGR;
|
typedef BaseImageAggregateImpl<PixelFormat::ARGB> ImageARGB;
|
||||||
typedef OverLuaFrameAggregateImpl<3, 2, 1, 4> OverLuaVideoFrameABGR;
|
typedef BaseImageAggregateImpl<PixelFormat::ABGR> ImageABGR;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue