@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine — Simplex Noise tutorial | |||
// | |||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// © 2013-2014 Guillaume Bittoun <guillaume.bittoun@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
@@ -31,8 +31,8 @@ int main(int argc, char **argv) | |||
srand(time(nullptr)); | |||
/* Create an image */ | |||
Image img(size); | |||
array2d<vec4> &data = img.Lock2D<PixelFormat::RGBA_F32>(); | |||
image img(size); | |||
array2d<vec4> &data = img.lock2d<PixelFormat::RGBA_F32>(); | |||
/* Declare plenty of allocators */ | |||
simplex_noise<2> s2; | |||
@@ -141,7 +141,7 @@ int main(int argc, char **argv) | |||
#endif | |||
/* Save image */ | |||
img.Unlock2D(data); | |||
img.Save("simplex.png"); | |||
img.unlock2d(data); | |||
img.save("simplex.png"); | |||
} | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine — Lua tutorial | |||
// | |||
// Copyright © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||
// Copyright © 2014—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -36,14 +36,14 @@ public: | |||
//------------------------------------------------------------------------- | |||
static int AddFive(lua_State* l) | |||
{ | |||
auto stack = LuaStack::Begin(l); | |||
int32_t i = stack.Get<int32_t>(); | |||
auto stack = LuaStack::Begin(l); | |||
int32_t i = stack.Get<int32_t>(); | |||
i += 5; | |||
return (stack << i).End(); | |||
} | |||
LOLUA_DECLARE_RETURN_METHOD_ARGS(AddTenInstance, GetPtr<DemoObject>(), AddTenMethod, Get<float>(), Get<int32_t>(), Get<int32_t>()); | |||
static int _AddTenInstance(lua_State* l) | |||
{ | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -343,14 +345,14 @@ ivec2 Framebuffer::GetSize() const | |||
return m_data->m_size; | |||
} | |||
Image Framebuffer::GetImage() const | |||
image Framebuffer::GetImage() const | |||
{ | |||
Image ret(m_data->m_size); | |||
image ret(m_data->m_size); | |||
u8vec4 *buffer = ret.Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *buffer = ret.lock<PixelFormat::RGBA_8>(); | |||
glReadPixels(0, 0, m_data->m_size.x, m_data->m_size.y, | |||
GL_RGBA, GL_UNSIGNED_BYTE, buffer); | |||
ret.Unlock(buffer); | |||
ret.unlock(buffer); | |||
return ret; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -39,9 +41,9 @@ ResourceCodecData* DummyImageCodec::Load(char const *path) | |||
if (strcmp("DUMMY", path)) | |||
return nullptr; | |||
auto data = new ResourceImageData(new Image(ivec2(256))); | |||
auto data = new ResourceImageData(new image(ivec2(256))); | |||
auto image = data->m_image; | |||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(), *tmp = pixels; | |||
u8vec4 *pixels = image->lock<PixelFormat::RGBA_8>(), *tmp = pixels; | |||
for (int j = 0; j < 256; j++) | |||
for (int i = 0; i < 256; i++) | |||
{ | |||
@@ -51,7 +53,7 @@ ResourceCodecData* DummyImageCodec::Load(char const *path) | |||
tmp->a = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; | |||
++tmp; | |||
} | |||
image->Unlock(pixels); | |||
image->unlock(pixels); | |||
return data; | |||
} | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -116,13 +116,13 @@ ResourceCodecData* GdiPlusImageCodec::Load(char const *path) | |||
/* FIXME: GDI+ doesn't know about RGBA, only ARGB. And OpenGL doesn't | |||
* know about ARGB, only RGBA. So we swap bytes. We could also fix | |||
* this in the shader. */ | |||
auto data = new ResourceImageData(new Image(ivec2(size))); | |||
auto data = new ResourceImageData(new image(ivec2(size))); | |||
auto image = data->m_image; | |||
u8vec4 *pdst = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *pdst = image->lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *psrc = static_cast<u8vec4 *>(bdata.Scan0); | |||
for (int n = 0; n < size.x * size.y; n++) | |||
pdst[n] = psrc[n].bgra; | |||
image->Unlock(pdst); | |||
image->unlock(pdst); | |||
bitmap->UnlockBits(&bdata); | |||
delete bitmap; | |||
@@ -184,7 +184,7 @@ bool GdiPlusImageCodec::Save(char const *path, ResourceCodecData* data) | |||
} | |||
auto image = data_image->m_image; | |||
ivec2 size = image->GetSize(); | |||
ivec2 size = image->size(); | |||
Gdiplus::Bitmap *b = new Gdiplus::Bitmap(size.x, size.y, | |||
PixelFormat32bppARGB); | |||
@@ -201,13 +201,13 @@ bool GdiPlusImageCodec::Save(char const *path, ResourceCodecData* data) | |||
return false; | |||
} | |||
u8vec4 *psrc = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *psrc = image->lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *psrc0 = psrc; | |||
u8vec4 *pdst = static_cast<u8vec4 *>(bdata.Scan0); | |||
for (int y = 0; y < size.y; y++) | |||
for (int x = 0; x < size.x; x++) | |||
*pdst++ = (*psrc++).bgra; | |||
image->Unlock(psrc0); | |||
image->unlock(psrc0); | |||
b->UnlockBits(&bdata); | |||
if (b->Save(wpath, &clsid, nullptr) != Gdiplus::Ok) | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -74,10 +74,10 @@ ResourceCodecData *Imlib2ImageCodec::Load(char const *path) | |||
} | |||
ivec2 size(imlib_image_get_width(), imlib_image_get_height()); | |||
auto data = new ResourceImageData(new Image(size)); | |||
auto data = new ResourceImageData(new image(size)); | |||
auto image = data->m_image; | |||
u8vec4 *dstdata = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *dstdata = image->lock<PixelFormat::RGBA_8>(); | |||
for (int i = 0; i < size.x * size.y; i++) | |||
{ | |||
@@ -86,7 +86,7 @@ ResourceCodecData *Imlib2ImageCodec::Load(char const *path) | |||
else | |||
dstdata[i] = srcdata[i].bgra; | |||
} | |||
image->Unlock(dstdata); | |||
image->unlock(dstdata); | |||
imlib_free_image(); | |||
@@ -100,13 +100,13 @@ bool Imlib2ImageCodec::Save(char const *path, ResourceCodecData *data) | |||
return false; | |||
auto image = data_image->m_image; | |||
ivec2 size = image->GetSize(); | |||
ivec2 size = image->size(); | |||
Imlib_Image priv = imlib_create_image(size.x, size.y); | |||
imlib_context_set_image(priv); | |||
imlib_image_set_has_alpha(1); | |||
u8vec4 const *srcdata = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 const *srcdata = image->lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *dstdata = (u8vec4 *)imlib_image_get_data(); | |||
for (int i = 0; i < size.x * size.y; i++) | |||
@@ -118,7 +118,7 @@ bool Imlib2ImageCodec::Save(char const *path, ResourceCodecData *data) | |||
} | |||
imlib_image_put_back_data((DATA32 *)dstdata); | |||
image->Unlock(srcdata); | |||
image->unlock(srcdata); | |||
imlib_save_image(path); | |||
imlib_free_image(); | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -36,7 +38,7 @@ public: | |||
private: | |||
static String ReadScreen(char const *name); | |||
static void WriteScreen(Image &image, array<uint8_t> &result); | |||
static void WriteScreen(image &image, array<uint8_t> &result); | |||
}; | |||
DECLARE_IMAGE_CODEC(OricImageCodec, 100) | |||
@@ -63,12 +65,12 @@ ResourceCodecData* OricImageCodec::Load(char const *path) | |||
if (screen.count() == 0) | |||
return nullptr; | |||
auto data = new ResourceImageData(new Image(ivec2(WIDTH, screen.count() * 6 / WIDTH))); | |||
auto image = data->m_image; | |||
auto data = new ResourceImageData(new image(ivec2(WIDTH, screen.count() * 6 / WIDTH))); | |||
auto img = data->m_image; | |||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *pixels = img->lock<PixelFormat::RGBA_8>(); | |||
for (int y = 0; y < image->GetSize().y; y++) | |||
for (int y = 0; y < img->size().y; y++) | |||
{ | |||
u8vec2 bgfg(0, 7); | |||
@@ -101,7 +103,7 @@ ResourceCodecData* OricImageCodec::Load(char const *path) | |||
} | |||
} | |||
image->Unlock(pixels); | |||
img->unlock(pixels); | |||
return data; | |||
} | |||
@@ -129,18 +131,18 @@ bool OricImageCodec::Save(char const *path, ResourceCodecData* data) | |||
result << (uint8_t)name[0]; | |||
result << 0; | |||
auto image = data_image->m_image; | |||
Image tmp; | |||
ivec2 size = image->GetSize(); | |||
auto img = data_image->m_image; | |||
image tmp; | |||
ivec2 size = img->size(); | |||
if (size.x != WIDTH) | |||
{ | |||
size.y = (int)((float)size.y * WIDTH / size.x); | |||
size.x = WIDTH; | |||
tmp = image->Resize(size, ResampleAlgorithm::Bresenham); | |||
image = &tmp; | |||
tmp = img->Resize(size, ResampleAlgorithm::Bresenham); | |||
img = &tmp; | |||
} | |||
WriteScreen(*image, result); | |||
WriteScreen(*img, result); | |||
File f; | |||
f.Open(path, FileAccess::Write); | |||
@@ -469,10 +471,10 @@ static uint8_t bestmove(ivec3 const *in, u8vec2 bgfg, | |||
return bestcommand; | |||
} | |||
void OricImageCodec::WriteScreen(Image &image, array<uint8_t> &result) | |||
void OricImageCodec::WriteScreen(image &img, array<uint8_t> &result) | |||
{ | |||
ivec2 size = image.GetSize(); | |||
vec4 *pixels = image.Lock<PixelFormat::RGBA_F32>(); | |||
ivec2 size = img.size(); | |||
vec4 *pixels = img.lock<PixelFormat::RGBA_F32>(); | |||
int stride = (size.x + 1); | |||
@@ -526,7 +528,7 @@ void OricImageCodec::WriteScreen(Image &image, array<uint8_t> &result) | |||
} | |||
} | |||
image.Unlock(pixels); | |||
img.unlock(pixels); | |||
//fprintf(stderr, " done.\n"); | |||
} | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -75,11 +75,11 @@ ResourceCodecData* SdlImageCodec::Load(char const *path) | |||
surface = tmp; | |||
} | |||
auto data = new ResourceImageData(new Image(size)); | |||
auto data = new ResourceImageData(new image(size)); | |||
auto image = data->m_image; | |||
u8vec4 *pixel_data = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *pixel_data = image->lock<PixelFormat::RGBA_8>(); | |||
memcpy(pixel_data, surface->pixels, 4 * size.x * size.y); | |||
image->Unlock(pixel_data); | |||
image->unlock(pixel_data); | |||
SDL_FreeSurface(surface); | |||
@@ -93,12 +93,12 @@ bool SdlImageCodec::Save(char const *path, ResourceCodecData* data) | |||
return false; | |||
auto image = data_image->m_image; | |||
ivec2 size = image->GetSize(); | |||
ivec2 size = image->size(); | |||
SDL_Surface *surface = Create32BppSurface(size); | |||
u8vec4 *pixel_data = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *pixel_data = image->lock<PixelFormat::RGBA_8>(); | |||
memcpy(surface->pixels, pixel_data, 4 * size.x * size.y); | |||
image->Unlock(pixel_data); | |||
image->unlock(pixel_data); | |||
int ret = SDL_SaveBMP(surface, path); | |||
SDL_FreeSurface(surface); | |||
@@ -1,12 +1,14 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2014 Benjamin Huet <huet.benjamin@gmail.com> | |||
// 2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// 2014 Benjamin Huet <huet.benjamin@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -43,8 +45,8 @@ ResourceCodecData* ZedImageCodec::Load(char const *path) | |||
struct CompactSecondary | |||
{ | |||
CompactSecondary(int32_t size) { m_size = size; } | |||
int32_t m_size; | |||
array<int32_t> m_tiles; | |||
int32_t m_size; | |||
array<int32_t> m_tiles; | |||
}; | |||
struct CompactMain | |||
{ | |||
@@ -108,7 +110,7 @@ ResourceCodecData* ZedImageCodec::Load(char const *path) | |||
file.Open(path, FileAccess::Read, true); | |||
//Put file in memory | |||
long file_size = file.GetSize(); | |||
long file_size = file.size(); | |||
array<uint8_t> file_buffer; | |||
file_buffer.resize(file_size); | |||
file.Read((uint8_t*)&file_buffer[0], file_size); | |||
@@ -227,9 +229,9 @@ ResourceCodecData* ZedImageCodec::Load(char const *path) | |||
tex_size <<= 1; | |||
//Prepare final image | |||
auto data = new ResourceTilesetData(new Image(ivec2(tex_size))); | |||
auto data = new ResourceTilesetData(new image(ivec2(tex_size))); | |||
auto image = data->m_image; | |||
uint8_t *pixels = image->Lock<PixelFormat::Y_8>(); | |||
uint8_t *pixels = image->lock<PixelFormat::Y_8>(); | |||
//Data refactor stage | |||
ivec2 pos = ivec2(0); | |||
@@ -284,7 +286,7 @@ ResourceCodecData* ZedImageCodec::Load(char const *path) | |||
j++; | |||
} | |||
} | |||
image->Unlock(pixels); | |||
image->unlock(pixels); | |||
data->m_tiles = tiles; | |||
@@ -1,11 +1,14 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// 2014 Benjamin Huet <huet.benjamin@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -41,8 +44,8 @@ ResourceCodecData* ZedPaletteImageCodec::Load(char const *path) | |||
File file; | |||
file.Open(path, FileAccess::Read, true); | |||
//Put file in memory | |||
long file_size = file.GetSize(); | |||
// Put file in memory | |||
long file_size = file.size(); | |||
array<uint8_t> file_buffer; | |||
file_buffer.resize(file_size); | |||
file.Read((uint8_t*)&file_buffer[0], file_size); | |||
@@ -53,18 +56,18 @@ ResourceCodecData* ZedPaletteImageCodec::Load(char const *path) | |||
int32_t tex_size = 2; | |||
while (tex_size < tex_sqrt) | |||
tex_size <<= 1; | |||
auto data = new ResourceImageData(new Image(ivec2(tex_size))); | |||
auto data = new ResourceImageData(new image(ivec2(tex_size))); | |||
auto image = data->m_image; | |||
#else | |||
int32_t tex_sqrt = file_size / 3; | |||
int32_t tex_size = 2; | |||
while (tex_size < tex_sqrt) | |||
tex_size <<= 1; | |||
auto data = new ResourceImageData(new Image(ivec2(tex_size, 1))); | |||
auto data = new ResourceImageData(new image(ivec2(tex_size, 1))); | |||
auto image = data->m_image; | |||
#endif | |||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *pixels = image->lock<PixelFormat::RGBA_8>(); | |||
for (int i = 0; i < file_buffer.count();) | |||
{ | |||
pixels->r = file_buffer[i++]; | |||
@@ -73,7 +76,7 @@ ResourceCodecData* ZedPaletteImageCodec::Load(char const *path) | |||
pixels->a = (i == 0) ? 0 : 255; | |||
++pixels; | |||
} | |||
image->Unlock(pixels); | |||
image->unlock(pixels); | |||
return data; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -33,18 +35,18 @@ enum class MergeMode | |||
}; | |||
template<PixelFormat FORMAT, MergeMode MODE> | |||
static image GenericMerge(image &src1, image &src2, float alpha) | |||
static image generic_merge(image &src1, image &src2, float alpha) | |||
{ | |||
typedef typename PixelType<FORMAT>::type pixel_t; | |||
ASSERT(src1.GetSize() == src2.GetSize()); | |||
int const count = src1.GetSize().x * src2.GetSize().y; | |||
ASSERT(src1.size() == src2.size()); | |||
int const count = src1.size().x * src2.size().y; | |||
image dst(src1.GetSize()); | |||
image dst(src1.size()); | |||
pixel_t const *src1p = src1.Lock<FORMAT>(); | |||
pixel_t const *src2p = src2.Lock<FORMAT>(); | |||
pixel_t *dstp = dst.Lock<FORMAT>(); | |||
pixel_t const *src1p = src1.lock<FORMAT>(); | |||
pixel_t const *src2p = src2.lock<FORMAT>(); | |||
pixel_t *dstp = dst.lock<FORMAT>(); | |||
for (int n = 0; n < count; ++n) | |||
{ | |||
@@ -71,80 +73,80 @@ static image GenericMerge(image &src1, image &src2, float alpha) | |||
dstp[n] = lol::abs(src1p[n] - src2p[n]); | |||
} | |||
src1.Unlock(src1p); | |||
src2.Unlock(src2p); | |||
dst.Unlock(dstp); | |||
src1.unlock(src1p); | |||
src2.unlock(src2p); | |||
dst.unlock(dstp); | |||
return dst; | |||
} | |||
template<MergeMode MODE> | |||
static image GenericMerge(image &src1, image &src2, float alpha) | |||
static image generic_merge(image &src1, image &src2, float alpha) | |||
{ | |||
bool gray1 = src1.GetFormat() == PixelFormat::Y_8 | |||
|| src1.GetFormat() == PixelFormat::Y_F32; | |||
bool gray2 = src2.GetFormat() == PixelFormat::Y_8 | |||
|| src2.GetFormat() == PixelFormat::Y_F32; | |||
bool gray1 = src1.format() == PixelFormat::Y_8 | |||
|| src1.format() == PixelFormat::Y_F32; | |||
bool gray2 = src2.format() == PixelFormat::Y_8 | |||
|| src2.format() == PixelFormat::Y_F32; | |||
if (gray1 && gray2) | |||
return GenericMerge<PixelFormat::Y_F32, MODE>(src1, src2, alpha); | |||
return generic_merge<PixelFormat::Y_F32, MODE>(src1, src2, alpha); | |||
else | |||
return GenericMerge<PixelFormat::RGBA_F32, MODE>(src1, src2, alpha); | |||
return generic_merge<PixelFormat::RGBA_F32, MODE>(src1, src2, alpha); | |||
} | |||
image image::Merge(image &src1, image &src2, float alpha) | |||
{ | |||
return GenericMerge<MergeMode::Mix>(src1, src2, alpha); | |||
return generic_merge<MergeMode::Mix>(src1, src2, alpha); | |||
} | |||
image image::Mean(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Mix>(src1, src2, 0.5f); | |||
return generic_merge<MergeMode::Mix>(src1, src2, 0.5f); | |||
} | |||
image image::Min(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Min>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Min>(src1, src2, 0.0f); | |||
} | |||
image image::Max(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Max>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Max>(src1, src2, 0.0f); | |||
} | |||
image image::Overlay(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Overlay>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Overlay>(src1, src2, 0.0f); | |||
} | |||
image image::Screen(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Screen>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Screen>(src1, src2, 0.0f); | |||
} | |||
image image::Divide(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Divide>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Divide>(src1, src2, 0.0f); | |||
} | |||
image image::Multiply(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Multiply>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Multiply>(src1, src2, 0.0f); | |||
} | |||
image image::Add(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Add>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Add>(src1, src2, 0.0f); | |||
} | |||
image image::Sub(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Sub>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Sub>(src1, src2, 0.0f); | |||
} | |||
image image::Difference(image &src1, image &src2) | |||
{ | |||
return GenericMerge<MergeMode::Difference>(src1, src2, 0.0f); | |||
return generic_merge<MergeMode::Difference>(src1, src2, 0.0f); | |||
} | |||
} /* namespace lol */ | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -21,18 +23,18 @@ namespace lol | |||
image image::Crop(ibox2 box) const | |||
{ | |||
ivec2 const srcsize = GetSize(); | |||
ivec2 const srcsize = size(); | |||
ivec2 const dstsize = box.extent(); | |||
image dst(dstsize); | |||
PixelFormat format = GetFormat(); | |||
PixelFormat fmt = format(); | |||
if (format != PixelFormat::Unknown) | |||
if (fmt != PixelFormat::Unknown) | |||
{ | |||
dst.SetFormat(format); | |||
uint8_t const *srcp = (uint8_t const *)m_data->m_pixels[(int)format]; | |||
uint8_t *dstp = (uint8_t *)dst.m_data->m_pixels[(int)format]; | |||
uint8_t bpp = BytesPerPixel(format); | |||
dst.set_format(fmt); | |||
uint8_t const *srcp = (uint8_t const *)m_data->m_pixels[(int)fmt]; | |||
uint8_t *dstp = (uint8_t *)dst.m_data->m_pixels[(int)fmt]; | |||
uint8_t bpp = BytesPerPixel(fmt); | |||
int len = dstsize.x; | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2015 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -24,44 +26,44 @@ namespace lol | |||
/* FIXME: though the algorithm is supposed to stop, we do not have a real, | |||
* guaranteed stop condition here. */ | |||
Image Image::DitherDbs() const | |||
image image::dither_dbs() const | |||
{ | |||
ivec2 size = GetSize(); | |||
ivec2 isize = size(); | |||
/* Build our human visual system kernel. */ | |||
array2d<float> kernel; | |||
kernel.resize(ivec2(NN, NN)); | |||
array2d<float> ker; | |||
ker.resize(ivec2(NN, NN)); | |||
float t = 0.f; | |||
for (int j = 0; j < NN; j++) | |||
for (int i = 0; i < NN; i++) | |||
{ | |||
vec2 v = vec2(i - N, j - N); | |||
kernel[i][j] = exp(-sqlength(v / 1.6f) / 2.f) | |||
+ exp(-sqlength(v / 0.6f) / 2.f); | |||
t += kernel[i][j]; | |||
ker[i][j] = exp(-sqlength(v / 1.6f) / 2.f) | |||
+ exp(-sqlength(v / 0.6f) / 2.f); | |||
t += ker[i][j]; | |||
} | |||
for (int j = 0; j < NN; j++) | |||
for (int i = 0; i < NN; i++) | |||
kernel[i][j] /= t; | |||
ker[i][j] /= t; | |||
/* A list of cells in our picture. If no change is done to a cell | |||
* for two iterations, we stop considering changes to it. */ | |||
ivec2 const csize = (size + ivec2(CELL - 1)) / CELL; | |||
ivec2 const csize = (isize + ivec2(CELL - 1)) / CELL; | |||
array2d<int> changelist(csize); | |||
memset(changelist.data(), 0, changelist.bytes()); | |||
Image dst = *this; | |||
dst.SetFormat(PixelFormat::Y_F32); | |||
image dst = *this; | |||
dst.set_format(PixelFormat::Y_F32); | |||
Image tmp1 = dst.Convolution(kernel); | |||
array2d<float> &tmp1data = tmp1.Lock2D<PixelFormat::Y_F32>(); | |||
image tmp1 = dst.Convolution(ker); | |||
array2d<float> &tmp1data = tmp1.lock2d<PixelFormat::Y_F32>(); | |||
dst = dst.DitherRandom(); | |||
array2d<float> &dstdata = dst.Lock2D<PixelFormat::Y_F32>(); | |||
dst = dst.dither_random(); | |||
array2d<float> &dstdata = dst.lock2d<PixelFormat::Y_F32>(); | |||
Image tmp2 = dst.Convolution(kernel); | |||
array2d<float> &tmp2data = tmp2.Lock2D<PixelFormat::Y_F32>(); | |||
image tmp2 = dst.Convolution(ker); | |||
array2d<float> &tmp2data = tmp2.lock2d<PixelFormat::Y_F32>(); | |||
for (int run = 0, last_change = 0; ; ++run) | |||
{ | |||
@@ -84,7 +86,7 @@ Image Image::DitherDbs() const | |||
ivec2 const pos(cx * CELL + pixel % CELL, | |||
cy * CELL + pixel / CELL); | |||
if (!(pos >= ivec2(0)) || !(pos < size)) | |||
if (!(pos >= ivec2(0)) || !(pos < isize)) | |||
continue; | |||
/* The best operation we can do */ | |||
@@ -103,7 +105,7 @@ Image Image::DitherDbs() const | |||
for (ivec2 const op : op_list) | |||
{ | |||
if (!(pos + op >= ivec2(0)) || !(pos + op < size)) | |||
if (!(pos + op >= ivec2(0)) || !(pos + op < isize)) | |||
continue; | |||
bool flip = (op == ivec2(0)); | |||
@@ -115,9 +117,9 @@ Image Image::DitherDbs() const | |||
/* TODO: implement min/max for 3+ arguments */ | |||
int imin = max(max(-N, op.x - N), -pos.x); | |||
int imax = min(min(N + 1, op.x + NN - N), size.x - pos.x); | |||
int imax = min(min(N + 1, op.x + NN - N), isize.x - pos.x); | |||
int jmin = max(max(-N, op.y - N), -pos.y); | |||
int jmax = min(min(N + 1, op.y + NN - N), size.y - pos.y); | |||
int jmax = min(min(N + 1, op.y + NN - N), isize.y - pos.y); | |||
float error = 0.f; | |||
for (int j = jmin; j < jmax; j++) | |||
@@ -125,9 +127,9 @@ Image Image::DitherDbs() const | |||
{ | |||
ivec2 pos2 = pos + ivec2(i, j); | |||
float m = kernel[i + N][j + N]; | |||
float m = ker[i + N][j + N]; | |||
if (!flip) | |||
m -= kernel[i - op.x + N][j - op.y + N]; | |||
m -= ker[i - op.x + N][j - op.y + N]; | |||
float p = tmp1data[pos2]; | |||
float q1 = tmp2data[pos2]; | |||
float q2 = q1 + m * (d2 - d); | |||
@@ -154,13 +156,13 @@ Image Image::DitherDbs() const | |||
for (int i = -N; i <= N; i++) | |||
{ | |||
ivec2 off(i, j); | |||
float delta = (d2 - d) * kernel[i + N][j + N]; | |||
float delta = (d2 - d) * ker[i + N][j + N]; | |||
if (pos + off >= ivec2(0) && pos + off < size) | |||
if (pos + off >= ivec2(0) && pos + off < isize) | |||
tmp2data[pos + off] += delta; | |||
if (!flip && pos + off + best_op >= ivec2(0) | |||
&& pos + off + best_op < size) | |||
&& pos + off + best_op < isize) | |||
tmp2data[pos + off + best_op] -= delta; | |||
} | |||
@@ -173,9 +175,9 @@ Image Image::DitherDbs() const | |||
++changelist[cx][cy]; | |||
} | |||
tmp1.Unlock2D(tmp1data); | |||
tmp2.Unlock2D(tmp2data); | |||
dst.Unlock2D(dstdata); | |||
tmp1.unlock2d(tmp1data); | |||
tmp2.unlock2d(tmp2data); | |||
dst.unlock2d(dstdata); | |||
return dst; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -23,49 +25,49 @@ namespace lol | |||
* Making the matrix generic is not terribly slower: the performance | |||
* hit is around 4% for Floyd-Steinberg and 13% for JaJuNi, with the | |||
* benefit of a lot less code. */ | |||
Image Image::DitherEdiff(array2d<float> const &kernel, ScanMode scan) const | |||
image image::dither_ediff(array2d<float> const &ker, ScanMode scan) const | |||
{ | |||
Image dst = *this; | |||
image dst = *this; | |||
ivec2 size = dst.GetSize(); | |||
ivec2 ksize = kernel.size(); | |||
ivec2 isize = dst.size(); | |||
ivec2 ksize = ker.size(); | |||
int kx; | |||
for (kx = 0; kx < ksize.x; kx++) | |||
if (kernel[kx][0] > 0.f) | |||
if (ker[kx][0] > 0.f) | |||
break; | |||
float *pixels = dst.Lock<PixelFormat::Y_F32>(); | |||
for (int y = 0; y < size.y; y++) | |||
float *pixels = dst.lock<PixelFormat::Y_F32>(); | |||
for (int y = 0; y < isize.y; y++) | |||
{ | |||
bool reverse = (y & 1) && (scan == ScanMode::Serpentine); | |||
for (int x = 0; x < size.x; x++) | |||
for (int x = 0; x < isize.x; x++) | |||
{ | |||
int x2 = reverse ? size.x - 1 - x : x; | |||
int x2 = reverse ? isize.x - 1 - x : x; | |||
int s = reverse ? -1 : 1; | |||
float p = pixels[y * size.x + x2]; | |||
float p = pixels[y * isize.x + x2]; | |||
float q = p < 0.5f ? 0.f : 1.f; | |||
pixels[y * size.x + x2] = q; | |||
pixels[y * isize.x + x2] = q; | |||
float e = (p - q); | |||
for (int j = 0; j < ksize.y && y < size.y - j; j++) | |||
for (int j = 0; j < ksize.y && y < isize.y - j; j++) | |||
for (int i = 0; i < ksize.x; i++) | |||
{ | |||
if (j == 0 && i <= kx) | |||
continue; | |||
if (x + i - kx < 0 || x + i - kx >= size.x) | |||
if (x + i - kx < 0 || x + i - kx >= isize.x) | |||
continue; | |||
pixels[(y + j) * size.x + x2 + (i - kx) * s] | |||
+= e * kernel[i][j]; | |||
pixels[(y + j) * isize.x + x2 + (i - kx) * s] | |||
+= e * ker[i][j]; | |||
} | |||
} | |||
} | |||
dst.Unlock(pixels); | |||
dst.unlock(pixels); | |||
return dst; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -17,51 +19,51 @@ | |||
namespace lol | |||
{ | |||
static Image DitherHelper(Image const &image, array2d<float> const &kernel, | |||
float scale, float angle); | |||
static image dither_helper(image const &img, array2d<float> const &ker, | |||
float scale, float angle); | |||
Image Image::DitherOrdered(array2d<float> const &kernel) const | |||
image image::dither_ordered(array2d<float> const &ker) const | |||
{ | |||
return DitherHelper(*this, kernel, 1.0f, 0.0f); | |||
return dither_helper(*this, ker, 1.0f, 0.0f); | |||
} | |||
Image Image::DitherHalftone(float radius, float angle) const | |||
image image::dither_halftone(float radius, float angle) const | |||
{ | |||
/* Increasing the precision is necessary or the rotation will look | |||
* like crap. So we create a kernel PRECISION times larger, and ask | |||
* the ditherer to scale it by 1/PRECISION. */ | |||
float const PRECISION = 4.f; | |||
int k = (radius * PRECISION * lol::sqrt(2.f) + 0.5f); | |||
array2d<float> kernel = Image::HalftoneKernel(ivec2(k, k)); | |||
array2d<float> ker = image::kernel::halftone(ivec2(k, k)); | |||
return DitherHelper(*this, kernel, 1.f / PRECISION, angle + F_PI / 4.f); | |||
return dither_helper(*this, ker, 1.f / PRECISION, angle + F_PI / 4.f); | |||
} | |||
static Image DitherHelper(Image const &image, array2d<float> const &kernel, | |||
float scale, float angle) | |||
static image dither_helper(image const &img, array2d<float> const &ker, | |||
float scale, float angle) | |||
{ | |||
ivec2 size = image.GetSize(); | |||
ivec2 ksize = kernel.size(); | |||
ivec2 isize = img.size(); | |||
ivec2 ksize = ker.size(); | |||
float cost = lol::cos(angle); | |||
float sint = lol::sin(angle); | |||
Image ret = image; | |||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||
image ret = img; | |||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||
for (int y = 0; y < size.y; y++) | |||
for (int y = 0; y < isize.y; y++) | |||
{ | |||
for (int x = 0; x < size.x; x++) | |||
for (int x = 0; x < isize.x; x++) | |||
{ | |||
int kx = (int)((cost * x - sint * y + 2 * size.x * size.y) / scale) % ksize.x; | |||
int ky = (int)((cost * y + sint * x + 2 * size.x * size.y) / scale) % ksize.y; | |||
int kx = (int)((cost * x - sint * y + 2 * isize.x * isize.y) / scale) % ksize.x; | |||
int ky = (int)((cost * y + sint * x + 2 * isize.x * isize.y) / scale) % ksize.y; | |||
float p = dstp[y * size.x + x]; | |||
dstp[y * size.x + x] = (p > kernel[kx][ky]) ? 1.f : 0.f; | |||
float p = dstp[y * isize.x + x]; | |||
dstp[y * isize.x + x] = (p > ker[kx][ky]) ? 1.f : 0.f; | |||
} | |||
} | |||
ret.Unlock(dstp); | |||
ret.unlock(dstp); | |||
return ret; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -69,13 +71,13 @@ static inline vec3 GetDiffusion(float v) | |||
return ret; | |||
} | |||
Image Image::DitherOstromoukhov(ScanMode scan) const | |||
image image::dither_ostromoukhov(ScanMode scan) const | |||
{ | |||
Image dst = *this; | |||
image dst = *this; | |||
float *pixels = dst.Lock<PixelFormat::Y_F32>(); | |||
int w = dst.GetSize().x; | |||
int h = dst.GetSize().y; | |||
float *pixels = dst.lock<PixelFormat::Y_F32>(); | |||
int w = dst.size().x; | |||
int h = dst.size().y; | |||
for (int y = 0; y < h; y++) | |||
{ | |||
@@ -103,7 +105,7 @@ Image Image::DitherOstromoukhov(ScanMode scan) const | |||
} | |||
} | |||
dst.Unlock(pixels); | |||
dst.unlock(pixels); | |||
return dst; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -17,19 +19,19 @@ | |||
namespace lol | |||
{ | |||
Image Image::DitherRandom() const | |||
image image::dither_random() const | |||
{ | |||
Image dst = *this; | |||
image dst = *this; | |||
float *pixels = dst.Lock<PixelFormat::Y_F32>(); | |||
int count = GetSize().x * GetSize().y; | |||
float *pixels = dst.lock<PixelFormat::Y_F32>(); | |||
int count = size().x * size().y; | |||
for (int n = 0; n < count; ++n) | |||
{ | |||
pixels[n] = (pixels[n] > lol::rand(0.5f)) ? 1.f : 0.f; | |||
} | |||
dst.Unlock(pixels); | |||
dst.unlock(pixels); | |||
return dst; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -17,34 +19,34 @@ | |||
namespace lol | |||
{ | |||
Image Image::Brightness(float val) const | |||
image image::Brightness(float val) const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = lol::clamp(pixels[n] + val, 0.f, 1.f); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
else | |||
{ | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = vec4(lol::clamp(pixels[n].rgb + vec3(val), 0.f, 1.f), | |||
pixels[n].a); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
return ret; | |||
} | |||
Image Image::Contrast(float val) const | |||
image image::Contrast(float val) const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
if (val >= 0.f) | |||
{ | |||
@@ -58,22 +60,22 @@ Image Image::Contrast(float val) const | |||
val = lol::clamp(1.f + val, 0.f, 1.f); | |||
} | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
float add = -0.5f * val + 0.5f; | |||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = lol::clamp(pixels[n] * val + add, 0.f, 1.f); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
else | |||
{ | |||
vec3 add = vec3(-0.5f * val + 0.5f); | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = vec4(lol::clamp(pixels[n].rgb * val + add, 0.f, 1.f), | |||
pixels[n].a); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
return ret; | |||
@@ -83,16 +85,16 @@ Image Image::Contrast(float val) const | |||
* TODO: the current approach is naive; we should use the histogram in order | |||
* to decide how to change the contrast. | |||
*/ | |||
Image Image::AutoContrast() const | |||
image image::AutoContrast() const | |||
{ | |||
Image ret = *this; | |||
image ret = *this; | |||
float min_val = 1.f, max_val = 0.f; | |||
int count = GetSize().x * GetSize().y; | |||
int count = size().x * size().y; | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
{ | |||
min_val = lol::min(min_val, pixels[n]); | |||
@@ -103,11 +105,11 @@ Image Image::AutoContrast() const | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = (pixels[n] - min_val) * t; | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
else | |||
{ | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
{ | |||
min_val = lol::min(min_val, pixels[n].r); | |||
@@ -125,60 +127,60 @@ Image Image::AutoContrast() const | |||
(pixels[n].b - min_val) * t, | |||
pixels[n].a);; | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
return ret; | |||
} | |||
Image Image::Invert() const | |||
image image::Invert() const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = 1.f - pixels[n]; | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
else | |||
{ | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = vec4(vec3(1.f) -pixels[n].rgb, pixels[n].a); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
} | |||
return ret; | |||
} | |||
Image Image::Threshold(float val) const | |||
image image::Threshold(float val) const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = pixels[n] > val ? 1.f : 0.f; | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
return ret; | |||
} | |||
Image Image::Threshold(vec3 val) const | |||
image image::Threshold(vec3 val) const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = vec4(pixels[n].r > val.r ? 1.f : 0.f, | |||
pixels[n].g > val.g ? 1.f : 0.f, | |||
pixels[n].b > val.b ? 1.f : 0.f, | |||
pixels[n].a); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
return ret; | |||
} | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -17,21 +19,21 @@ | |||
namespace lol | |||
{ | |||
static Image SepConv(Image &src, array<float> const &hvec, | |||
static image SepConv(image &src, array<float> const &hvec, | |||
array<float> const &vvec); | |||
static Image NonSepConv(Image &src, array2d<float> const &kernel); | |||
static image NonSepConv(image &src, array2d<float> const &in_kernel); | |||
Image Image::Convolution(array2d<float> const &kernel) | |||
image image::Convolution(array2d<float> const &in_kernel) | |||
{ | |||
/* Find the cell with the largest value */ | |||
ivec2 ksize = kernel.size(); | |||
ivec2 ksize = in_kernel.size(); | |||
int bestx = -1, besty = -1; | |||
float tmp = 0.f; | |||
for (int dy = 0; dy < ksize.y; ++dy) | |||
for (int dx = 0; dx < ksize.x; ++dx) | |||
if (lol::sq(kernel[dx][dy]) > tmp) | |||
if (lol::sq(in_kernel[dx][dy]) > tmp) | |||
{ | |||
tmp = sq(kernel[dx][dy]); | |||
tmp = sq(in_kernel[dx][dy]); | |||
bestx = dx; | |||
besty = dy; | |||
} | |||
@@ -52,8 +54,8 @@ Image Image::Convolution(array2d<float> const &kernel) | |||
if (dx == bestx) | |||
continue; | |||
float p = kernel[dx][dy] * kernel[bestx][besty]; | |||
float q = kernel[dx][besty] * kernel[bestx][dy]; | |||
float p = in_kernel[dx][dy] * in_kernel[bestx][besty]; | |||
float q = in_kernel[dx][besty] * in_kernel[bestx][dy]; | |||
if (lol::abs(p - q) > 1.0e-8f) | |||
separable = false; | |||
@@ -65,29 +67,29 @@ Image Image::Convolution(array2d<float> const &kernel) | |||
/* Matrix rank is 1! Separate the filter. */ | |||
array<float> hvec, vvec; | |||
float norm = 1.0f / lol::sqrt(lol::abs(kernel[bestx][besty])); | |||
float norm = 1.0f / lol::sqrt(lol::abs(in_kernel[bestx][besty])); | |||
for (int dx = 0; dx < ksize.x; dx++) | |||
hvec << norm * kernel[dx][besty]; | |||
hvec << norm * in_kernel[dx][besty]; | |||
for (int dy = 0; dy < ksize.y; dy++) | |||
vvec << norm * kernel[bestx][dy]; | |||
vvec << norm * in_kernel[bestx][dy]; | |||
return SepConv(*this, hvec, vvec); | |||
} | |||
else | |||
{ | |||
return NonSepConv(*this, kernel); | |||
return NonSepConv(*this, in_kernel); | |||
} | |||
} | |||
Image Image::Sharpen(array2d<float> const &kernel) | |||
image image::Sharpen(array2d<float> const &in_kernel) | |||
{ | |||
ivec2 ksize = kernel.size(); | |||
ivec2 ksize = in_kernel.size(); | |||
array2d<float> newkernel(ksize); | |||
for (int dy = 0; dy < ksize.y; ++dy) | |||
for (int dx = 0; dx < ksize.x; ++dx) | |||
{ | |||
newkernel[dx][dy] = - kernel[dx][dy]; | |||
newkernel[dx][dy] = - in_kernel[dx][dy]; | |||
if (dx == ksize.x / 2 && dy == ksize.y / 2) | |||
newkernel[dx][dy] += 2.f; | |||
} | |||
@@ -96,16 +98,16 @@ Image Image::Sharpen(array2d<float> const &kernel) | |||
} | |||
template<PixelFormat FORMAT, int WRAP_X, int WRAP_Y> | |||
static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||
static image NonSepConv(image &src, array2d<float> const &in_kernel) | |||
{ | |||
typedef typename PixelType<FORMAT>::type pixel_t; | |||
ivec2 const size = src.GetSize(); | |||
ivec2 const ksize = kernel.size(); | |||
Image dst(size); | |||
ivec2 const size = src.size(); | |||
ivec2 const ksize = in_kernel.size(); | |||
image dst(size); | |||
array2d<pixel_t> const &srcp = src.Lock2D<FORMAT>(); | |||
array2d<pixel_t> &dstp = dst.Lock2D<FORMAT>(); | |||
array2d<pixel_t> const &srcp = src.lock2d<FORMAT>(); | |||
array2d<pixel_t> &dstp = dst.lock2d<FORMAT>(); | |||
for (int y = 0; y < size.y; y++) | |||
{ | |||
@@ -123,7 +125,7 @@ static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||
for (int dx = 0; dx < ksize.x; dx++) | |||
{ | |||
float f = kernel[dx][dy]; | |||
float f = in_kernel[dx][dy]; | |||
int x2 = x + dx - ksize.x / 2; | |||
if (x2 < 0) | |||
@@ -139,33 +141,33 @@ static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||
} | |||
} | |||
src.Unlock2D(srcp); | |||
dst.Unlock2D(dstp); | |||
src.unlock2d(srcp); | |||
dst.unlock2d(dstp); | |||
return dst; | |||
} | |||
static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||
static image NonSepConv(image &src, array2d<float> const &in_kernel) | |||
{ | |||
bool const wrap_x = src.GetWrapX() == WrapMode::Repeat; | |||
bool const wrap_y = src.GetWrapY() == WrapMode::Repeat; | |||
if (src.GetFormat() == PixelFormat::Y_8 | |||
|| src.GetFormat() == PixelFormat::Y_F32) | |||
if (src.format() == PixelFormat::Y_8 | |||
|| src.format() == PixelFormat::Y_F32) | |||
{ | |||
if (wrap_x) | |||
{ | |||
if (wrap_y) | |||
return NonSepConv<PixelFormat::Y_F32, 1, 1>(src, kernel); | |||
return NonSepConv<PixelFormat::Y_F32, 1, 1>(src, in_kernel); | |||
else | |||
return NonSepConv<PixelFormat::Y_F32, 1, 0>(src, kernel); | |||
return NonSepConv<PixelFormat::Y_F32, 1, 0>(src, in_kernel); | |||
} | |||
else | |||
{ | |||
if (wrap_y) | |||
return NonSepConv<PixelFormat::Y_F32, 0, 1>(src, kernel); | |||
return NonSepConv<PixelFormat::Y_F32, 0, 1>(src, in_kernel); | |||
else | |||
return NonSepConv<PixelFormat::Y_F32, 0, 0>(src, kernel); | |||
return NonSepConv<PixelFormat::Y_F32, 0, 0>(src, in_kernel); | |||
} | |||
} | |||
else | |||
@@ -173,32 +175,32 @@ static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||
if (wrap_x) | |||
{ | |||
if (wrap_y) | |||
return NonSepConv<PixelFormat::RGBA_F32, 1, 1>(src, kernel); | |||
return NonSepConv<PixelFormat::RGBA_F32, 1, 1>(src, in_kernel); | |||
else | |||
return NonSepConv<PixelFormat::RGBA_F32, 1, 0>(src, kernel); | |||
return NonSepConv<PixelFormat::RGBA_F32, 1, 0>(src, in_kernel); | |||
} | |||
else | |||
{ | |||
if (wrap_y) | |||
return NonSepConv<PixelFormat::RGBA_F32, 0, 1>(src, kernel); | |||
return NonSepConv<PixelFormat::RGBA_F32, 0, 1>(src, in_kernel); | |||
else | |||
return NonSepConv<PixelFormat::RGBA_F32, 0, 0>(src, kernel); | |||
return NonSepConv<PixelFormat::RGBA_F32, 0, 0>(src, in_kernel); | |||
} | |||
} | |||
} | |||
template<PixelFormat FORMAT, int WRAP_X, int WRAP_Y> | |||
static Image SepConv(Image &src, array<float> const &hvec, | |||
static image SepConv(image &src, array<float> const &hvec, | |||
array<float> const &vvec) | |||
{ | |||
typedef typename PixelType<FORMAT>::type pixel_t; | |||
ivec2 const size = src.GetSize(); | |||
ivec2 const size = src.size(); | |||
ivec2 const ksize(hvec.count(), vvec.count()); | |||
Image dst(size); | |||
image dst(size); | |||
array2d<pixel_t> const &srcp = src.Lock2D<FORMAT>(); | |||
array2d<pixel_t> &dstp = dst.Lock2D<FORMAT>(); | |||
array2d<pixel_t> const &srcp = src.lock2d<FORMAT>(); | |||
array2d<pixel_t> &dstp = dst.lock2d<FORMAT>(); | |||
array2d<pixel_t> tmp(size); | |||
@@ -244,20 +246,20 @@ static Image SepConv(Image &src, array<float> const &hvec, | |||
} | |||
} | |||
src.Unlock2D(srcp); | |||
dst.Unlock2D(dstp); | |||
src.unlock2d(srcp); | |||
dst.unlock2d(dstp); | |||
return dst; | |||
} | |||
static Image SepConv(Image &src, array<float> const &hvec, | |||
static image SepConv(image &src, array<float> const &hvec, | |||
array<float> const &vvec) | |||
{ | |||
bool const wrap_x = src.GetWrapX() == WrapMode::Repeat; | |||
bool const wrap_y = src.GetWrapY() == WrapMode::Repeat; | |||
if (src.GetFormat() == PixelFormat::Y_8 | |||
|| src.GetFormat() == PixelFormat::Y_F32) | |||
if (src.format() == PixelFormat::Y_8 | |||
|| src.format() == PixelFormat::Y_F32) | |||
{ | |||
if (wrap_x) | |||
{ | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -22,115 +24,115 @@ | |||
namespace lol | |||
{ | |||
Image Image::Dilate() | |||
image image::Dilate() | |||
{ | |||
ivec2 const size = GetSize(); | |||
Image ret(size); | |||
ivec2 isize = size(); | |||
image ret(isize); | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
float const *srcp = Lock<PixelFormat::Y_F32>(); | |||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||
float const *srcp = lock<PixelFormat::Y_F32>(); | |||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||
for (int y = 0; y < size.y; ++y) | |||
for (int x = 0; x < size.x; ++x) | |||
for (int y = 0; y < isize.y; ++y) | |||
for (int x = 0; x < isize.x; ++x) | |||
{ | |||
int y2 = lol::max(y - 1, 0); | |||
int x2 = lol::max(x - 1, 0); | |||
int y3 = lol::min(y + 1, size.y - 1); | |||
int x3 = lol::min(x + 1, size.x - 1); | |||
float t = srcp[y * size.x + x]; | |||
t = lol::max(t, srcp[y * size.x + x2]); | |||
t = lol::max(t, srcp[y * size.x + x3]); | |||
t = lol::max(t, srcp[y2 * size.x + x]); | |||
t = lol::max(t, srcp[y3 * size.x + x]); | |||
dstp[y * size.x + x] = t; | |||
int y3 = lol::min(y + 1, isize.y - 1); | |||
int x3 = lol::min(x + 1, isize.x - 1); | |||
float t = srcp[y * isize.x + x]; | |||
t = lol::max(t, srcp[y * isize.x + x2]); | |||
t = lol::max(t, srcp[y * isize.x + x3]); | |||
t = lol::max(t, srcp[y2 * isize.x + x]); | |||
t = lol::max(t, srcp[y3 * isize.x + x]); | |||
dstp[y * isize.x + x] = t; | |||
} | |||
Unlock(srcp); | |||
ret.Unlock(dstp); | |||
unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
else | |||
{ | |||
vec4 const *srcp = Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 const *srcp = lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int y = 0; y < size.y; ++y) | |||
for (int x = 0; x < size.x; ++x) | |||
for (int y = 0; y < isize.y; ++y) | |||
for (int x = 0; x < isize.x; ++x) | |||
{ | |||
int y2 = lol::max(y - 1, 0); | |||
int x2 = lol::max(x - 1, 0); | |||
int y3 = lol::min(y + 1, size.y - 1); | |||
int x3 = lol::min(x + 1, size.x - 1); | |||
vec3 t = srcp[y * size.x + x].rgb; | |||
t = lol::max(t, srcp[y * size.x + x2].rgb); | |||
t = lol::max(t, srcp[y * size.x + x3].rgb); | |||
t = lol::max(t, srcp[y2 * size.x + x].rgb); | |||
t = lol::max(t, srcp[y3 * size.x + x].rgb); | |||
dstp[y * size.x + x] = vec4(t, srcp[y * size.x + x].a); | |||
int y3 = lol::min(y + 1, isize.y - 1); | |||
int x3 = lol::min(x + 1, isize.x - 1); | |||
vec3 t = srcp[y * isize.x + x].rgb; | |||
t = lol::max(t, srcp[y * isize.x + x2].rgb); | |||
t = lol::max(t, srcp[y * isize.x + x3].rgb); | |||
t = lol::max(t, srcp[y2 * isize.x + x].rgb); | |||
t = lol::max(t, srcp[y3 * isize.x + x].rgb); | |||
dstp[y * isize.x + x] = vec4(t, srcp[y * isize.x + x].a); | |||
} | |||
Unlock(srcp); | |||
ret.Unlock(dstp); | |||
unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
return ret; | |||
} | |||
Image Image::Erode() | |||
image image::Erode() | |||
{ | |||
ivec2 const size = GetSize(); | |||
Image ret(size); | |||
ivec2 isize = size(); | |||
image ret(isize); | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
float const *srcp = Lock<PixelFormat::Y_F32>(); | |||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||
float const *srcp = lock<PixelFormat::Y_F32>(); | |||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||
for (int y = 0; y < size.y; ++y) | |||
for (int x = 0; x < size.x; ++x) | |||
for (int y = 0; y < isize.y; ++y) | |||
for (int x = 0; x < isize.x; ++x) | |||
{ | |||
int y2 = lol::max(y - 1, 0); | |||
int x2 = lol::max(x - 1, 0); | |||
int y3 = lol::min(y + 1, size.y - 1); | |||
int x3 = lol::min(x + 1, size.x - 1); | |||
float t = srcp[y * size.x + x]; | |||
t = lol::max(t, srcp[y * size.x + x2]); | |||
t = lol::max(t, srcp[y * size.x + x3]); | |||
t = lol::max(t, srcp[y2 * size.x + x]); | |||
t = lol::max(t, srcp[y3 * size.x + x]); | |||
dstp[y * size.x + x] = t; | |||
int y3 = lol::min(y + 1, isize.y - 1); | |||
int x3 = lol::min(x + 1, isize.x - 1); | |||
float t = srcp[y * isize.x + x]; | |||
t = lol::max(t, srcp[y * isize.x + x2]); | |||
t = lol::max(t, srcp[y * isize.x + x3]); | |||
t = lol::max(t, srcp[y2 * isize.x + x]); | |||
t = lol::max(t, srcp[y3 * isize.x + x]); | |||
dstp[y * isize.x + x] = t; | |||
} | |||
Unlock(srcp); | |||
ret.Unlock(dstp); | |||
unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
else | |||
{ | |||
vec4 const *srcp = Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 const *srcp = lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int y = 0; y < size.y; ++y) | |||
for (int x = 0; x < size.x; ++x) | |||
for (int y = 0; y < isize.y; ++y) | |||
for (int x = 0; x < isize.x; ++x) | |||
{ | |||
int y2 = lol::max(y - 1, 0); | |||
int x2 = lol::max(x - 1, 0); | |||
int y3 = lol::min(y + 1, size.y - 1); | |||
int x3 = lol::min(x + 1, size.x - 1); | |||
vec3 t = srcp[y * size.x + x].rgb; | |||
t = lol::min(t, srcp[y * size.x + x2].rgb); | |||
t = lol::min(t, srcp[y * size.x + x3].rgb); | |||
t = lol::min(t, srcp[y2 * size.x + x].rgb); | |||
t = lol::min(t, srcp[y3 * size.x + x].rgb); | |||
dstp[y * size.x + x] = vec4(t, srcp[y * size.x + x].a); | |||
int y3 = lol::min(y + 1, isize.y - 1); | |||
int x3 = lol::min(x + 1, isize.x - 1); | |||
vec3 t = srcp[y * isize.x + x].rgb; | |||
t = lol::min(t, srcp[y * isize.x + x2].rgb); | |||
t = lol::min(t, srcp[y * isize.x + x3].rgb); | |||
t = lol::min(t, srcp[y2 * isize.x + x].rgb); | |||
t = lol::min(t, srcp[y3 * isize.x + x].rgb); | |||
dstp[y * isize.x + x] = vec4(t, srcp[y * isize.x + x].a); | |||
} | |||
Unlock(srcp); | |||
ret.Unlock(dstp); | |||
unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
return ret; | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -33,38 +35,38 @@ static int cmpfloat(void const *i1, void const *i2) | |||
return (a > b) - (a < b); | |||
} | |||
Image Image::Median(ivec2 ksize) const | |||
image image::Median(ivec2 ksize) const | |||
{ | |||
ivec2 const size = GetSize(); | |||
Image tmp = *this; | |||
Image ret(size); | |||
ivec2 const isize = size(); | |||
image tmp = *this; | |||
image ret(isize); | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
ivec2 const lsize = 2 * ksize + ivec2(1); | |||
array2d<float> list(lsize); | |||
float *srcp = tmp.Lock<PixelFormat::Y_F32>(); | |||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||
float *srcp = tmp.lock<PixelFormat::Y_F32>(); | |||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||
for (int y = 0; y < size.y; y++) | |||
for (int y = 0; y < isize.y; y++) | |||
{ | |||
for (int x = 0; x < size.x; x++) | |||
for (int x = 0; x < isize.x; x++) | |||
{ | |||
/* Make a list of neighbours */ | |||
for (int j = -ksize.y; j <= ksize.y; j++) | |||
{ | |||
int y2 = y + j; | |||
if (y2 < 0) y2 = size.y - 1 - ((-y2 - 1) % size.y); | |||
else if (y2 > 0) y2 = y2 % size.y; | |||
if (y2 < 0) y2 = isize.y - 1 - ((-y2 - 1) % isize.y); | |||
else if (y2 > 0) y2 = y2 % isize.y; | |||
for (int i = -ksize.x; i <= ksize.x; i++) | |||
{ | |||
int x2 = x + i; | |||
if (x2 < 0) x2 = size.x - 1 - ((-x2 - 1) % size.x); | |||
else if (x2 > 0) x2 = x2 % size.x; | |||
if (x2 < 0) x2 = isize.x - 1 - ((-x2 - 1) % isize.x); | |||
else if (x2 > 0) x2 = x2 % isize.x; | |||
list[i + ksize.x][j + ksize.y] = srcp[y2 * size.x + x2]; | |||
list[i + ksize.x][j + ksize.y] = srcp[y2 * isize.x + x2]; | |||
} | |||
} | |||
@@ -72,39 +74,39 @@ Image Image::Median(ivec2 ksize) const | |||
qsort(&list[0][0], lsize.x * lsize.y, sizeof(float), cmpfloat); | |||
/* Store the median value */ | |||
dstp[y * size.x + x] = *(&list[0][0] + lsize.x * lsize.y / 2); | |||
dstp[y * isize.x + x] = *(&list[0][0] + lsize.x * lsize.y / 2); | |||
} | |||
} | |||
tmp.Unlock(srcp); | |||
ret.Unlock(dstp); | |||
tmp.unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
else | |||
{ | |||
ivec2 const lsize = 2 * ksize + ivec2(1); | |||
array2d<vec3> list(lsize); | |||
vec4 *srcp = tmp.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *srcp = tmp.lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int y = 0; y < size.y; y++) | |||
for (int y = 0; y < isize.y; y++) | |||
{ | |||
for (int x = 0; x < size.x; x++) | |||
for (int x = 0; x < isize.x; x++) | |||
{ | |||
/* Make a list of neighbours */ | |||
for (int j = -ksize.y; j <= ksize.y; j++) | |||
{ | |||
int y2 = y + j; | |||
if (y2 < 0) y2 = size.y - 1 - ((-y2 - 1) % size.y); | |||
else if (y2 > 0) y2 = y2 % size.y; | |||
if (y2 < 0) y2 = isize.y - 1 - ((-y2 - 1) % isize.y); | |||
else if (y2 > 0) y2 = y2 % isize.y; | |||
for (int i = -ksize.x; i <= ksize.x; i++) | |||
{ | |||
int x2 = x + i; | |||
if (x2 < 0) x2 = size.x - 1 - ((-x2 - 1) % size.x); | |||
else if (x2 > 0) x2 = x2 % size.x; | |||
if (x2 < 0) x2 = isize.x - 1 - ((-x2 - 1) % isize.x); | |||
else if (x2 > 0) x2 = x2 % isize.x; | |||
list[i + ksize.x][j + ksize.y] = srcp[y2 * size.x + x2].rgb; | |||
list[i + ksize.x][j + ksize.y] = srcp[y2 * isize.x + x2].rgb; | |||
} | |||
} | |||
@@ -139,26 +141,26 @@ Image Image::Median(ivec2 ksize) const | |||
} | |||
/* Store the median value */ | |||
dstp[y * size.x + x] = vec4(median, srcp[y * size.x + x].a); | |||
dstp[y * isize.x + x] = vec4(median, srcp[y * isize.x + x].a); | |||
} | |||
} | |||
tmp.Unlock(srcp); | |||
ret.Unlock(dstp); | |||
tmp.unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
return ret; | |||
} | |||
Image Image::Median(array2d<float> const &kernel) const | |||
image image::Median(array2d<float> const &kernel) const | |||
{ | |||
ivec2 const size = GetSize(); | |||
Image tmp = *this; | |||
Image ret(size); | |||
ivec2 const isize = size(); | |||
image tmp = *this; | |||
image ret(isize); | |||
/* FIXME: TODO */ | |||
#if 0 | |||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||
{ | |||
} | |||
else | |||
@@ -167,27 +169,27 @@ Image Image::Median(array2d<float> const &kernel) const | |||
ivec2 const ksize = kernel.size(); | |||
array2d<vec3> list(ksize); | |||
vec4 *srcp = tmp.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *srcp = tmp.lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int y = 0; y < size.y; y++) | |||
for (int y = 0; y < isize.y; y++) | |||
{ | |||
for (int x = 0; x < size.x; x++) | |||
for (int x = 0; x < isize.x; x++) | |||
{ | |||
/* Make a list of neighbours */ | |||
for (int j = 0; j < ksize.y; j++) | |||
{ | |||
int y2 = y + j - ksize.y / 2; | |||
if (y2 < 0) y2 = size.y - 1 - ((-y2 - 1) % size.y); | |||
else if (y2 > 0) y2 = y2 % size.y; | |||
if (y2 < 0) y2 = isize.y - 1 - ((-y2 - 1) % isize.y); | |||
else if (y2 > 0) y2 = y2 % isize.y; | |||
for (int i = 0; i < ksize.x; i++) | |||
{ | |||
int x2 = x + i - ksize.x / 2; | |||
if (x2 < 0) x2 = size.x - 1 - ((-x2 - 1) % size.x); | |||
else if (x2 > 0) x2 = x2 % size.x; | |||
if (x2 < 0) x2 = isize.x - 1 - ((-x2 - 1) % isize.x); | |||
else if (x2 > 0) x2 = x2 % isize.x; | |||
list[i][j] = srcp[y2 * size.x + x2].rgb; | |||
list[i][j] = srcp[y2 * isize.x + x2].rgb; | |||
} | |||
} | |||
@@ -222,12 +224,12 @@ Image Image::Median(array2d<float> const &kernel) const | |||
} | |||
/* Store the median value */ | |||
dstp[y * size.x + x] = vec4(median, srcp[y * size.x + x].a); | |||
dstp[y * isize.x + x] = vec4(median, srcp[y * isize.x + x].a); | |||
} | |||
} | |||
tmp.Unlock(srcp); | |||
ret.Unlock(dstp); | |||
tmp.unlock(srcp); | |||
ret.unlock(dstp); | |||
} | |||
return ret; | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -17,28 +19,28 @@ | |||
namespace lol | |||
{ | |||
Image Image::YUVToRGB() const | |||
image image::YUVToRGB() const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = Color::YUVToRGB(pixels[n]); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
return ret; | |||
} | |||
Image Image::RGBToYUV() const | |||
image image::RGBToYUV() const | |||
{ | |||
Image ret = *this; | |||
int count = GetSize().x * GetSize().y; | |||
image ret = *this; | |||
int count = size().x * size().y; | |||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < count; ++n) | |||
pixels[n] = Color::RGBToYUV(pixels[n]); | |||
ret.Unlock(pixels); | |||
ret.unlock(pixels); | |||
return ret; | |||
} | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -20,7 +20,7 @@ namespace lol | |||
{ | |||
/* | |||
* Public Image class | |||
* Public image class | |||
*/ | |||
image::image() | |||
@@ -31,13 +31,13 @@ image::image() | |||
image::image(char const *path) | |||
: m_data(new image_data()) | |||
{ | |||
Load(path); | |||
load(path); | |||
} | |||
image::image(ivec2 size) | |||
: m_data(new image_data()) | |||
{ | |||
SetSize(size); | |||
resize(size); | |||
} | |||
image::image (image const &other) | |||
@@ -65,21 +65,21 @@ image::~image() | |||
void image::Copy(uint8_t* src_pixels, ivec2 const& size, PixelFormat fmt) | |||
{ | |||
ASSERT(fmt != PixelFormat::Unknown); | |||
SetSize(size); | |||
SetFormat(fmt); | |||
resize(size); | |||
set_format(fmt); | |||
memcpy(m_data->m_pixels[(int)fmt]->data(), src_pixels, | |||
size.x * size.y * BytesPerPixel(fmt)); | |||
} | |||
void image::Copy(image const &src) | |||
{ | |||
ivec2 size = src.GetSize(); | |||
PixelFormat fmt = src.GetFormat(); | |||
ivec2 size = src.size(); | |||
PixelFormat fmt = src.format(); | |||
SetSize(size); | |||
resize(size); | |||
if (fmt != PixelFormat::Unknown) | |||
{ | |||
SetFormat(fmt); | |||
set_format(fmt); | |||
memcpy(m_data->m_pixels[(int)fmt]->data(), | |||
src.m_data->m_pixels[(int)fmt]->data(), | |||
size.x * size.y * BytesPerPixel(fmt)); | |||
@@ -88,10 +88,10 @@ void image::Copy(image const &src) | |||
void image::DummyFill() | |||
{ | |||
Load("DUMMY"); | |||
load("DUMMY"); | |||
} | |||
bool image::Load(char const *path) | |||
bool image::load(char const *path) | |||
{ | |||
auto resource = ResourceLoader::Load(path); | |||
if (resource == nullptr) | |||
@@ -109,7 +109,7 @@ bool image::Load(char const *path) | |||
return true; | |||
} | |||
bool image::Save(char const *path) | |||
bool image::save(char const *path) | |||
{ | |||
auto data = new ResourceImageData(new image(*this)); | |||
auto result = ResourceLoader::Save(path, data); | |||
@@ -117,12 +117,12 @@ bool image::Save(char const *path) | |||
return result; | |||
} | |||
ivec2 image::GetSize() const | |||
ivec2 image::size() const | |||
{ | |||
return m_data->m_size; | |||
} | |||
void image::SetSize(ivec2 size) | |||
void image::resize(ivec2 size) | |||
{ | |||
ASSERT(size.x > 0); | |||
ASSERT(size.y > 0); | |||
@@ -158,24 +158,24 @@ void image::SetWrap(WrapMode wrap_x, WrapMode wrap_y) | |||
m_data->m_wrap_y = wrap_y; | |||
} | |||
/* The Lock() method */ | |||
template<PixelFormat T> typename PixelType<T>::type *image::Lock() | |||
/* The lock() method */ | |||
template<PixelFormat T> typename PixelType<T>::type *image::lock() | |||
{ | |||
SetFormat(T); | |||
set_format(T); | |||
return (typename PixelType<T>::type *)m_data->m_pixels[(int)T]->data(); | |||
} | |||
/* The Lock2D() method */ | |||
void *image::Lock2DHelper(PixelFormat T) | |||
/* The lock2d() method */ | |||
void *image::lock2d_helper(PixelFormat T) | |||
{ | |||
SetFormat(T); | |||
set_format(T); | |||
return m_data->m_pixels[(int)T]->data2d(); | |||
} | |||
template<typename T> | |||
void image::Unlock2D(array2d<T> const &array) | |||
void image::unlock2d(array2d<T> const &array) | |||
{ | |||
ASSERT(m_data->m_pixels.has_key((int)m_data->m_format)); | |||
ASSERT(array.data() == m_data->m_pixels[(int)m_data->m_format]->data()); | |||
@@ -183,9 +183,9 @@ void image::Unlock2D(array2d<T> const &array) | |||
/* Explicit specialisations for the above templates */ | |||
#define _T(T) \ | |||
template PixelType<T>::type *image::Lock<T>(); \ | |||
template array2d<PixelType<T>::type> &image::Lock2D<T>(); \ | |||
template void image::Unlock2D(array2d<PixelType<T>::type> const &array); | |||
template PixelType<T>::type *image::lock<T>(); \ | |||
template array2d<PixelType<T>::type> &image::lock2d<T>(); \ | |||
template void image::unlock2d(array2d<PixelType<T>::type> const &array); | |||
_T(PixelFormat::Y_8) | |||
_T(PixelFormat::RGB_8) | |||
_T(PixelFormat::RGBA_8) | |||
@@ -195,14 +195,14 @@ _T(PixelFormat::RGBA_F32) | |||
#undef _T | |||
/* Special case for the "any" format: return the last active buffer */ | |||
void *image::Lock() | |||
void *image::lock() | |||
{ | |||
ASSERT(m_data->m_format != PixelFormat::Unknown); | |||
return m_data->m_pixels[(int)m_data->m_format]->data(); | |||
} | |||
void image::Unlock(void const *pixels) | |||
void image::unlock(void const *pixels) | |||
{ | |||
ASSERT(m_data->m_pixels.has_key((int)m_data->m_format)); | |||
ASSERT(pixels == m_data->m_pixels[(int)m_data->m_format]->data()); | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -17,7 +19,7 @@ | |||
namespace lol | |||
{ | |||
array2d<float> image::BayerKernel(ivec2 size) | |||
array2d<float> image::kernel::bayer(ivec2 size) | |||
{ | |||
array2d<float> ret(size); | |||
@@ -46,7 +48,7 @@ array2d<float> image::BayerKernel(ivec2 size) | |||
return ret; | |||
} | |||
array2d<float> image::HalftoneKernel(ivec2 size) | |||
array2d<float> image::kernel::halftone(ivec2 size) | |||
{ | |||
array2d<float> ret(size); | |||
@@ -72,10 +74,10 @@ array2d<float> image::HalftoneKernel(ivec2 size) | |||
ret[x][y] = flip ? 10.f - r : r; | |||
} | |||
return NormalizeKernel(ret); | |||
return normalize(ret); | |||
} | |||
array2d<float> image::BlueNoiseKernel(ivec2 size, ivec2 gsize) | |||
array2d<float> image::kernel::blue_noise(ivec2 size, ivec2 gsize) | |||
{ | |||
float const epsilon = 1.f / (size.x * size.y + 1); | |||
gsize = lol::min(size, gsize); | |||
@@ -180,7 +182,7 @@ static int cmpdot(const void *p1, const void *p2) | |||
return ((Dot const *)p1)->val > ((Dot const *)p2)->val; | |||
} | |||
array2d<float> image::NormalizeKernel(array2d<float> const &kernel) | |||
array2d<float> image::kernel::normalize(array2d<float> const &kernel) | |||
{ | |||
ivec2 size = kernel.size(); | |||
@@ -209,7 +211,7 @@ array2d<float> image::NormalizeKernel(array2d<float> const &kernel) | |||
return dst; | |||
} | |||
array2d<float> image::EdiffKernel(EdiffAlgorithm algorithm) | |||
array2d<float> image::kernel::ediff(EdiffAlgorithm algorithm) | |||
{ | |||
switch (algorithm) | |||
{ | |||
@@ -270,7 +272,7 @@ array2d<float> image::EdiffKernel(EdiffAlgorithm algorithm) | |||
* there is little chance that any value below 0.2 will be useful. */ | |||
#define BLUR_EPSILON 0.2f | |||
array2d<float> image::GaussianKernel(vec2 radius, float angle, vec2 delta) | |||
array2d<float> image::kernel::gaussian(vec2 radius, float angle, vec2 delta) | |||
{ | |||
array2d<float> kernel; | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -19,8 +21,8 @@ namespace lol | |||
bool image::RenderRandom(ivec2 size) | |||
{ | |||
SetSize(size); | |||
vec4 *pixels = Lock<PixelFormat::RGBA_F32>(); | |||
resize(size); | |||
vec4 *pixels = lock<PixelFormat::RGBA_F32>(); | |||
for (int n = 0; n < size.x * size.y; ++n) | |||
pixels[n] = vec4(lol::rand(1.f), | |||
@@ -28,7 +30,7 @@ bool image::RenderRandom(ivec2 size) | |||
lol::rand(1.f), | |||
1.f); | |||
Unlock(pixels); | |||
unlock(pixels); | |||
return true; | |||
} | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2004—2015 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -60,7 +60,7 @@ static u8vec4 f32tou8(vec4 pixel) | |||
* Pixel-level image manipulation | |||
*/ | |||
PixelFormat image::GetFormat() const | |||
PixelFormat image::format() const | |||
{ | |||
return m_data->m_format; | |||
} | |||
@@ -81,41 +81,41 @@ PixelFormat image::GetFormat() const | |||
* x lossless conversion (u8 to float) | |||
* # lossy conversion (dithering and/or convert color→gray) | |||
*/ | |||
void image::SetFormat(PixelFormat fmt) | |||
void image::set_format(PixelFormat fmt) | |||
{ | |||
PixelFormat old_fmt = m_data->m_format; | |||
/* Preliminary intermediate conversions */ | |||
if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_F32) | |||
SetFormat(PixelFormat::RGBA_F32); | |||
set_format(PixelFormat::RGBA_F32); | |||
else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_F32) | |||
SetFormat(PixelFormat::RGBA_F32); | |||
set_format(PixelFormat::RGBA_F32); | |||
else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGBA_8) | |||
SetFormat(PixelFormat::RGBA_F32); | |||
set_format(PixelFormat::RGBA_F32); | |||
else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGB_8) | |||
SetFormat(PixelFormat::RGBA_F32); | |||
set_format(PixelFormat::RGBA_F32); | |||
else if (old_fmt == PixelFormat::RGB_F32 && fmt == PixelFormat::RGBA_8) | |||
SetFormat(PixelFormat::RGBA_F32); | |||
set_format(PixelFormat::RGBA_F32); | |||
else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_F32) | |||
SetFormat(PixelFormat::RGB_F32); | |||
set_format(PixelFormat::RGB_F32); | |||
else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::RGB_8) | |||
SetFormat(PixelFormat::RGB_F32); | |||
set_format(PixelFormat::RGB_F32); | |||
else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_8) | |||
SetFormat(PixelFormat::RGB_F32); | |||
set_format(PixelFormat::RGB_F32); | |||
else if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_8) | |||
SetFormat(PixelFormat::RGB_F32); | |||
set_format(PixelFormat::RGB_F32); | |||
else if (old_fmt == PixelFormat::RGB_F32 && fmt == PixelFormat::Y_8) | |||
SetFormat(PixelFormat::Y_F32); | |||
set_format(PixelFormat::Y_F32); | |||
else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_8) | |||
SetFormat(PixelFormat::Y_F32); | |||
set_format(PixelFormat::Y_F32); | |||
old_fmt = m_data->m_format; | |||
/* Set the new active pixel format */ | |||
m_data->m_format = fmt; | |||
ivec2 size = GetSize(); | |||
int count = size.x * size.y; | |||
ivec2 isize = size(); | |||
int count = isize.x * isize.y; | |||
/* If we never used this format, allocate a new buffer: we will | |||
* obviously need it. */ | |||
@@ -131,17 +131,17 @@ void image::SetFormat(PixelFormat fmt) | |||
case PixelFormat::Unknown: | |||
break; | |||
case PixelFormat::Y_8: | |||
data = new PixelData<PixelFormat::Y_8>(size); break; | |||
data = new PixelData<PixelFormat::Y_8>(isize); break; | |||
case PixelFormat::RGB_8: | |||
data = new PixelData<PixelFormat::RGB_8>(size); break; | |||
data = new PixelData<PixelFormat::RGB_8>(isize); break; | |||
case PixelFormat::RGBA_8: | |||
data = new PixelData<PixelFormat::RGBA_8>(size); break; | |||
data = new PixelData<PixelFormat::RGBA_8>(isize); break; | |||
case PixelFormat::Y_F32: | |||
data = new PixelData<PixelFormat::Y_F32>(size); break; | |||
data = new PixelData<PixelFormat::Y_F32>(isize); break; | |||
case PixelFormat::RGB_F32: | |||
data = new PixelData<PixelFormat::RGB_F32>(size); break; | |||
data = new PixelData<PixelFormat::RGB_F32>(isize); break; | |||
case PixelFormat::RGBA_F32: | |||
data = new PixelData<PixelFormat::RGBA_F32>(size); break; | |||
data = new PixelData<PixelFormat::RGBA_F32>(isize); break; | |||
} | |||
#if __GNUC__ | |||
#pragma GCC diagnostic pop | |||
@@ -314,31 +314,31 @@ void image::SetFormat(PixelFormat fmt) | |||
#if 0 | |||
init_tables(); | |||
for (int y = 0; y < size.y; y++) | |||
for (int x = 0; x < size.x; x++) | |||
for (int y = 0; y < isize.y; y++) | |||
for (int x = 0; x < isize.x; x++) | |||
for (i = 0; i < 4; i++) | |||
{ | |||
double p, e; | |||
uint8_t d; | |||
p = src[4 * (y * size.x + x) + i]; | |||
p = src[4 * (y * isize.x + x) + i]; | |||
if (p < 0.) d = 0.; | |||
else if (p > 1.) d = 255; | |||
else d = (int)(255.999 * pow(p, 1. / global_gamma)); | |||
dest[4 * (y * size.x + x) + i] = d; | |||
dest[4 * (y * isize.x + x) + i] = d; | |||
e = (p - u8tof32(d)) / 16; | |||
if (x < size.x - 1) | |||
src[4 * (y * size.x + x + 1) + i] += e * 7; | |||
if (y < size.y - 1) | |||
if (x < isize.x - 1) | |||
src[4 * (y * isize.x + x + 1) + i] += e * 7; | |||
if (y < isize.y - 1) | |||
{ | |||
if (x > 0) | |||
src[4 * ((y + 1) * size.x + x - 1) + i] += e * 3; | |||
src[4 * ((y + 1) * size.x + x) + i] += e * 5; | |||
if (x < size.x - 1) | |||
src[4 * ((y + 1) * size.x + x + 1) + i] += e; | |||
src[4 * ((y + 1) * isize.x + x - 1) + i] += e * 3; | |||
src[4 * ((y + 1) * isize.x + x) + i] += e * 5; | |||
if (x < isize.x - 1) | |||
src[4 * ((y + 1) * isize.x + x + 1) + i] += e; | |||
} | |||
} | |||
#endif | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -35,10 +37,10 @@ image image::Resize(ivec2 size, ResampleAlgorithm algorithm) | |||
static image ResizeBicubic(image &src, ivec2 size) | |||
{ | |||
image dst(size); | |||
ivec2 const oldsize = src.GetSize(); | |||
ivec2 const oldsize = src.size(); | |||
vec4 const *srcp = src.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = dst.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 const *srcp = src.lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = dst.lock<PixelFormat::RGBA_F32>(); | |||
float scalex = size.x > 1 ? (oldsize.x - 1.f) / (size.x - 1) : 1.f; | |||
float scaley = size.y > 1 ? (oldsize.y - 1.f) / (size.y - 1) : 1.f; | |||
@@ -121,8 +123,8 @@ static image ResizeBicubic(image &src, ivec2 size) | |||
} | |||
} | |||
dst.Unlock(dstp); | |||
src.Unlock(srcp); | |||
dst.unlock(dstp); | |||
src.unlock(srcp); | |||
return dst; | |||
} | |||
@@ -137,11 +139,11 @@ static image ResizeBicubic(image &src, ivec2 size) | |||
static image ResizeBresenham(image &src, ivec2 size) | |||
{ | |||
image dst(size); | |||
ivec2 const oldsize = src.GetSize(); | |||
ivec2 const oldsize = src.size(); | |||
float const invswsh = 1.0f / (oldsize.x * oldsize.y); | |||
vec4 const *srcp = src.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = dst.Lock<PixelFormat::RGBA_F32>(); | |||
vec4 const *srcp = src.lock<PixelFormat::RGBA_F32>(); | |||
vec4 *dstp = dst.lock<PixelFormat::RGBA_F32>(); | |||
array<vec4> aline, line; | |||
aline.resize(size.x); | |||
@@ -198,8 +200,8 @@ static image ResizeBresenham(image &src, ivec2 size) | |||
dstp[y * size.x + x] = aline[x] * invswsh; | |||
} | |||
dst.Unlock(dstp); | |||
src.Unlock(srcp); | |||
dst.unlock(dstp); | |||
src.unlock(srcp); | |||
return dst; | |||
} | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -76,46 +76,52 @@ public: | |||
void DummyFill(); | |||
void Copy(uint8_t* pixels, ivec2 const& size, PixelFormat fmt); | |||
void Copy(image const &other); | |||
bool Load(char const *path); | |||
bool Save(char const *path); | |||
bool load(char const *path); | |||
bool save(char const *path); | |||
/* Low level access */ | |||
ivec2 GetSize() const; | |||
void SetSize(ivec2); | |||
ivec2 size() const; | |||
void resize(ivec2); | |||
PixelFormat GetFormat() const; | |||
void SetFormat(PixelFormat fmt); | |||
PixelFormat format() const; | |||
void set_format(PixelFormat fmt); | |||
WrapMode GetWrapX() const; | |||
WrapMode GetWrapY() const; | |||
void SetWrap(WrapMode wrap_x, WrapMode wrap_y); | |||
/* Lock continuous arrays of pixels for writing */ | |||
template<PixelFormat T> typename PixelType<T>::type *Lock(); | |||
void *Lock(); | |||
void Unlock(void const *pixels); | |||
template<PixelFormat T> typename PixelType<T>::type *lock(); | |||
void *lock(); | |||
void unlock(void const *pixels); | |||
/* Lock 2D arrays of pixels for writing */ | |||
template<PixelFormat T> | |||
inline array2d<typename PixelType<T>::type> &Lock2D() | |||
inline array2d<typename PixelType<T>::type> &lock2d() | |||
{ | |||
/* Hack: this indirection is needed because of a Visual Studio ICE */ | |||
return *(array2d<typename PixelType<T>::type> *)Lock2DHelper(T); | |||
return *(array2d<typename PixelType<T>::type> *)lock2d_helper(T); | |||
} | |||
template<typename T> | |||
void Unlock2D(array2d<T> const &); | |||
void unlock2d(array2d<T> const &); | |||
/* Image processing kernels */ | |||
static array2d<float> BayerKernel(ivec2 size); | |||
static array2d<float> HalftoneKernel(ivec2 size); | |||
static array2d<float> BlueNoiseKernel(ivec2 size, | |||
ivec2 gsize = ivec2(7, 7)); | |||
static array2d<float> EdiffKernel(EdiffAlgorithm algorithm); | |||
static array2d<float> NormalizeKernel(array2d<float> const &kernel); | |||
static array2d<float> GaussianKernel(vec2 radius, | |||
float angle = 0.f, | |||
vec2 delta = vec2(0.f, 0.f)); | |||
struct kernel | |||
{ | |||
kernel() = delete; | |||
static array2d<float> normalize(array2d<float> const &kernel); | |||
static array2d<float> bayer(ivec2 size); | |||
static array2d<float> halftone(ivec2 size); | |||
static array2d<float> blue_noise(ivec2 size, | |||
ivec2 gsize = ivec2(7, 7)); | |||
static array2d<float> ediff(EdiffAlgorithm algorithm); | |||
static array2d<float> gaussian(vec2 radius, | |||
float angle = 0.f, | |||
vec2 delta = vec2(0.f, 0.f)); | |||
}; | |||
/* Rendering */ | |||
bool RenderRandom(ivec2 size); | |||
@@ -141,13 +147,13 @@ public: | |||
image YUVToRGB() const; | |||
/* Dithering */ | |||
image DitherRandom() const; | |||
image DitherEdiff(array2d<float> const &kernel, | |||
ScanMode scan = ScanMode::Raster) const; | |||
image DitherOstromoukhov(ScanMode scan = ScanMode::Raster) const; | |||
image DitherOrdered(array2d<float> const &kernel) const; | |||
image DitherHalftone(float radius, float angle) const; | |||
image DitherDbs() const; | |||
image dither_random() const; | |||
image dither_ediff(array2d<float> const &kernel, | |||
ScanMode scan = ScanMode::Raster) const; | |||
image dither_ostromoukhov(ScanMode scan = ScanMode::Raster) const; | |||
image dither_ordered(array2d<float> const &kernel) const; | |||
image dither_halftone(float radius, float angle) const; | |||
image dither_dbs() const; | |||
/* Combine images */ | |||
static image Merge(image &src1, image &src2, float alpha); | |||
@@ -163,7 +169,7 @@ public: | |||
static image Difference(image &src1, image &src2); | |||
private: | |||
void *Lock2DHelper(PixelFormat T); | |||
void *lock2d_helper(PixelFormat T); | |||
class image_data *m_data; | |||
}; | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#pragma once | |||
@@ -81,7 +83,7 @@ public: | |||
int WriteString(const String &buf); | |||
long int GetPosFromStart(); | |||
void SetPosFromStart(long int pos); | |||
long int GetSize(); | |||
long int size(); | |||
long int GetModificationTime(); | |||
private: | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -182,7 +184,7 @@ class FileData | |||
#endif | |||
} | |||
long int GetSize() | |||
long int size() | |||
{ | |||
#if __ANDROID__ | |||
return 0; | |||
@@ -321,9 +323,9 @@ void File::SetPosFromStart(long int pos) | |||
} | |||
//-- | |||
long int File::GetSize() | |||
long int File::size() | |||
{ | |||
return m_data->GetSize(); | |||
return m_data->size(); | |||
} | |||
//-- | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
@@ -175,7 +175,7 @@ public: | |||
protected: | |||
virtual bool DoWork() | |||
{ | |||
return m_image.Load(m_path.C()); | |||
return m_image.load(m_path.C()); | |||
} | |||
String m_path; | |||
@@ -1,7 +1,7 @@ | |||
// | |||
// Lol Engine — Unit tests | |||
// | |||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
@@ -23,13 +23,13 @@ lolunit_declare_fixture(image_test) | |||
{ | |||
lolunit_declare_test(open_image) | |||
{ | |||
Image image("data/gradient.png"); | |||
image img("data/gradient.png"); | |||
ivec2 size = image.GetSize(); | |||
lolunit_assert_equal(size.x, 256); | |||
lolunit_assert_equal(size.y, 16); | |||
ivec2 isize = img.size(); | |||
lolunit_assert_equal(isize.x, 256); | |||
lolunit_assert_equal(isize.y, 16); | |||
u8vec4 *data = image.Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *data = img.lock<PixelFormat::RGBA_8>(); | |||
lolunit_assert(data); | |||
lolunit_assert_equal((int)data[0].r, 0x00); | |||
@@ -40,7 +40,7 @@ lolunit_declare_fixture(image_test) | |||
lolunit_assert_equal((int)data[255].g, 0xff); | |||
lolunit_assert_equal((int)data[255].b, 0xff); | |||
image.Unlock(data); | |||
img.unlock(data); | |||
} | |||
}; | |||
@@ -1,11 +1,13 @@ | |||
// | |||
// Lol Engine | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
@@ -44,10 +46,10 @@ TextureImage::TextureImage(char const *path) | |||
Init(path); | |||
} | |||
TextureImage::TextureImage(char const *path, Image* image) | |||
TextureImage::TextureImage(char const *path, image* img) | |||
: m_data(GetNewData()) | |||
{ | |||
Init(path, image); | |||
Init(path, img); | |||
} | |||
TextureImage::~TextureImage() | |||
@@ -66,19 +68,19 @@ void TextureImage::Init(char const *path, ResourceCodecData* loaded_data) | |||
auto image_data = dynamic_cast<ResourceImageData*>(loaded_data); | |||
if (image_data != nullptr) | |||
{ | |||
Init(path, new Image(*image_data->m_image)); | |||
Init(path, new image(*image_data->m_image)); | |||
} | |||
delete image_data; | |||
} | |||
void TextureImage::Init(char const *path, Image* image) | |||
void TextureImage::Init(char const *path, image* img) | |||
{ | |||
m_data->m_name = String("<textureimage> ") + path; | |||
m_data->m_texture = nullptr; | |||
m_data->m_image = image; | |||
m_data->m_image_size = m_data->m_image->GetSize(); | |||
m_data->m_image = img; | |||
m_data->m_image_size = m_data->m_image->size(); | |||
m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x), | |||
PotUp(m_data->m_image_size.y)); | |||
@@ -111,13 +113,13 @@ void TextureImage::TickDraw(float seconds, Scene &scene) | |||
m_data->m_texture = nullptr; | |||
} | |||
PixelFormat format = m_data->m_image->GetFormat(); | |||
PixelFormat format = m_data->m_image->format(); | |||
int planes = BytesPerPixel(format); | |||
int w = m_data->m_texture_size.x; | |||
int h = m_data->m_texture_size.y; | |||
uint8_t *pixels = (uint8_t *)m_data->m_image->Lock(); | |||
uint8_t *pixels = (uint8_t *)m_data->m_image->lock(); | |||
bool resized = false; | |||
if (w != m_data->m_image_size.x || h != m_data->m_image_size.y) | |||
{ | |||
@@ -129,6 +131,7 @@ void TextureImage::TickDraw(float seconds, Scene &scene) | |||
pixels = tmp; | |||
resized = false; | |||
} | |||
/* FIXME: no unlock? */ | |||
m_data->m_texture = new Texture(ivec2(w, h), format); | |||
m_data->m_texture->SetData(pixels); | |||
@@ -146,12 +149,12 @@ char const *TextureImage::GetName() | |||
return m_data->m_name.C(); | |||
} | |||
void TextureImage::UpdateTexture(Image* image) | |||
void TextureImage::UpdateTexture(image* img) | |||
{ | |||
m_data->m_image = image; | |||
m_data->m_image_size = m_data->m_image->GetSize(); | |||
m_data->m_image = img; | |||
m_data->m_image_size = m_data->m_image->size(); | |||
m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x), | |||
PotUp(m_data->m_image_size.y)); | |||
PotUp(m_data->m_image_size.y)); | |||
} | |||
Texture * TextureImage::GetTexture() | |||
@@ -164,12 +167,12 @@ Texture const * TextureImage::GetTexture() const | |||
return m_data->m_texture; | |||
} | |||
Image * TextureImage::GetImage() | |||
image * TextureImage::GetImage() | |||
{ | |||
return m_data->m_image; | |||
} | |||
Image const * TextureImage::GetImage() const | |||
image const * TextureImage::GetImage() const | |||
{ | |||
return m_data->m_image; | |||
} | |||