11#include " UnrealEnginePythonPrivatePCH.h"
22
3+ #include " Runtime/Engine/Public/ImageUtils.h"
4+ #include " Runtime/Engine/Classes/Engine/Texture.h"
5+
6+ PyObject *py_ue_texture_get_width (ue_PyUObject *self, PyObject * args) {
7+
8+ ue_py_check (self);
9+
10+ UTexture2D *texture = ue_py_check_type<UTexture2D>(self);
11+ if (!texture)
12+ return PyErr_Format (PyExc_Exception, " object is not a Texture" );
13+
14+ return PyLong_FromLong (texture->GetSizeX ());
15+ }
16+
17+ PyObject *py_ue_texture_get_height (ue_PyUObject *self, PyObject * args) {
18+
19+ ue_py_check (self);
20+
21+ UTexture2D *texture = ue_py_check_type<UTexture2D>(self);
22+ if (!texture)
23+ return PyErr_Format (PyExc_Exception, " object is not a Texture" );
24+
25+ return PyLong_FromLong (texture->GetSizeY ());
26+ }
327
428PyObject *py_ue_texture_get_data (ue_PyUObject *self, PyObject * args) {
529
@@ -11,11 +35,10 @@ PyObject *py_ue_texture_get_data(ue_PyUObject *self, PyObject * args) {
1135 return NULL ;
1236 }
1337
14- if (!self->ue_object ->IsA <UTexture2D>())
38+ UTexture2D *tex = ue_py_check_type<UTexture2D>(self);
39+ if (!tex)
1540 return PyErr_Format (PyExc_Exception, " object is not a Texture2D" );
1641
17- UTexture2D *tex = (UTexture2D *)self->ue_object ;
18-
1942 if (mipmap >= tex->GetNumMips ())
2043 return PyErr_Format (PyExc_Exception, " invalid mipmap id" );
2144
@@ -29,44 +52,94 @@ PyObject *py_ue_texture_set_data(ue_PyUObject *self, PyObject * args) {
2952
3053 ue_py_check (self);
3154
32- PyObject *byte_array ;
55+ Py_buffer py_buf ;
3356 int mipmap = 0 ;
3457
35- if (!PyArg_ParseTuple (args, " O |i:texture_get_data " , &byte_array , &mipmap)) {
58+ if (!PyArg_ParseTuple (args, " z* |i:texture_set_data " , &py_buf , &mipmap)) {
3659 return NULL ;
3760 }
3861
39- if (!self->ue_object ->IsA <UTexture2D>())
62+ UTexture2D *tex = ue_py_check_type<UTexture2D>(self);
63+ if (!tex)
4064 return PyErr_Format (PyExc_Exception, " object is not a Texture2D" );
4165
42- UTexture2D *tex = (UTexture2D *)self->ue_object ;
4366
44- if (!PyByteArray_Check (byte_array) )
45- return PyErr_Format (PyExc_Exception, " argument is not a bytearray " );
67+ if (!py_buf. buf )
68+ return PyErr_Format (PyExc_Exception, " invalid data " );
4669
4770 if (mipmap >= tex->GetNumMips ())
4871 return PyErr_Format (PyExc_Exception, " invalid mipmap id" );
4972
5073 char *blob = (char *)tex->PlatformData ->Mips [mipmap].BulkData .Lock (LOCK_READ_WRITE);
5174 int32 len = tex->PlatformData ->Mips [mipmap].BulkData .GetBulkDataSize ();
52- Py_ssize_t byte_array_size = PyByteArray_Size (byte_array) ;
75+ int32 wanted_len = py_buf. len ;
5376 // avoid making mess
54- if (byte_array_size > len)
55- byte_array_size = len;
56- char *byte_array_blob = PyByteArray_AsString (byte_array);
57- FMemory::Memcpy (blob, byte_array_blob, byte_array_size);
77+ if (wanted_len > len) {
78+ UE_LOG (LogPython, Warning, TEXT (" truncating buffer to %d bytes" ), len);
79+ wanted_len = len;
80+ }
81+ FMemory::Memcpy (blob, py_buf.buf , wanted_len);
5882 tex->PlatformData ->Mips [mipmap].BulkData .Unlock ();
5983
6084 tex->MarkPackageDirty ();
6185#if WITH_EDITOR
6286 tex->PostEditChange ();
6387#endif
6488
65- // ensure compatibility between 4.12 and 4.14
66- // tex->UpdateResourceW();
89+ tex->UpdateResource ();
6790
6891 Py_INCREF (Py_None);
6992 return Py_None;
7093}
7194
95+ PyObject *py_unreal_engine_compress_image_array (PyObject * self, PyObject * args) {
96+ int width;
97+ int height;
98+ Py_buffer py_buf;
99+ if (!PyArg_ParseTuple (args, " iiz*:compress_image_array" , &width, &height, &py_buf)) {
100+ return NULL ;
101+ }
102+
103+ if (py_buf.buf == nullptr || py_buf.len <= 0 ) {
104+ PyBuffer_Release (&py_buf);
105+ return PyErr_Format (PyExc_Exception, " invalid image data" );
106+ }
107+
108+ TArray<FColor> colors;
109+ uint8 *buf = (uint8 *)py_buf.buf ;
110+ for (int32 i = 0 ; i < py_buf.len ; i += 4 ) {
111+ colors.Add (FColor (buf[i], buf[1 + 1 ], buf[i + 2 ], buf[i + 3 ]));
112+ }
113+
114+ TArray<uint8> output;
115+
116+ FImageUtils::CompressImageArray (width, height, colors, output);
117+
118+ return PyBytes_FromStringAndSize ((char *)output.GetData (), output.Num ());
119+ }
120+
121+ PyObject *py_unreal_engine_create_checkerboard_texture (PyObject * self, PyObject * args) {
122+ PyObject *py_color_one;
123+ PyObject *py_color_two;
124+ int checker_size;
125+ if (!PyArg_ParseTuple (args, " OOi:create_checkboard_texture" , &py_color_one, &py_color_two, &checker_size)) {
126+ return NULL ;
127+ }
128+
129+ ue_PyFColor *color_one = py_ue_is_fcolor (py_color_one);
130+ if (!color_one)
131+ return PyErr_Format (PyExc_Exception, " argument is not a FColor" );
132+
133+ ue_PyFColor *color_two = py_ue_is_fcolor (py_color_two);
134+ if (!color_two)
135+ return PyErr_Format (PyExc_Exception, " argument is not a FColor" );
136+
137+ UTexture2D *texture = FImageUtils::CreateCheckerboardTexture (color_one->color , color_two->color , checker_size);
138+
139+ ue_PyUObject *ret = ue_get_python_wrapper (texture);
140+ if (!ret)
141+ return PyErr_Format (PyExc_Exception, " uobject is in invalid state" );
142+ Py_INCREF (ret);
143+ return (PyObject *)ret;
144+ }
72145
0 commit comments