blob: 0aeb29632f77e5ce1d980a7b353e361ac9a16890 [file] [log] [blame]
Sjoerd Mullenderc4315491992-09-23 14:53:00 +00001/***********************************************************
2Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25
26/* Cl objects */
27
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000028#include <stdarg.h>
Sjoerd Mullenderc4315491992-09-23 14:53:00 +000029#include <cl.h>
30#include "allobjects.h"
31#include "modsupport.h" /* For getargs() etc. */
32#include "ceval.h" /* For call_object() */
33
34typedef struct {
35 OB_HEAD
36 int ob_isCompressor; /* Compressor or Decompressor */
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +000037 CL_Handle ob_compressorHdl;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +000038} clobject;
39
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000040static object *ClError; /* exception cl.error */
41
42static int error_handler_called = 0;
43
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +000044/********************************************************************
45 Utility routines.
46********************************************************************/
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000047static void
Sjoerd Mullender3a997271993-02-04 16:43:28 +000048cl_ErrorHandler(CL_Handle handle, int code, const char *fmt, ...)
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000049{
50 va_list ap;
51 char errbuf[BUFSIZ]; /* hopefully big enough */
Sjoerd Mullender384f2481992-09-29 16:43:43 +000052 char *p;
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000053
Sjoerd Mullender384f2481992-09-29 16:43:43 +000054 if (err_occurred()) /* don't change existing error */
55 return;
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000056 error_handler_called = 1;
57 va_start(ap, fmt);
58 vsprintf(errbuf, fmt, ap);
59 va_end(ap);
Sjoerd Mullender384f2481992-09-29 16:43:43 +000060 p = &errbuf[strlen(errbuf) - 1]; /* swat the line feed */
61 if (*p == '\n')
62 *p = 0;
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +000063 err_setstr(ClError, errbuf);
64}
65
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +000066/*
67 * This assumes that params are always in the range 0 to some maximum.
68 * This is not very efficient.
69 */
70static int
Sjoerd Mullender3a997271993-02-04 16:43:28 +000071param_type_is_float(CL_Handle comp, int param)
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +000072{
Sjoerd Mullender3a997271993-02-04 16:43:28 +000073 int bufferlength;
74 int *PVbuffer;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +000075 int ret;
76
77 error_handler_called = 0;
78 bufferlength = clQueryParams(comp, 0, 0);
79 if (error_handler_called)
80 return -1;
81
82 if (param < 0 || param >= bufferlength / 2)
83 return -1;
84
Sjoerd Mullender3a997271993-02-04 16:43:28 +000085 PVbuffer = NEW(int, bufferlength);
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +000086 if (PVbuffer == NULL)
87 return -1;
88
89 bufferlength = clQueryParams(comp, PVbuffer, bufferlength);
90 if (error_handler_called) {
91 DEL(PVbuffer);
92 return -1;
93 }
94
95 if (PVbuffer[param*2 + 1] == CL_FLOATING_ENUM_VALUE ||
96 PVbuffer[param*2 + 1] == CL_FLOATING_RANGE_VALUE)
97 ret = 1;
98 else
99 ret = 0;
100
101 DEL(PVbuffer);
102
103 return ret;
104}
105
106/********************************************************************
107 Single image compression/decompression.
108********************************************************************/
109static object *
110cl_CompressImage(self, args)
111 object *self, *args;
112{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000113 int compressionScheme, width, height, originalFormat;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000114 float compressionRatio;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000115 int frameBufferSize, compressedBufferSize;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000116 char *frameBuffer;
117 object *compressedBuffer;
118
119 if (!getargs(args, "(iiiifs#)", &compressionScheme, &width, &height,
120 &originalFormat, &compressionRatio, &frameBuffer,
121 &frameBufferSize))
122 return NULL;
123
124 retry:
125 compressedBuffer = newsizedstringobject(NULL, frameBufferSize);
126 if (compressedBuffer == NULL)
127 return NULL;
128
129 compressedBufferSize = frameBufferSize;
130 error_handler_called = 0;
131 if (clCompressImage(compressionScheme, width, height, originalFormat,
132 compressionRatio, (void *) frameBuffer,
133 &compressedBufferSize,
134 (void *) getstringvalue(compressedBuffer))
135 == FAILURE) {
136 DECREF(compressedBuffer);
137 if (!error_handler_called)
138 err_setstr(ClError, "clCompressImage failed");
139 return NULL;
140 }
141
142 if (compressedBufferSize > frameBufferSize) {
143 frameBufferSize = compressedBufferSize;
144 DECREF(compressedBuffer);
145 goto retry;
146 }
147
148 if (compressedBufferSize < frameBufferSize)
149 if (resizestring(&compressedBuffer, compressedBufferSize))
150 return NULL;
151
152 return compressedBuffer;
153}
154
155static object *
156cl_DecompressImage(self, args)
157 object *self, *args;
158{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000159 int compressionScheme, width, height, originalFormat;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000160 char *compressedBuffer;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000161 int compressedBufferSize, frameBufferSize;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000162 object *frameBuffer;
163
164 if (!getargs(args, "(iiiis#i)", &compressionScheme, &width, &height,
165 &originalFormat, &compressedBuffer, &compressedBufferSize,
166 &frameBufferSize))
167 return NULL;
168
169 frameBuffer = newsizedstringobject(NULL, frameBufferSize);
170 if (frameBuffer == NULL)
171 return NULL;
172
173 error_handler_called = 0;
174 if (clDecompressImage(compressionScheme, width, height, originalFormat,
175 compressedBufferSize, compressedBuffer,
176 (void *) getstringvalue(frameBuffer)) == FAILURE) {
177 DECREF(frameBuffer);
178 if (!error_handler_called)
179 err_setstr(ClError, "clDecompressImage failed");
180 return NULL;
181 }
182
183 return frameBuffer;
184}
185
186/********************************************************************
187 Sequential compression/decompression.
188********************************************************************/
189extern typeobject Cltype; /* Really static, forward */
190
191#define CheckCompressor(self) if ((self)->ob_compressorHdl == NULL) { \
192 err_setstr(RuntimeError, "(de)compressor not active"); \
193 return NULL; \
194 }
195
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000196static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000197doClose(self, args, close_func)
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000198 clobject *self;
199 object *args;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000200 int (*close_func) PROTO((CL_Handle));
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000201{
202 CheckCompressor(self);
203
204 if (!getnoarg(args))
205 return NULL;
206
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000207 error_handler_called = 0;
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000208 if ((*close_func)(self->ob_compressorHdl) == FAILURE) {
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000209 if (!error_handler_called)
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000210 err_setstr(ClError, "close failed");
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000211 return NULL;
212 }
213
214 self->ob_compressorHdl = NULL;
215
216 INCREF(None);
217 return None;
218}
219
220static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000221clm_CloseCompressor(self, args)
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000222 clobject *self;
223 object *args;
224{
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000225 return doClose(self, args, clCloseCompressor);
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000226}
227
228static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000229clm_CloseDecompressor(self, args)
230 clobject *self;
231 object *args;
232{
233 return doClose(self, args, clCloseDecompressor);
234}
235
236static object *
237clm_Compress(self, args)
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000238 clobject *self;
239 object *args;
240{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000241 int numberOfFrames;
242 int frameBufferSize, compressedBufferSize;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000243 char *frameBuffer;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000244 int PVbuf[2];
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000245 object *data;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000246
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000247 CheckCompressor(self);
248
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000249 if (!getargs(args, "(is#)", &numberOfFrames, &frameBuffer, &frameBufferSize))
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000250 return NULL;
251
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000252 PVbuf[0] = CL_COMPRESSED_BUFFER_SIZE;
253 PVbuf[1] = 0;
254 error_handler_called = 0;
255 clGetParams(self->ob_compressorHdl, PVbuf, 2L);
256 if (error_handler_called)
257 return NULL;
258
259 data = newsizedstringobject(NULL, PVbuf[1]);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000260 if (data == NULL)
261 return NULL;
262
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000263 compressedBufferSize = PVbuf[1];
264
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000265 error_handler_called = 0;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000266 if (clCompress(self->ob_compressorHdl, numberOfFrames,
267 (void *) frameBuffer, &compressedBufferSize,
268 (void *) getstringvalue(data)) == FAILURE) {
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000269 DECREF(data);
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000270 if (!error_handler_called)
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000271 err_setstr(ClError, "compress failed");
272 return NULL;
273 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000274
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000275 if (compressedBufferSize < PVbuf[1])
276 if (resizestring(&data, compressedBufferSize))
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000277 return NULL;
278
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000279 if (compressedBufferSize > PVbuf[1]) {
280 /* we didn't get all "compressed" data */
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000281 DECREF(data);
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000282 err_setstr(ClError, "compressed data is more than fitted");
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000283 return NULL;
284 }
285
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000286 return data;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000287}
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000288
289static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000290clm_Decompress(self, args)
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000291 clobject *self;
292 object *args;
293{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000294 int PVbuf[2];
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000295 object *data;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000296 int numberOfFrames;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000297 char *compressedData;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000298 int compressedDataSize;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000299
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000300 CheckCompressor(self);
301
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000302 if (!getargs(args, "(is#)", &numberOfFrames, &compressedData,
303 &compressedDataSize))
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000304 return NULL;
305
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000306 PVbuf[0] = CL_FRAME_BUFFER_SIZE;
307 PVbuf[1] = 0;
308 error_handler_called = 0;
309 clGetParams(self->ob_compressorHdl, PVbuf, 2L);
310 if (error_handler_called)
311 return NULL;
312
313 data = newsizedstringobject(NULL, PVbuf[1]);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000314 if (data == NULL)
315 return NULL;
316
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000317 error_handler_called = 0;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000318 if (clDecompress(self->ob_compressorHdl, numberOfFrames,
319 compressedDataSize, (void *) compressedData,
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000320 (void *) getstringvalue(data)) == FAILURE) {
321 DECREF(data);
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000322 if (!error_handler_called)
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000323 err_setstr(ClError, "decompress failed");
324 return NULL;
325 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000326
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000327 return data;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000328}
329
330static object *
331doParams(self, args, func, modified)
332 clobject *self;
333 object *args;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000334 void (*func)(CL_Handle, int *, int);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000335 int modified;
336{
337 object *list, *v;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000338 int *PVbuffer;
339 int length;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000340 int i;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000341 float number;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000342
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000343 CheckCompressor(self);
344
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000345 if (!getargs(args, "O", &list))
346 return NULL;
347 if (!is_listobject(list)) {
348 err_badarg();
349 return NULL;
350 }
351 length = getlistsize(list);
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000352 PVbuffer = NEW(int, length);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000353 if (PVbuffer == NULL)
354 return err_nomem();
355 for (i = 0; i < length; i++) {
356 v = getlistitem(list, i);
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000357 if (is_floatobject(v)) {
358 number = getfloatvalue(v);
359 PVbuffer[i] = CL_TypeIsInt(number);
360 } else if (is_intobject(v))
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000361 PVbuffer[i] = getintvalue(v);
362 else {
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000363 DEL(PVbuffer);
364 err_badarg();
365 return NULL;
366 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000367 }
368
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000369 error_handler_called = 0;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000370 (*func)(self->ob_compressorHdl, PVbuffer, length);
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000371 if (error_handler_called)
372 return NULL;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000373
374 if (modified) {
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000375 for (i = 0; i < length; i++) {
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000376 if ((i & 1) &&
377 param_type_is_float(self->ob_compressorHdl,
378 PVbuffer[i-1]) > 0) {
379 number = CL_TypeIsFloat(PVbuffer[i]);
380 v = newfloatobject(number);
381 } else
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000382 v = newintobject(PVbuffer[i]);
383 setlistitem(list, i, v);
384 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000385 }
386
387 DEL(PVbuffer);
388
389 INCREF(None);
390 return None;
391}
392
393static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000394clm_GetParams(self, args)
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000395 clobject *self;
396 object *args;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000397{
398 return doParams(self, args, clGetParams, 1);
399}
400
401static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000402clm_SetParams(self, args)
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000403 clobject *self;
404 object *args;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000405{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000406 return doParams(self, args, clSetParams, 0);
407}
408
409static object *
410do_get(self, args, func)
411 clobject *self;
412 object *args;
413 int (*func)(CL_Handle, int);
414{
415 int paramID, value;
416 float fvalue;
417
418 CheckCompressor(self);
419
420 if (!getargs(args, "i", &paramID))
421 return NULL;
422
423 error_handler_called = 0;
424 value = (*func)(self->ob_compressorHdl, paramID);
425 if (error_handler_called)
426 return NULL;
427
428 if (param_type_is_float(self->ob_compressorHdl, paramID) > 0) {
429 fvalue = CL_TypeIsFloat(value);
430 return newfloatobject(fvalue);
431 }
432
433 return newintobject(value);
434}
435
436static object *
437clm_GetParam(self, args)
438 clobject *self;
439 object *args;
440{
441 return do_get(self, args, clGetParam);
442}
443
444static object *
445clm_GetDefault(self, args)
446 clobject *self;
447 object *args;
448{
449 return do_get(self, args, clGetDefault);
450}
451
452static object *
453do_set(self, args, func)
454 clobject *self;
455 object *args;
456 int (*func)(CL_Handle, int, int);
457{
458 int paramID, value;
459 float fvalue;
460
461 CheckCompressor(self);
462
463 if (!getargs(args, "(ii)", &paramID, &value)) {
464 err_clear();
465 if (!getargs(args, "(if)", &paramID, &fvalue)) {
466 err_clear();
467 err_setstr(TypeError, "bad argument list (format '(ii)' or '(if)')");
468 return NULL;
469 }
470 value = CL_TypeIsInt(fvalue);
471 }
472
473 error_handler_called = 0;
474 value = (*func)(self->ob_compressorHdl, paramID, value);
475 if (error_handler_called)
476 return NULL;
477
478 if (param_type_is_float(self->ob_compressorHdl, paramID) > 0)
479 return newfloatobject(CL_TypeIsFloat(value));
480 else
481 return newintobject(value);
482}
483
484static object *
485clm_SetParam(self, args)
486 clobject *self;
487 object *args;
488{
489 return do_set(self, args, clSetParam);
490}
491
492static object *
493clm_SetDefault(self, args)
494 clobject *self;
495 object *args;
496{
497 return do_set(self, args, clSetDefault);
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000498}
499
500static object *
501clm_GetParamID(self, args)
502 clobject *self;
503 object *args;
504{
505 char *name;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000506 int value;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000507
508 CheckCompressor(self);
509
510 if (!getargs(args, "s", &name))
511 return NULL;
512
513 error_handler_called = 0;
514 value = clGetParamID(self->ob_compressorHdl, name);
515 if (value == FAILURE) {
516 if (!error_handler_called)
517 err_setstr(ClError, "getparamid failed");
518 return NULL;
519 }
520
521 return newintobject(value);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000522}
523
524static object *
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000525clm_QueryParams(self, args)
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000526 clobject *self;
527 object *args;
528{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000529 int bufferlength;
530 int *PVbuffer;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000531 object *list;
532 int i;
533
Sjoerd Mullender37f17b71992-09-25 10:28:20 +0000534 CheckCompressor(self);
535
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000536 if (!getnoarg(args))
537 return NULL;
538
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000539 error_handler_called = 0;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000540 bufferlength = clQueryParams(self->ob_compressorHdl, 0, 0);
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000541 if (error_handler_called)
542 return NULL;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000543
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000544 PVbuffer = NEW(int, bufferlength);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000545 if (PVbuffer == NULL)
546 return err_nomem();
547
548 bufferlength = clQueryParams(self->ob_compressorHdl, PVbuffer,
549 bufferlength);
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000550 if (error_handler_called) {
551 DEL(PVbuffer);
552 return NULL;
553 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000554
555 list = newlistobject(bufferlength);
556 if (list == NULL) {
557 DEL(PVbuffer);
558 return NULL;
559 }
560
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000561 for (i = 0; i < bufferlength; i++) {
562 if (i & 1)
563 setlistitem(list, i, newintobject(PVbuffer[i]));
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000564 else if (PVbuffer[i] == 0) {
565 INCREF(None);
566 setlistitem(list, i, None);
567 } else
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000568 setlistitem(list, i, newstringobject((char *) PVbuffer[i]));
569 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000570
571 DEL(PVbuffer);
572
573 return list;
574}
575
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000576static object *
577clm_GetMinMax(self, args)
578 clobject *self;
579 object *args;
580{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000581 int param, min, max;
582 float fmin, fmax;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000583
584 CheckCompressor(self);
585
586 if (!getargs(args, "i", &param))
587 return NULL;
588
589 clGetMinMax(self->ob_compressorHdl, param, &min, &max);
590
591 if (param_type_is_float(self->ob_compressorHdl, param) > 0) {
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000592 fmin = CL_TypeIsFloat(min);
593 fmax = CL_TypeIsFloat(max);
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000594 return mkvalue("(ff)", fmin, fmax);
595 }
596
597 return mkvalue("(ii)", min, max);
598}
599
600static object *
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000601clm_SetMin(self, args)
602 clobject *self;
603 object *args;
604{
605 return do_set(self, args, clSetMin);
606}
607
608static object *
609clm_SetMax(self, args)
610 clobject *self;
611 object *args;
612{
613 return do_set(self, args, clSetMax);
614}
615
616static object *
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000617clm_GetName(self, args)
618 clobject *self;
619 object *args;
620{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000621 int param;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000622 char *name;
623
624 CheckCompressor(self);
625
626 if (!getargs(args, "i", &param))
627 return NULL;
628
629 error_handler_called = 0;
630 name = clGetName(self->ob_compressorHdl, param);
631 if (name == NULL || error_handler_called) {
632 if (!error_handler_called)
633 err_setstr(ClError, "getname failed");
634 return NULL;
635 }
636
637 return newstringobject(name);
638}
639
640static object *
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000641clm_ReadHeader(self, args)
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000642 clobject *self;
643 object *args;
644{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000645 char *header;
646 int headerSize;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000647
648 CheckCompressor(self);
649
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000650 if (!getargs(args, "s#", &header, &headerSize))
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000651 return NULL;
652
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000653 return newintobject(clReadHeader(self->ob_compressorHdl,
654 headerSize, header));
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000655}
656
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000657static struct methodlist compressor_methods[] = {
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000658 {"close", clm_CloseCompressor}, /* alias */
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000659 {"CloseCompressor", clm_CloseCompressor},
660 {"Compress", clm_Compress},
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000661 {"GetDefault", clm_GetDefault},
662 {"GetMinMax", clm_GetMinMax},
663 {"GetName", clm_GetName},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000664 {"GetParam", clm_GetParam},
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000665 {"GetParamID", clm_GetParamID},
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000666 {"GetParams", clm_GetParams},
667 {"QueryParams", clm_QueryParams},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000668 {"SetDefault", clm_SetDefault},
669 {"SetMax", clm_SetMax},
670 {"SetMin", clm_SetMin},
671 {"SetParam", clm_SetParam},
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000672 {"SetParams", clm_SetParams},
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000673 {NULL, NULL} /* sentinel */
674};
675
676static struct methodlist decompressor_methods[] = {
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000677 {"close", clm_CloseDecompressor}, /* alias */
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000678 {"CloseDecompressor", clm_CloseDecompressor},
679 {"Decompress", clm_Decompress},
680 {"GetDefault", clm_GetDefault},
681 {"GetMinMax", clm_GetMinMax},
682 {"GetName", clm_GetName},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000683 {"GetParam", clm_GetParam},
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000684 {"GetParamID", clm_GetParamID},
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000685 {"GetParams", clm_GetParams},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000686 {"ReadHeader", clm_ReadHeader},
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000687 {"QueryParams", clm_QueryParams},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000688 {"SetDefault", clm_SetDefault},
689 {"SetMax", clm_SetMax},
690 {"SetMin", clm_SetMin},
691 {"SetParam", clm_SetParam},
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000692 {"SetParams", clm_SetParams},
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000693 {NULL, NULL} /* sentinel */
694};
695
696static void
697cl_dealloc(self)
698 clobject *self;
699{
700 if (self->ob_compressorHdl) {
701 if (self->ob_isCompressor)
702 clCloseCompressor(self->ob_compressorHdl);
703 else
704 clCloseDecompressor(self->ob_compressorHdl);
705 }
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000706 DEL(self);
707}
708
709static object *
710cl_getattr(self, name)
711 clobject *self;
712 char *name;
713{
714 if (self->ob_isCompressor)
715 return findmethod(compressor_methods, (object *)self, name);
716 else
717 return findmethod(decompressor_methods, (object *) self, name);
718}
719
720static typeobject Cltype = {
721 OB_HEAD_INIT(&Typetype)
722 0, /*ob_size*/
723 "cl", /*tp_name*/
724 sizeof(clobject), /*tp_size*/
725 0, /*tp_itemsize*/
726 /* methods */
727 cl_dealloc, /*tp_dealloc*/
728 0, /*tp_print*/
729 cl_getattr, /*tp_getattr*/
730 0, /*tp_setattr*/
731 0, /*tp_compare*/
732 0, /*tp_repr*/
733 0, /*tp_as_number*/
734 0, /*tp_as_sequence*/
735 0, /*tp_as_mapping*/
736};
737
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000738static object *
739doOpen(self, args, open_func, iscompressor)
740 object *self, *args;
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000741 int (*open_func) PROTO((int, CL_Handle *));
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000742 int iscompressor;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000743{
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000744 int scheme;
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000745 clobject *new;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000746
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000747 if (!getargs(args, "i", &scheme))
748 return NULL;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000749
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000750 new = NEWOBJ(clobject, &Cltype);
751 if (new == NULL)
752 return NULL;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000753
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000754 new->ob_compressorHdl = NULL;
755 new->ob_isCompressor = iscompressor;
756
757 error_handler_called = 0;
758 if ((*open_func)(scheme, &new->ob_compressorHdl) == FAILURE) {
759 DECREF(new);
760 if (!error_handler_called)
761 err_setstr(ClError, "Open(De)Compressor failed");
762 return NULL;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000763 }
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000764 return new;
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000765}
766
767static object *
768cl_OpenCompressor(self, args)
769 object *self, *args;
770{
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000771 return doOpen(self, args, clOpenCompressor, 1);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000772}
773
774static object *
775cl_OpenDecompressor(self, args)
776 object *self, *args;
777{
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000778 return doOpen(self, args, clOpenDecompressor, 0);
Sjoerd Mullender384f2481992-09-29 16:43:43 +0000779}
780
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000781static object *
782cl_QueryScheme(self, args)
783 object *self, *args;
784{
785 char *header;
786 int headerlen;
787 int scheme;
788
789 if (!getargs(args, "s#", &header, &headerlen))
790 return NULL;
791
792 scheme = clQueryScheme(header);
793 if (scheme < 0) {
794 err_setstr(ClError, "unknown compression scheme");
795 return NULL;
796 }
797
798 return newintobject(scheme);
799}
800
801static object *
802cl_QueryMaxHeaderSize(self, args)
803 object *self, *args;
804{
805 int scheme;
806
807 if (!getargs(args, "i", &scheme))
808 return NULL;
809
810 return newintobject(clQueryMaxHeaderSize(scheme));
811}
812
813static object *
814cl_QueryAlgorithms(self, args)
815 object *self, *args;
816{
817 int algorithmMediaType;
818 int bufferlength;
819 int *PVbuffer;
820 object *list;
821 int i;
822
823 if (!getargs(args, "i", &algorithmMediaType))
824 return NULL;
825
826 error_handler_called = 0;
827 bufferlength = clQueryAlgorithms(algorithmMediaType, 0, 0);
828 if (error_handler_called)
829 return NULL;
830
831 PVbuffer = NEW(int, bufferlength);
832 if (PVbuffer == NULL)
833 return err_nomem();
834
835 bufferlength = clQueryAlgorithms(algorithmMediaType, PVbuffer,
836 bufferlength);
837 if (error_handler_called) {
838 DEL(PVbuffer);
839 return NULL;
840 }
841
842 list = newlistobject(bufferlength);
843 if (list == NULL) {
844 DEL(PVbuffer);
845 return NULL;
846 }
847
848 for (i = 0; i < bufferlength; i++) {
849 if (i & 1)
850 setlistitem(list, i, newintobject(PVbuffer[i]));
851 else if (PVbuffer[i] == 0) {
852 INCREF(None);
853 setlistitem(list, i, None);
854 } else
855 setlistitem(list, i, newstringobject((char *) PVbuffer[i]));
856 }
857
858 DEL(PVbuffer);
859
860 return list;
861}
862
863static object *
864cl_QuerySchemeFromName(self, args)
865 object *self, *args;
866{
867 int algorithmMediaType;
868 char *name;
869 int scheme;
870
871 if (!getargs(args, "(is)", &algorithmMediaType, &name))
872 return NULL;
873
874 error_handler_called = 0;
875 scheme = clQuerySchemeFromName(algorithmMediaType, name);
876 if (error_handler_called) {
877 err_setstr(ClError, "unknown compression scheme");
878 return NULL;
879 }
880
881 return newintobject(scheme);
882}
883
884static object *
885cl_GetAlgorithmName(self, args)
886 object *self, *args;
887{
888 int scheme;
889 char *name;
890
891 if (!getargs(args, "i", &scheme))
892 return NULL;
893
894 name = clGetAlgorithmName(scheme);
895 if (name == 0) {
896 err_setstr(ClError, "unknown compression scheme");
897 return NULL;
898 }
899
900 return newstringobject(name);
901}
902
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000903static struct methodlist cl_methods[] = {
Sjoerd Mullender8dd054d1992-12-14 13:17:29 +0000904 {"CompressImage", cl_CompressImage},
905 {"DecompressImage", cl_DecompressImage},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000906 {"GetAlgorithmName", cl_GetAlgorithmName},
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000907 {"OpenCompressor", cl_OpenCompressor},
908 {"OpenDecompressor", cl_OpenDecompressor},
Sjoerd Mullender3a997271993-02-04 16:43:28 +0000909 {"QueryAlgorithms", cl_QueryAlgorithms},
910 {"QueryMaxHeaderSize", cl_QueryMaxHeaderSize},
911 {"QueryScheme", cl_QueryScheme},
912 {"QuerySchemeFromName", cl_QuerySchemeFromName},
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000913 {NULL, NULL} /* Sentinel */
914};
915
916void
917initcl()
918{
Sjoerd Mullenderd53a4f31992-09-24 10:37:39 +0000919 object *m, *d;
920
921 m = initmodule("cl", cl_methods);
922 d = getmoduledict(m);
923
924 ClError = newstringobject("cl.error");
925 if (ClError == NULL || dictinsert(d, "error", ClError) != 0)
926 fatal("can't define cl.error");
927
928 (void) clSetErrorHandler(cl_ErrorHandler);
Sjoerd Mullenderc4315491992-09-23 14:53:00 +0000929}