📄 clmodule.c
字号:
/* Cl objects */
#define CLDEBUG
#include <stdarg.h>
#include <cl.h>
#if defined(CL_JPEG_SOFTWARE) && !defined(CL_JPEG_COSMO)
#include <dmedia/cl_cosmo.h>
#endif
#include "Python.h"
typedef struct {
PyObject_HEAD
int ob_isCompressor; /* Compressor or Decompressor */
CL_Handle ob_compressorHdl;
int *ob_paramtypes;
int ob_nparams;
} clobject;
static PyObject *ClError; /* exception cl.error */
static int error_handler_called = 0;
/*
* We want to use the function prototypes that are available in the C
* compiler on the SGI. Because of that, we need to declare the first
* argument of the compressor and decompressor methods as "object *",
* even though they are really "clobject *". Therefore we cast the
* argument to the proper type using this macro.
*/
#define SELF ((clobject *) self)
/********************************************************************
Utility routines.
********************************************************************/
static void
cl_ErrorHandler(CL_Handle handle, int code, const char *fmt, ...)
{
va_list ap;
char errbuf[BUFSIZ]; /* hopefully big enough */
char *p;
if (PyErr_Occurred()) /* don't change existing error */
return;
error_handler_called = 1;
va_start(ap, fmt);
vsprintf(errbuf, fmt, ap);
va_end(ap);
p = &errbuf[strlen(errbuf) - 1]; /* swat the line feed */
if (*p == '\n')
*p = 0;
PyErr_SetString(ClError, errbuf);
}
/*
* This assumes that params are always in the range 0 to some maximum.
*/
static int
param_type_is_float(clobject *self, int param)
{
int bufferlength;
if (self->ob_paramtypes == NULL) {
error_handler_called = 0;
bufferlength = clQueryParams(self->ob_compressorHdl, 0, 0);
if (error_handler_called)
return -1;
self->ob_paramtypes = PyMem_NEW(int, bufferlength);
if (self->ob_paramtypes == NULL)
return -1;
self->ob_nparams = bufferlength / 2;
(void) clQueryParams(self->ob_compressorHdl,
self->ob_paramtypes, bufferlength);
if (error_handler_called) {
PyMem_DEL(self->ob_paramtypes);
self->ob_paramtypes = NULL;
return -1;
}
}
if (param < 0 || param >= self->ob_nparams)
return -1;
if (self->ob_paramtypes[param*2 + 1] == CL_FLOATING_ENUM_VALUE ||
self->ob_paramtypes[param*2 + 1] == CL_FLOATING_RANGE_VALUE)
return 1;
else
return 0;
}
/********************************************************************
Single image compression/decompression.
********************************************************************/
static PyObject *
cl_CompressImage(PyObject *self, PyObject *args)
{
int compressionScheme, width, height, originalFormat;
float compressionRatio;
int frameBufferSize, compressedBufferSize;
char *frameBuffer;
PyObject *compressedBuffer;
if (!PyArg_Parse(args, "(iiiifs#)", &compressionScheme,
&width, &height,
&originalFormat, &compressionRatio, &frameBuffer,
&frameBufferSize))
return NULL;
retry:
compressedBuffer = PyString_FromStringAndSize(NULL, frameBufferSize);
if (compressedBuffer == NULL)
return NULL;
compressedBufferSize = frameBufferSize;
error_handler_called = 0;
if (clCompressImage(compressionScheme, width, height, originalFormat,
compressionRatio, (void *) frameBuffer,
&compressedBufferSize,
(void *) PyString_AsString(compressedBuffer))
== FAILURE || error_handler_called) {
Py_DECREF(compressedBuffer);
if (!error_handler_called)
PyErr_SetString(ClError, "clCompressImage failed");
return NULL;
}
if (compressedBufferSize > frameBufferSize) {
frameBufferSize = compressedBufferSize;
Py_DECREF(compressedBuffer);
goto retry;
}
if (compressedBufferSize < frameBufferSize)
if (_PyString_Resize(&compressedBuffer, compressedBufferSize))
return NULL;
return compressedBuffer;
}
static PyObject *
cl_DecompressImage(PyObject *self, PyObject *args)
{
int compressionScheme, width, height, originalFormat;
char *compressedBuffer;
int compressedBufferSize, frameBufferSize;
PyObject *frameBuffer;
if (!PyArg_Parse(args, "(iiiis#)", &compressionScheme, &width, &height,
&originalFormat, &compressedBuffer,
&compressedBufferSize))
return NULL;
frameBufferSize = width * height * CL_BytesPerPixel(originalFormat);
frameBuffer = PyString_FromStringAndSize(NULL, frameBufferSize);
if (frameBuffer == NULL)
return NULL;
error_handler_called = 0;
if (clDecompressImage(compressionScheme, width, height, originalFormat,
compressedBufferSize, compressedBuffer,
(void *) PyString_AsString(frameBuffer))
== FAILURE || error_handler_called) {
Py_DECREF(frameBuffer);
if (!error_handler_called)
PyErr_SetString(ClError, "clDecompressImage failed");
return NULL;
}
return frameBuffer;
}
/********************************************************************
Sequential compression/decompression.
********************************************************************/
#define CheckCompressor(self) if ((self)->ob_compressorHdl == NULL) { \
PyErr_SetString(PyExc_RuntimeError, "(de)compressor not active"); \
return NULL; \
}
static PyObject *
doClose(clobject *self, PyObject *args, int (*close_func)(CL_Handle))
{
CheckCompressor(self);
if (!PyArg_NoArgs(args))
return NULL;
error_handler_called = 0;
if ((*close_func)(self->ob_compressorHdl) == FAILURE ||
error_handler_called) {
if (!error_handler_called)
PyErr_SetString(ClError, "close failed");
return NULL;
}
self->ob_compressorHdl = NULL;
if (self->ob_paramtypes)
PyMem_DEL(self->ob_paramtypes);
self->ob_paramtypes = NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
clm_CloseCompressor(PyObject *self, PyObject *args)
{
return doClose(SELF, args, clCloseCompressor);
}
static PyObject *
clm_CloseDecompressor(PyObject *self, PyObject *args)
{
return doClose(SELF, args, clCloseDecompressor);
}
static PyObject *
clm_Compress(PyObject *self, PyObject *args)
{
int numberOfFrames;
int frameBufferSize, compressedBufferSize, size;
char *frameBuffer;
PyObject *data;
CheckCompressor(SELF);
if (!PyArg_Parse(args, "(is#)", &numberOfFrames,
&frameBuffer, &frameBufferSize))
return NULL;
error_handler_called = 0;
size = clGetParam(SELF->ob_compressorHdl, CL_COMPRESSED_BUFFER_SIZE);
compressedBufferSize = size;
if (error_handler_called)
return NULL;
data = PyString_FromStringAndSize(NULL, size);
if (data == NULL)
return NULL;
error_handler_called = 0;
if (clCompress(SELF->ob_compressorHdl, numberOfFrames,
(void *) frameBuffer, &compressedBufferSize,
(void *) PyString_AsString(data)) == FAILURE ||
error_handler_called) {
Py_DECREF(data);
if (!error_handler_called)
PyErr_SetString(ClError, "compress failed");
return NULL;
}
if (compressedBufferSize < size)
if (_PyString_Resize(&data, compressedBufferSize))
return NULL;
if (compressedBufferSize > size) {
/* we didn't get all "compressed" data */
Py_DECREF(data);
PyErr_SetString(ClError,
"compressed data is more than fitted");
return NULL;
}
return data;
}
static PyObject *
clm_Decompress(PyObject *self, PyObject *args)
{
PyObject *data;
int numberOfFrames;
char *compressedData;
int compressedDataSize, dataSize;
CheckCompressor(SELF);
if (!PyArg_Parse(args, "(is#)", &numberOfFrames, &compressedData,
&compressedDataSize))
return NULL;
error_handler_called = 0;
dataSize = clGetParam(SELF->ob_compressorHdl, CL_FRAME_BUFFER_SIZE);
if (error_handler_called)
return NULL;
data = PyString_FromStringAndSize(NULL, dataSize);
if (data == NULL)
return NULL;
error_handler_called = 0;
if (clDecompress(SELF->ob_compressorHdl, numberOfFrames,
compressedDataSize, (void *) compressedData,
(void *) PyString_AsString(data)) == FAILURE ||
error_handler_called) {
Py_DECREF(data);
if (!error_handler_called)
PyErr_SetString(ClError, "decompress failed");
return NULL;
}
return data;
}
static PyObject *
doParams(clobject *self, PyObject *args, int (*func)(CL_Handle, int *, int),
int modified)
{
PyObject *list, *v;
int *PVbuffer;
int length;
int i;
float number;
CheckCompressor(self);
if (!PyArg_Parse(args, "O", &list))
return NULL;
if (!PyList_Check(list)) {
PyErr_BadArgument();
return NULL;
}
length = PyList_Size(list);
PVbuffer = PyMem_NEW(int, length);
if (PVbuffer == NULL)
return PyErr_NoMemory();
for (i = 0; i < length; i++) {
v = PyList_GetItem(list, i);
if (PyFloat_Check(v)) {
number = PyFloat_AsDouble(v);
PVbuffer[i] = CL_TypeIsInt(number);
} else if (PyInt_Check(v)) {
PVbuffer[i] = PyInt_AsLong(v);
if ((i & 1) &&
param_type_is_float(self, PVbuffer[i-1]) > 0) {
number = PVbuffer[i];
PVbuffer[i] = CL_TypeIsInt(number);
}
} else {
PyMem_DEL(PVbuffer);
PyErr_BadArgument();
return NULL;
}
}
error_handler_called = 0;
(*func)(self->ob_compressorHdl, PVbuffer, length);
if (error_handler_called) {
PyMem_DEL(PVbuffer);
return NULL;
}
if (modified) {
for (i = 0; i < length; i++) {
if ((i & 1) &&
param_type_is_float(self, PVbuffer[i-1]) > 0) {
number = CL_TypeIsFloat(PVbuffer[i]);
v = PyFloat_FromDouble(number);
} else
v = PyInt_FromLong(PVbuffer[i]);
PyList_SetItem(list, i, v);
}
}
PyMem_DEL(PVbuffer);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
clm_GetParams(PyObject *self, PyObject *args)
{
return doParams(SELF, args, clGetParams, 1);
}
static PyObject *
clm_SetParams(PyObject *self, PyObject *args)
{
return doParams(SELF, args, clSetParams, 0);
}
static PyObject *
do_get(clobject *self, PyObject *args, int (*func)(CL_Handle, int))
{
int paramID, value;
float fvalue;
CheckCompressor(self);
if (!PyArg_Parse(args, "i", ¶mID))
return NULL;
error_handler_called = 0;
value = (*func)(self->ob_compressorHdl, paramID);
if (error_handler_called)
return NULL;
if (param_type_is_float(self, paramID) > 0) {
fvalue = CL_TypeIsFloat(value);
return PyFloat_FromDouble(fvalue);
}
return PyInt_FromLong(value);
}
static PyObject *
clm_GetParam(PyObject *self, PyObject *args)
{
return do_get(SELF, args, clGetParam);
}
static PyObject *
clm_GetDefault(PyObject *self, PyObject *args)
{
return do_get(SELF, args, clGetDefault);
}
static PyObject *
clm_SetParam(PyObject *self, PyObject *args)
{
int paramID, value;
float fvalue;
CheckCompressor(SELF);
if (!PyArg_Parse(args, "(ii)", ¶mID, &value)) {
PyErr_Clear();
if (!PyArg_Parse(args, "(if)", ¶mID, &fvalue)) {
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"bad argument list (format '(ii)' or '(if)')");
return NULL;
}
value = CL_TypeIsInt(fvalue);
} else {
if (param_type_is_float(SELF, paramID) > 0) {
fvalue = value;
value = CL_TypeIsInt(fvalue);
}
}
error_handler_called = 0;
value = clSetParam(SELF->ob_compressorHdl, paramID, value);
if (error_handler_called)
return NULL;
if (param_type_is_float(SELF, paramID) > 0)
return PyFloat_FromDouble(CL_TypeIsFloat(value));
else
return PyInt_FromLong(value);
}
static PyObject *
clm_GetParamID(PyObject *self, PyObject *args)
{
char *name;
int value;
CheckCompressor(SELF);
if (!PyArg_Parse(args, "s", &name))
return NULL;
error_handler_called = 0;
value = clGetParamID(SELF->ob_compressorHdl, name);
if (value == FAILURE || error_handler_called) {
if (!error_handler_called)
PyErr_SetString(ClError, "getparamid failed");
return NULL;
}
return PyInt_FromLong(value);
}
static PyObject *
clm_QueryParams(PyObject *self, PyObject *args)
{
int bufferlength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -