open_toontown_panda3d/panda/src/gobj/texture_ext.cxx

152 lines
4.8 KiB
C++

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file texture_ext.cxx
* @author rdb
* @date 2016-08-08
*/
#include "texture_ext.h"
#ifdef HAVE_PYTHON
#ifndef CPPPARSER
extern Dtool_PyTypedObject Dtool_PointerToArray_unsigned_char;
extern Dtool_PyTypedObject Dtool_ConstPointerToArray_unsigned_char;
#endif
/**
* Replaces the current system-RAM image with the new data. If compression is
* not CM_off, it indicates that the new data is already pre-compressed in the
* indicated format.
*
* This does *not* affect keep_ram_image.
*/
void Extension<Texture>::
set_ram_image(PyObject *image, Texture::CompressionMode compression,
size_t page_size) {
nassertv(compression != Texture::CM_default);
// Check if perhaps a PointerToArray object was passed in.
if (DtoolCanThisBeAPandaInstance(image)) {
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)image;
if (inst->_My_Type == &Dtool_ConstPointerToArray_unsigned_char) {
_this->set_ram_image(*(const CPTA_uchar *)inst->_ptr_to_object, compression, page_size);
return;
} else if (inst->_My_Type == &Dtool_PointerToArray_unsigned_char) {
_this->set_ram_image(*(const PTA_uchar *)inst->_ptr_to_object, compression, page_size);
return;
}
}
#if PY_VERSION_HEX >= 0x02060000
if (PyObject_CheckBuffer(image)) {
// User passed a buffer object.
Py_buffer view;
if (PyObject_GetBuffer(image, &view, PyBUF_CONTIG_RO) == -1) {
PyErr_SetString(PyExc_TypeError,
"Texture.set_ram_image() requires a contiguous buffer");
return;
}
int component_width = _this->get_component_width();
if (compression == Texture::CM_off) {
if (view.itemsize != 1 && view.itemsize != component_width) {
PyErr_SetString(PyExc_TypeError,
"buffer.itemsize does not match Texture component size");
return;
}
if (view.len % component_width != 0) {
PyErr_Format(PyExc_ValueError,
"byte buffer is not a multiple of %zu bytes",
component_width);
return;
}
} else {
if (view.itemsize != 1) {
PyErr_SetString(PyExc_TypeError,
"buffer.itemsize should be 1 for compressed images");
return;
}
}
PTA_uchar data = PTA_uchar::empty_array(view.len, Texture::get_class_type());
memcpy(data.p(), view.buf, view.len);
_this->set_ram_image(MOVE(data), compression, page_size);
PyBuffer_Release(&view);
return;
}
#endif
Dtool_Raise_ArgTypeError(image, 0, "Texture.set_ram_image", "CPTA_uchar or buffer");
}
/**
* Replaces the current system-RAM image with the new data, converting it
* first if necessary from the indicated component-order format. See
* get_ram_image_as() for specifications about the format. This method cannot
* support compressed image data or sub-pages; use set_ram_image() for that.
*/
void Extension<Texture>::
set_ram_image_as(PyObject *image, const string &provided_format) {
// Check if perhaps a PointerToArray object was passed in.
if (DtoolCanThisBeAPandaInstance(image)) {
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)image;
if (inst->_My_Type == &Dtool_ConstPointerToArray_unsigned_char) {
_this->set_ram_image_as(*(const CPTA_uchar *)inst->_ptr_to_object, provided_format);
return;
} else if (inst->_My_Type == &Dtool_PointerToArray_unsigned_char) {
_this->set_ram_image_as(*(const PTA_uchar *)inst->_ptr_to_object, provided_format);
return;
}
}
#if PY_VERSION_HEX >= 0x02060000
if (PyObject_CheckBuffer(image)) {
// User passed a buffer object.
Py_buffer view;
if (PyObject_GetBuffer(image, &view, PyBUF_CONTIG_RO) == -1) {
PyErr_SetString(PyExc_TypeError,
"Texture.set_ram_image_as() requires a contiguous buffer");
return;
}
int component_width = _this->get_component_width();
if (view.itemsize != 1 && view.itemsize != component_width) {
PyErr_SetString(PyExc_TypeError,
"buffer.itemsize does not match Texture component size");
return;
}
if (view.len % component_width != 0) {
PyErr_Format(PyExc_ValueError,
"byte buffer is not a multiple of %zu bytes",
component_width);
return;
}
PTA_uchar data = PTA_uchar::empty_array(view.len, Texture::get_class_type());
memcpy(data.p(), view.buf, view.len);
_this->set_ram_image_as(MOVE(data), provided_format);
PyBuffer_Release(&view);
return;
}
#endif
Dtool_Raise_ArgTypeError(image, 0, "Texture.set_ram_image_as", "CPTA_uchar or buffer");
}
#endif // HAVE_PYTHON