mirror of
https://github.com/love2d/love.git
synced 2026-08-17 02:58:31 +02:00
ImageData: limited support for integer pixel formats.
For now this doesn't support conversions (get/set/mapPixel, etc). Just the ability for ImageData to contain integer pixel contents, for example via Canvas:newImageData.
This commit is contained in:
@@ -43,7 +43,7 @@ ImageData::ImageData(int width, int height, PixelFormat format)
|
||||
: ImageDataBase(format, width, height)
|
||||
{
|
||||
if (!validPixelFormat(format))
|
||||
throw love::Exception("Unsupported pixel format for ImageData");
|
||||
throw love::Exception("ImageData does not support the %s pixel format.", getPixelFormatName(format));
|
||||
|
||||
create(width, height, format);
|
||||
|
||||
@@ -55,7 +55,7 @@ ImageData::ImageData(int width, int height, PixelFormat format, void *data, bool
|
||||
: ImageDataBase(format, width, height)
|
||||
{
|
||||
if (!validPixelFormat(format))
|
||||
throw love::Exception("Unsupported pixel format for ImageData");
|
||||
throw love::Exception("ImageData does not support the %s pixel format.", getPixelFormatName(format));
|
||||
|
||||
if (own)
|
||||
this->data = (unsigned char *) data;
|
||||
@@ -196,11 +196,7 @@ love::filesystem::FileData *ImageData::encode(FormatHandler::EncodedFormat encod
|
||||
}
|
||||
|
||||
if (encoder == nullptr || encodedimage.data == nullptr)
|
||||
{
|
||||
const char *fname = "unknown";
|
||||
love::getConstant(format, fname);
|
||||
throw love::Exception("No suitable image encoder for %s format.", fname);
|
||||
}
|
||||
throw love::Exception("No suitable image encoder for the %s pixel format.", getPixelFormatName(format));
|
||||
|
||||
love::filesystem::FileData *filedata = nullptr;
|
||||
|
||||
@@ -540,7 +536,7 @@ void ImageData::setPixel(int x, int y, const Colorf &c)
|
||||
Pixel *p = (Pixel *) (data + ((y * width + x) * pixelsize));
|
||||
|
||||
if (pixelSetFunction == nullptr)
|
||||
throw love::Exception("Unhandled pixel format %d in ImageData::setPixel", format);
|
||||
throw love::Exception("ImageData:setPixel does not currently support the %s pixel format.", getPixelFormatName(format));
|
||||
|
||||
Lock lock(mutex);
|
||||
|
||||
@@ -556,7 +552,7 @@ void ImageData::getPixel(int x, int y, Colorf &c) const
|
||||
const Pixel *p = (const Pixel *) (data + ((y * width + x) * pixelsize));
|
||||
|
||||
if (pixelGetFunction == nullptr)
|
||||
throw love::Exception("Unhandled pixel format %d in ImageData::setPixel", format);
|
||||
throw love::Exception("ImageData:getPixel does not currently support the %s pixel format.", getPixelFormatName(format));
|
||||
|
||||
Lock lock(mutex);
|
||||
|
||||
@@ -759,7 +755,7 @@ void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, in
|
||||
else if (srcformat == PIXELFORMAT_RGBA32_FLOAT && dstformat == PIXELFORMAT_RGBA16_FLOAT)
|
||||
pasteRGBA32FtoRGBA16F(rowsrc, rowdst, sw);
|
||||
|
||||
else
|
||||
else if (getfunction != nullptr && setfunction != nullptr)
|
||||
{
|
||||
// Slow path: convert src -> Colorf -> dst.
|
||||
Colorf c;
|
||||
@@ -771,6 +767,10 @@ void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, in
|
||||
setfunction(c, dstp);
|
||||
}
|
||||
}
|
||||
else if (getfunction == nullptr)
|
||||
throw love::Exception("ImageData:paste does not currently support converting from the %s pixel format.", getPixelFormatName(srcformat));
|
||||
else
|
||||
throw love::Exception("ImageData:paste does not currently support converting to the %s pixel format.", getPixelFormatName(dstformat));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -787,45 +787,7 @@ size_t ImageData::getPixelSize() const
|
||||
|
||||
bool ImageData::validPixelFormat(PixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case PIXELFORMAT_R8_UNORM:
|
||||
case PIXELFORMAT_RG8_UNORM:
|
||||
case PIXELFORMAT_RGBA8_UNORM:
|
||||
case PIXELFORMAT_R16_UNORM:
|
||||
case PIXELFORMAT_RG16_UNORM:
|
||||
case PIXELFORMAT_RGBA16_UNORM:
|
||||
case PIXELFORMAT_R16_FLOAT:
|
||||
case PIXELFORMAT_RG16_FLOAT:
|
||||
case PIXELFORMAT_RGBA16_FLOAT:
|
||||
case PIXELFORMAT_R32_FLOAT:
|
||||
case PIXELFORMAT_RG32_FLOAT:
|
||||
case PIXELFORMAT_RGBA32_FLOAT:
|
||||
case PIXELFORMAT_RGBA4_UNORM:
|
||||
case PIXELFORMAT_RGB5A1_UNORM:
|
||||
case PIXELFORMAT_RGB565_UNORM:
|
||||
case PIXELFORMAT_RGB10A2_UNORM:
|
||||
case PIXELFORMAT_RG11B10_FLOAT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageData::canPaste(PixelFormat src, PixelFormat dst)
|
||||
{
|
||||
if (src == dst)
|
||||
return true;
|
||||
|
||||
if (!(src == PIXELFORMAT_RGBA8_UNORM || src == PIXELFORMAT_RGBA16_UNORM
|
||||
|| src == PIXELFORMAT_RGBA16_FLOAT || src == PIXELFORMAT_RGBA32_FLOAT))
|
||||
return false;
|
||||
|
||||
if (!(dst == PIXELFORMAT_RGBA8_UNORM || dst == PIXELFORMAT_RGBA16_UNORM
|
||||
|| dst == PIXELFORMAT_RGBA16_FLOAT || dst == PIXELFORMAT_RGBA32_FLOAT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return isPixelFormatColor(format) && !isPixelFormatCompressed(format);
|
||||
}
|
||||
|
||||
ImageData::PixelSetFunction ImageData::getPixelSetFunction(PixelFormat format)
|
||||
|
||||
@@ -124,7 +124,6 @@ public:
|
||||
PixelGetFunction getPixelGetFunction() const { return pixelGetFunction; }
|
||||
|
||||
static bool validPixelFormat(PixelFormat format);
|
||||
static bool canPaste(PixelFormat src, PixelFormat dst);
|
||||
|
||||
static PixelSetFunction getPixelSetFunction(PixelFormat format);
|
||||
static PixelGetFunction getPixelGetFunction(PixelFormat format);
|
||||
|
||||
@@ -368,9 +368,9 @@ local objectcache = setmetatable({}, {
|
||||
width = width,
|
||||
height = height,
|
||||
format = format,
|
||||
pointer = ffi.cast(conv.pointer, imagedata:getFFIPointer()),
|
||||
tolua = conv.tolua,
|
||||
fromlua = conv.fromlua,
|
||||
pointer = conv == nil and nil or ffi.cast(conv.pointer, imagedata:getFFIPointer()),
|
||||
tolua = conv == nil and nil or conv.tolua,
|
||||
fromlua = conv == nil and nil or conv.fromlua,
|
||||
}
|
||||
|
||||
self[imagedata] = p
|
||||
@@ -395,6 +395,8 @@ function ImageData:_mapPixelUnsafe(func, ix, iy, iw, ih)
|
||||
local p = objectcache[self]
|
||||
local idw, idh = p.width, p.height
|
||||
|
||||
if p.pointer == nil then error("ImageData:mapPixel does not currently support the "..p.format.." pixel format.", 2) end
|
||||
|
||||
ix = floor(ix)
|
||||
iy = floor(iy)
|
||||
iw = floor(iw)
|
||||
@@ -423,6 +425,8 @@ function ImageData:getPixel(x, y)
|
||||
local p = objectcache[self]
|
||||
if not inside(x, y, p.width, p.height) then error("Attempt to get out-of-range pixel!", 2) end
|
||||
|
||||
if p.pointer == nil then error("ImageData:getPixel does not currently support the "..p.format.." pixel format.", 2) end
|
||||
|
||||
ffifuncs.lockMutex(self)
|
||||
local pixel = p.pointer[y * p.width + x]
|
||||
local r, g, b, a = p.tolua(pixel)
|
||||
@@ -451,6 +455,8 @@ function ImageData:setPixel(x, y, r, g, b, a)
|
||||
local p = objectcache[self]
|
||||
if not inside(x, y, p.width, p.height) then error("Attempt to set out-of-range pixel!", 2) end
|
||||
|
||||
if p.pointer == nil then error("ImageData:setPixel does not currently support the "..p.format.." pixel format.", 2) end
|
||||
|
||||
ffifuncs.lockMutex(self)
|
||||
p.fromlua(p.pointer[y * p.width + x], r, g, b, a)
|
||||
ffifuncs.unlockMutex(self)
|
||||
|
||||
Reference in New Issue
Block a user