~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/xieperf/xieperf.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: xieperf.c,v 1.4 2001/02/09 02:05:48 xorgcvs Exp $ */
 
2
 
 
3
/**** module xieperf.c ****/
 
4
/****************************************************************************
 
5
 
 
6
Copyright 1993, 1994, 1998  The Open Group
 
7
 
 
8
Permission to use, copy, modify, distribute, and sell this software and its
 
9
documentation for any purpose is hereby granted without fee, provided that
 
10
the above copyright notice appear in all copies and that both that
 
11
copyright notice and this permission notice appear in supporting
 
12
documentation.
 
13
 
 
14
The above copyright notice and this permission notice shall be included in
 
15
all copies or substantial portions of the Software.
 
16
 
 
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
20
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
21
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
22
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
23
 
 
24
Except as contained in this notice, the name of The Open Group shall not be
 
25
used in advertising or otherwise to promote the sale, use or other dealings
 
26
in this Software without prior written authorization from The Open Group.
 
27
 
 
28
 
 
29
                                NOTICE
 
30
                              
 
31
This software is being provided by AGE Logic, Inc. under the
 
32
following license.  By obtaining, using and/or copying this software,
 
33
you agree that you have read, understood, and will comply with these
 
34
terms and conditions:
 
35
 
 
36
     Permission to use, copy, modify, distribute and sell this
 
37
     software and its documentation for any purpose and without
 
38
     fee or royalty and to grant others any or all rights granted
 
39
     herein is hereby granted, provided that you agree to comply
 
40
     with the following copyright notice and statements, including
 
41
     the disclaimer, and that the same appears on all copies and
 
42
     derivative works of the software and documentation you make.
 
43
     
 
44
     "Copyright 1993, 1994 by AGE Logic, Inc."
 
45
     
 
46
     THIS SOFTWARE IS PROVIDED "AS IS".  AGE LOGIC MAKES NO
 
47
     REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  By way of
 
48
     example, but not limitation, AGE LOGIC MAKE NO
 
49
     REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS
 
50
     FOR ANY PARTICULAR PURPOSE OR THAT THE SOFTWARE DOES NOT
 
51
     INFRINGE THIRD-PARTY PROPRIETARY RIGHTS.  AGE LOGIC 
 
52
     SHALL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE.  IN NO
 
53
     EVENT SHALL EITHER PARTY BE LIABLE FOR ANY INDIRECT,
 
54
     INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS
 
55
     OF PROFITS, REVENUE, DATA OR USE, INCURRED BY EITHER PARTY OR
 
56
     ANY THIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT OR
 
57
     BASED ON A WARRANTY, EVEN IF AGE LOGIC LICENSEES
 
58
     HEREUNDER HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
 
59
     DAMAGES.
 
60
    
 
61
     The name of AGE Logic, Inc. may not be used in
 
62
     advertising or publicity pertaining to this software without
 
63
     specific, written prior permission from AGE Logic.
 
64
 
 
65
     Title to this software shall at all times remain with AGE
 
66
     Logic, Inc.
 
67
*****************************************************************************
 
68
  
 
69
        xieperf.c -- xieperf main module ( looks a lot like x11perf.c ) 
 
70
 
 
71
        Syd Logan -- AGE Logic, Inc.
 
72
  
 
73
*****************************************************************************/
 
74
/* $XFree86: xc/programs/xieperf/xieperf.c,v 3.8 2001/12/14 20:01:53 dawes Exp $ */
 
75
 
 
76
#include <X11/Xos.h>
 
77
#include <stdio.h>
 
78
#include <ctype.h>
 
79
#include <signal.h>
 
80
#include <math.h>
 
81
#include <errno.h>
 
82
#include "xieperf.h"
 
83
#include <X11/Xmu/SysUtil.h>
 
84
#include <X11/Xmu/StdCmap.h>
 
85
#include <time.h>
 
86
#define Time_t time_t
 
87
#ifndef O_BINARY
 
88
#define O_BINARY 0
 
89
#endif
 
90
#define lowbit(x) ((x) & (~(x) + 1))
 
91
 
 
92
 
 
93
/* Only for working on ``fake'' servers, for hardware that doesn't exist */
 
94
static Bool     drawToFakeServer = False;
 
95
static Pixmap   tileToQuery     = None;
 
96
 
 
97
static Bool     labels          = False;
 
98
static Bool     loadTests       = False;
 
99
static char     *loadTestsFile;
 
100
#define DEFAULT_REPEAT  2
 
101
static int      repeat          = DEFAULT_REPEAT;
 
102
static int      seconds         = 5;
 
103
Bool    dontClear;
 
104
unsigned short capabilities = 0;
 
105
unsigned short class_request = SUBSET_FULL;
 
106
extern int CacheSizeMax;
 
107
static FILE     *fp = ( FILE * ) NULL;
 
108
static Bool RGB_BESTStandardColormapObtained = False;
 
109
 
 
110
char    *imagepath = "./images";
 
111
 
 
112
static Window   status;     /* Status window and GC */
 
113
static GC       tgc;
 
114
 
 
115
static double syncTime = 0.0;
 
116
 
 
117
static int saveargc;
 
118
static char **saveargv;
 
119
 
 
120
static char *foreground = NULL;
 
121
static char *background = NULL;
 
122
 
 
123
static int  fixedReps = 0;
 
124
 
 
125
static Bool sigBail = False;
 
126
static Bool *doit;
 
127
Bool WMSafe = False;
 
128
static Bool loCal = False;
 
129
Bool showErrors = False;
 
130
static Bool runErrors = False;
 
131
static Bool runEvents = False;
 
132
static Bool showLabels = False;   /* Hear me now and believe me later,
 
133
                                     when 'True', is helpful if test 
 
134
                                     dies in calibration */ 
 
135
static Bool showTechs = False;
 
136
static int visualClass = -1;
 
137
 
 
138
static XRectangle ws[] = {  /* Clip rectangles */
 
139
    {195, 195, 120, 120},
 
140
    { 45, 145, 120, 120},
 
141
    {345, 245, 120, 120}
 
142
 
 
143
};
 
144
#define MAXCLIP     (sizeof(ws) / sizeof(ws[0]))
 
145
static Window clipWindows[MAXCLIP];
 
146
static Colormap cmap, colorcmap, graycmap, emptycmap; 
 
147
static int depth = -1;  /* -1 means use default depth */
 
148
Window drawableWindow;
 
149
Window monitorWindow;
 
150
Window monitor2Window;
 
151
static unsigned long whiteidx, blackidx;
 
152
unsigned long DCRedMask, DCGreenMask, DCBlueMask;
 
153
static unsigned char rbits, gbits, bbits;
 
154
 
 
155
 
 
156
/* ScreenSaver state */
 
157
static XParmRec    xparms;
 
158
static int ssTimeout, ssInterval, ssPreferBlanking, ssAllowExposures;
 
159
 
 
160
static void usage ( void );
 
161
static Window CreateXIEParent ( XParms xp );
 
162
static void AllocateGrayMapColors ( XParms xp );
 
163
static void AllocateColorMapColors ( XParms xp );
 
164
static void SetDirectTrueColorStuff ( XParms xp, int *n_colors );
 
165
#ifdef notyet
 
166
static int GetWords ( int argi, int argc, char **argv, char **wordsp, 
 
167
                      int *nump );
 
168
static int atox ( char *s );
 
169
static int GetNumbers ( int argi, int argc, char **argv, int *intsp, 
 
170
                        int *nump );
 
171
#endif
 
172
static void SendTripleBandPlaneDataSequential ( XParms xp, Parms p, 
 
173
                                                int flo_id, 
 
174
                                                XiePhotospace photospace, 
 
175
                                                int element, char *data, 
 
176
                                                int size, 
 
177
                                                unsigned char pixel_stride[3], 
 
178
                                                unsigned char left_pad[3], 
 
179
                                                unsigned char scanline_pad[3], 
 
180
                                                XieLTriplet width, 
 
181
                                                XieLTriplet height );
 
182
static void ScanlinePad ( int *value, int pad );
 
183
static int EventOrErrorValid ( unsigned short testcp );
 
184
static int ServerIsCapable ( unsigned short testcp );
 
185
static void ListAllTechs ( XParms xp );
 
186
#ifdef notyet
 
187
static void FillHisto ( XieHistogramData histos[], int size, int levels );
 
188
#endif
 
189
static int TDLutCellSize ( XParms xp );
 
190
static int LutCellSize ( int depth );
 
191
static int icbrt_with_guess ( int a, int guess );
 
192
static int icbrt_with_bits ( int a, int bits );
 
193
 
 
194
/************************************************
 
195
*           time related stuff                  *
 
196
************************************************/
 
197
 
 
198
#ifdef VMS
 
199
 
 
200
typedef struct _vms_time {
 
201
    unsigned long low;
 
202
    unsigned long high;
 
203
}vms_time;
 
204
 
 
205
struct timeval {
 
206
    long tv_sec;        /* seconds since Jan. 1, 1970 */
 
207
    long tv_usec;  /* and microseconds */
 
208
};
 
209
 
 
210
struct timezone {
 
211
    int  tz_minuteswest;     /* of Greenwich */
 
212
    int  tz_dsttime;    /* type of dst correction to apply */
 
213
};
 
214
 
 
215
 
 
216
static int firsttime = True;
 
217
static vms_time basetime;
 
218
 
 
219
int gettimeofday(tp)
 
220
    struct timeval *tp;
 
221
{
 
222
    vms_time current_time, resultant;
 
223
    unsigned long mumble, foo;
 
224
    int status;
 
225
 
 
226
    if (firsttime) {
 
227
        sys$gettim(&basetime);
 
228
        firsttime = False;
 
229
    }
 
230
    sys$gettim(&current_time);
 
231
    resultant.high = current_time.high - basetime.high;
 
232
    resultant.low = current_time.low - basetime.low;
 
233
    if (current_time.low < basetime.low) {
 
234
        resultant.high -= 1;
 
235
    }
 
236
    status = lib$ediv( &(10000000), &resultant, &tp->tv_sec, &tp->tv_usec);
 
237
    tp->tv_usec /= 10;
 
238
    return 0;
 
239
}
 
240
 
 
241
#endif
 
242
 
 
243
static struct  timeval start;
 
244
 
 
245
static void 
 
246
PrintTime(void)
 
247
{
 
248
    Time_t t;
 
249
 
 
250
    t = time((Time_t *)NULL);
 
251
    printf("%s\n", ctime(&t));
 
252
}
 
253
 
 
254
static void 
 
255
InitTimes(void)
 
256
{
 
257
    X_GETTIMEOFDAY(&start);
 
258
}
 
259
 
 
260
static double 
 
261
ElapsedTime(double correction)
 
262
{
 
263
    struct timeval stop;
 
264
 
 
265
    X_GETTIMEOFDAY(&stop);
 
266
    if (stop.tv_usec < start.tv_usec) {
 
267
        stop.tv_usec += 1000000;
 
268
        stop.tv_sec -= 1;
 
269
    }
 
270
    return  (double)(stop.tv_usec - start.tv_usec) +
 
271
            (1000000.0 * (double)(stop.tv_sec - start.tv_sec)) - correction;
 
272
}
 
273
 
 
274
static double 
 
275
RoundTo3Digits(double d)
 
276
{
 
277
    /* It's kind of silly to print out things like ``193658.4/sec'' so just
 
278
       junk all but 3 most significant digits. */
 
279
 
 
280
    double exponent, sign;
 
281
 
 
282
    exponent = 1.0;
 
283
    /* the code below won't work if d should happen to be non-positive. */
 
284
    if (d < 0.0) {
 
285
        d = -d;
 
286
        sign = -1.0;
 
287
    } else
 
288
        sign = 1.0;
 
289
    if (d >= 1000.0) {
 
290
        do {
 
291
            exponent *= 10.0;
 
292
        } while (d/exponent >= 1000.0);
 
293
        d = (double)((int) (d/exponent + 0.5));
 
294
        d *= exponent;
 
295
    } else {
 
296
        if (d != 0.0) {
 
297
            while (d*exponent < 100.0) {
 
298
                exponent *= 10.0;
 
299
            }
 
300
        }
 
301
        d = (double)((int) (d*exponent + 0.5));
 
302
        d /= exponent;
 
303
    }
 
304
    return d * sign;
 
305
}
 
306
 
 
307
 
 
308
static void 
 
309
ReportTimes(double usecs, int n, char *str, int average)
 
310
{
 
311
    double msecsperobj, objspersec;
 
312
 
 
313
    if ( n != 0 )
 
314
    {
 
315
        if(usecs != 0.0)
 
316
        {
 
317
            msecsperobj = usecs / (1000.0 * (double)n);
 
318
            objspersec = (double) n * 1000000.0 / usecs;
 
319
 
 
320
            /* Round obj/sec to 3 significant digits.  Leave msec untouched, to
 
321
               allow averaging results from several repetitions. */
 
322
            objspersec =  RoundTo3Digits(objspersec);
 
323
 
 
324
            if (average) {
 
325
                printf("%6d trep @ %7.4f msec (%6.1f/sec): %s\n", 
 
326
                        n, msecsperobj, objspersec, str);
 
327
            } else {
 
328
                printf("%6d reps @ %7.4f msec (%6.1f/sec): %s\n", 
 
329
                        n, msecsperobj, objspersec, str);
 
330
            }
 
331
        } else {
 
332
            printf("%6d %sreps @ 0.0 msec (unmeasurably fast): %s\n",
 
333
                n, average ? "t" : "", str);
 
334
        }
 
335
    }
 
336
    else
 
337
    {
 
338
        printf("0 reps @ 0.0 msec (test initialization failed): %s\n", str);
 
339
    }
 
340
}
 
341
 
 
342
/************************************************
 
343
*               Generic X stuff                 *
 
344
************************************************/
 
345
 
 
346
static char *program_name;
 
347
 
 
348
Display *
 
349
GetDisplay(void)
 
350
{
 
351
        return( xparms.d );
 
352
}
 
353
 
 
354
/*
 
355
 * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
 
356
 * If found, remove it from command line.  Don't go past a lone -.
 
357
 */
 
358
static char *
 
359
Get_Display_Name(int *pargc,    /* MODIFIED */
 
360
                 char **argv)   /* MODIFIED */
 
361
{
 
362
    int     argc = *pargc;
 
363
    char    **pargv = argv+1;
 
364
    char    *displayname = NULL;
 
365
    int     i;
 
366
 
 
367
    for (i = 1; i != argc; i++) {
 
368
        char *arg = argv[i];
 
369
 
 
370
        if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
 
371
            if (++i >= argc) usage ();
 
372
 
 
373
            displayname = argv[i];
 
374
            *pargc -= 2;
 
375
            continue;
 
376
        }
 
377
        if (!strcmp(arg,"-")) {
 
378
            while (i<argc)  *pargv++ = argv[i++];
 
379
            break;
 
380
        }
 
381
        *pargv++ = arg;
 
382
    }
 
383
 
 
384
    *pargv = NULL;
 
385
    return (displayname);
 
386
}
 
387
 
 
388
 
 
389
/*
 
390
 * Open_Display: Routine to open a display with correct error handling.
 
391
 */
 
392
Display *
 
393
Open_Display(char *display_name)
 
394
{
 
395
    Display *d;
 
396
 
 
397
    d = XOpenDisplay(display_name);
 
398
    if (d == NULL) {
 
399
        fprintf (stderr, "%s:  unable to open display '%s'\n",
 
400
                 program_name, XDisplayName (display_name));
 
401
        usage ();
 
402
        /* doesn't return */
 
403
    }
 
404
 
 
405
    return(d);
 
406
}
 
407
 
 
408
SIGNAL_T
 
409
Cleanup(int sig)
 
410
{
 
411
    sigBail = True;
 
412
#ifdef SIGNALRETURNSINT
 
413
    return 0;
 
414
#endif
 
415
}
 
416
 
 
417
/************************************************
 
418
*               Performance stuff               *
 
419
************************************************/
 
420
 
 
421
static void 
 
422
usage(void)
 
423
{
 
424
    char    **cpp;
 
425
    int     i = 0;
 
426
    static char *help_message[] = {
 
427
"where options include:",
 
428
"    -display <host:display>   the XIE server to contact",
 
429
"    -images <path>            path to images supplied with this software,", 
 
430
"                              defaults to ./images if flag not specified",
 
431
"    -timeout <s>              timeout value for certain tests (default=60 secs)",
 
432
"    -sync                     do the tests in synchronous mode",
 
433
"    -script file              read tests from a file, ``-'' to use console",
 
434
"    -repeat <n>               do tests <n> times (outer loop) (default = 2)",
 
435
"    -time <s>                 do tests for <s> seconds each (default = 5)",
 
436
"    -depth <depth>            use a visual with <depth> planes per pixel",
 
437
"    -GrayScale                use a GrayScale visual",
 
438
"    -StaticGray               use a StaticGray visual",
 
439
"    -StaticColor              use a StaticColor visual",
 
440
"    -PseudoColor              use a PseudoColor visual",
 
441
"    -TrueColor                use a TrueColor visual",
 
442
"    -DirectColor              use a DirectColor visual",
 
443
"    -WMSafe                   let window manager install colormap",
 
444
"    -showtechs                print supported techniques",
 
445
"    -showlabels               print test label to screen before calibration",
 
446
"    -showevents               for error and event tests, display as received",
 
447
"    -events                   include event tests",
 
448
"    -errors                   include error tests",
 
449
"    -loCal                    no calibration, fix reps to 5 ( -reps overrides this )",
 
450
"    -all                      do all tests",
 
451
"    -tests                    generate a list of all tests", 
 
452
"    -mkscript                 generate script file to stderr ( recognizes -repeat and -reps )",
 
453
"    -cache <n>                cache up to n photomaps in server",
 
454
"    -labels                   print test labels ( use -all or -range to specify tests )",      
 
455
"    -DIS                      run DIS subset tests only ( use -all or -range to specify tests )",                      
 
456
"    -range <test1>[,<test2>]  like all, but do <test1> to <test2>",
 
457
"    -reps <n>                 fix the inner loop rep count (default = auto scale)",
 
458
NULL};
 
459
 
 
460
    fflush(stdout);
 
461
    fprintf(stderr, "usage: %s [-options ...]\n", program_name);
 
462
    for (cpp = help_message; *cpp; cpp++) {
 
463
        fprintf(stderr, "%s\n", *cpp);
 
464
    }
 
465
 
 
466
    fprintf(stderr, "\n");
 
467
    
 
468
    /* Print out original command line as the above usage message is so long */
 
469
    for (i = 0; i != saveargc; i++) {
 
470
        fprintf(stderr, "%s ", saveargv[i]);
 
471
    }
 
472
    fprintf(stderr, "\n\n");
 
473
    exit (1);
 
474
}
 
475
 
 
476
void 
 
477
NullProc(XParms xp, Parms p)
 
478
{
 
479
}
 
480
 
 
481
Bool 
 
482
NullInitProc(XParms xp, Parms p, int reps)
 
483
{
 
484
    return reps;
 
485
}
 
486
 
 
487
 
 
488
static void 
 
489
HardwareSync(XParms xp)
 
490
{
 
491
    /*
 
492
     * Some graphics hardware allows the server to claim it is done,
 
493
     * while in reality the hardware is busily working away.  So fetch
 
494
     * a pixel from the window that was drawn to, which should be
 
495
     * enough to make the server wait for the graphics hardware.
 
496
     */
 
497
    XImage *image;
 
498
 
 
499
    image = XGetImage(xp->d, xp->w, 0, 0, 1, 1, ~0, ZPixmap);
 
500
    XDestroyImage(image);
 
501
}
 
502
 
 
503
static void 
 
504
DoHardwareSync(XParms xp, Parms p, int reps)
 
505
{
 
506
    int i;
 
507
    
 
508
    for (i = 0; i != reps; i++) {
 
509
        HardwareSync(xp);
 
510
    }
 
511
}
 
512
 
 
513
static Test syncTest = {
 
514
    "syncTime", "Internal test for finding how long HardwareSync takes",
 
515
    NullInitProc, DoHardwareSync, NullProc, NullProc, 
 
516
    VALL, 0, 0,
 
517
    {1}
 
518
};
 
519
 
 
520
 
 
521
static Window 
 
522
CreatePerfWindow(XParms xp, int x, int y, int width, int height)
 
523
{
 
524
    XSetWindowAttributes xswa;
 
525
    Window w;
 
526
    unsigned long value_mask;
 
527
 
 
528
    xswa.background_pixel = xp->background;
 
529
    xswa.border_pixel = xp->foreground;
 
530
    if ( WMSafe == False )
 
531
        xswa.override_redirect = True;
 
532
    else
 
533
        xswa.override_redirect = False;
 
534
    xswa.backing_store = False;
 
535
    xswa.save_under = False;
 
536
    xswa.colormap = cmap;
 
537
    value_mask = CWBackPixel | CWBorderPixel | CWColormap |
 
538
        CWOverrideRedirect |CWBackingStore | CWSaveUnder;
 
539
 
 
540
    w = XCreateWindow(xp->d, xp->p, x, y, width, height, 1,
 
541
        xp->vinfo.depth, CopyFromParent, xp->vinfo.visual,
 
542
        value_mask, &xswa);
 
543
    XMapWindow (xp->d, w);
 
544
    return w;
 
545
}
 
546
 
 
547
static Window 
 
548
CreatePerfWindowUnmapped(XParms xp, int x, int y, int width, int height)
 
549
{
 
550
    XSetWindowAttributes xswa;
 
551
    Window w;
 
552
    unsigned long value_mask;
 
553
 
 
554
    xswa.background_pixel = xp->background;
 
555
    xswa.border_pixel = xp->foreground;
 
556
    xswa.colormap = cmap;
 
557
    if ( WMSafe == False )
 
558
        xswa.override_redirect = True;
 
559
    else
 
560
        xswa.override_redirect = False;
 
561
    xswa.backing_store = False;
 
562
    xswa.save_under = False;
 
563
    value_mask = CWBackPixel | CWBorderPixel | CWColormap |
 
564
        CWOverrideRedirect |CWBackingStore | CWSaveUnder;
 
565
    w = XCreateWindow(xp->d, xp->p, x, y, width, height, 1,
 
566
        xp->vinfo.depth, CopyFromParent, xp->vinfo.visual, value_mask, &xswa);
 
567
    return w;
 
568
}
 
569
 
 
570
void
 
571
InstallThisColormap(XParms xp, Colormap newcmap)
 
572
{
 
573
        if ( WMSafe == False )
 
574
        {
 
575
                XSetWindowColormap( xp->d, xp->w, newcmap );
 
576
        XFlush( xp->d );
 
577
                XSetWindowColormap( xp->d, drawableWindow, newcmap );
 
578
        XFlush( xp->d );
 
579
                XInstallColormap( xp->d, newcmap );
 
580
        XFlush( xp->d );
 
581
        }
 
582
        else
 
583
        {       
 
584
                XSetWindowColormap( xp->d, xp->p, newcmap );
 
585
        XFlush( xp->d );
 
586
        }
 
587
        cmap = newcmap;
 
588
}
 
589
 
 
590
void
 
591
InstallDefaultColormap(XParms xp)
 
592
{
 
593
        InstallThisColormap( xp,
 
594
                        DefaultColormap( xp->d, DefaultScreen( xp->d ) ) );
 
595
        XFlush( xp->d );
 
596
}
 
597
 
 
598
void
 
599
InstallGrayColormap(XParms xp)
 
600
{
 
601
        cmap = graycmap;
 
602
        InstallThisColormap( xp, cmap );
 
603
}
 
604
 
 
605
void
 
606
InstallEmptyColormap(XParms xp)
 
607
{
 
608
        cmap = emptycmap;
 
609
        InstallThisColormap( xp, cmap );
 
610
}
 
611
 
 
612
void
 
613
InstallColorColormap(XParms xp)
 
614
{
 
615
        cmap = colorcmap;
 
616
        InstallThisColormap( xp, cmap );
 
617
}
 
618
 
 
619
static void 
 
620
CreateClipWindows(XParms xp, int clips)
 
621
{
 
622
    int j;
 
623
    XWindowAttributes    xwa;
 
624
 
 
625
    (void) XGetWindowAttributes(xp->d, xp->w, &xwa);
 
626
    if (clips > MAXCLIP) clips = MAXCLIP;
 
627
    for (j = 0; j != clips; j++) {
 
628
        clipWindows[j] = CreatePerfWindow(xp, xwa.x + ws[j].x, 
 
629
                xwa.y + ws[j].y, ws[j].width, ws[j].height);
 
630
    }
 
631
} /* CreateClipWindows */
 
632
 
 
633
 
 
634
static void 
 
635
DestroyClipWindows(XParms xp, int clips)
 
636
{
 
637
    int j;
 
638
 
 
639
    if (clips > MAXCLIP) clips = MAXCLIP;
 
640
    for (j = 0; j != clips; j++) {
 
641
        XDestroyWindow(xp->d, clipWindows[j]);
 
642
    }
 
643
} /* DestroyClipWindows */
 
644
 
 
645
 
 
646
static double 
 
647
DoTest(XParms xp, Test *test, int reps)
 
648
{
 
649
    double  time;
 
650
    unsigned int ret_width, ret_height;
 
651
 
 
652
    /* Tell screen-saver to restart counting again.  See comments below for the
 
653
       XSetScreenSaver call. */
 
654
    XForceScreenSaver(xp->d, ScreenSaverReset);
 
655
    if ( dontClear == False )
 
656
        XClearWindow( xp->d, xp->w );
 
657
    HardwareSync (xp); 
 
658
    InitTimes ();
 
659
    (*test->proc) (xp, &test->parms, reps);
 
660
    HardwareSync(xp);
 
661
 
 
662
    time = ElapsedTime(syncTime);
 
663
    if (drawToFakeServer)
 
664
        XQueryBestSize(xp->d, TileShape, tileToQuery,
 
665
                       32, 32, &ret_width, &ret_height);
 
666
    (*test->passCleanup) (xp, &test->parms);
 
667
    return time;
 
668
}
 
669
 
 
670
 
 
671
static int 
 
672
CalibrateTest(XParms xp, Test *test, int seconds, double *usecperobj)
 
673
{
 
674
#define goal    2500000.0   /* Try to get up to 2.5 seconds                 */
 
675
#define enough  2000000.0   /* But settle for 2.0 seconds                   */
 
676
#define tick      10000.0   /* Assume clock not faster than .01 seconds     */
 
677
 
 
678
    double  usecs;
 
679
    int     reps, didreps;  /* Reps desired, reps performed                 */
 
680
    int     exponent;
 
681
 
 
682
    /* Attempt to get an idea how long each rep lasts by getting enough
 
683
       reps to last more tan enough.  Then scale that up to the number of
 
684
       seconds desired.
 
685
 
 
686
       If init call to test ever fails, return False and test will be skipped.
 
687
    */
 
688
 
 
689
    if (fixedReps != 0) {
 
690
        return fixedReps;
 
691
    }
 
692
    reps = 1;
 
693
    for (;;) {
 
694
        XDestroySubwindows(xp->d, xp->w);
 
695
        XClearWindow(xp->d, xp->w);
 
696
        didreps = (*test->init) (xp, &test->parms, reps);
 
697
        if (didreps == 0) {
 
698
            return 0;
 
699
        }
 
700
        /* Create clip windows if requested */
 
701
        CreateClipWindows(xp, test->clips);
 
702
        if ( dontClear == False )
 
703
                XClearWindow( xp->d, xp->w );
 
704
        HardwareSync(xp);
 
705
        InitTimes();
 
706
        (*test->proc) (xp, &test->parms, reps);
 
707
        HardwareSync(xp);
 
708
        usecs = ElapsedTime(syncTime);
 
709
        (*test->cleanup) (xp, &test->parms);
 
710
        DestroyClipWindows(xp, test->clips);
 
711
 
 
712
        if (didreps != reps) {
 
713
            /* The test can't do the number of reps as we asked for.  
 
714
               Give up */
 
715
            *usecperobj = 
 
716
                usecs / (double)(didreps * test->parms.objects);
 
717
            return didreps;
 
718
        }
 
719
        /* Did we go long enough? */
 
720
        if (usecs >= enough) break;
 
721
 
 
722
        /* Don't let too short a clock make new reps wildly high */
 
723
        if (usecs < tick) usecs = tick;
 
724
 
 
725
        /* Try to get up to goal seconds. */
 
726
        reps = (int) (goal * (double)reps / usecs) + 1;
 
727
    }
 
728
 
 
729
    *usecperobj = usecs / (double) (reps * test->parms.objects);
 
730
    reps = (int) ((double)seconds * 1000000.0 * (double)reps / usecs) + 1;
 
731
 
 
732
    /* Now round reps up to 1 digit accuracy, so we don't get stupid-looking
 
733
       numbers of repetitions. */
 
734
    reps--;
 
735
    exponent = 1;
 
736
    while (reps > 9) {
 
737
        reps /= 10;
 
738
        exponent *= 10;
 
739
    }
 
740
    reps = (reps + 1) * exponent;
 
741
    return reps;
 
742
} /* CalibrateTest */
 
743
 
 
744
static void 
 
745
CreatePerfGCs(XParms xp, int func, unsigned long pm)
 
746
{
 
747
    XGCValues gcvfg, gcvbg;
 
748
    unsigned long       fg, bg;
 
749
 
 
750
    fg = xp->foreground;
 
751
    bg = xp->background;
 
752
    gcvfg.graphics_exposures = False;
 
753
    gcvbg.graphics_exposures = False;
 
754
    gcvfg.plane_mask = pm;
 
755
    gcvbg.plane_mask = pm;
 
756
    gcvfg.function = func;
 
757
    gcvbg.function = func;
 
758
    
 
759
    if (func == GXxor) {
 
760
        /* Make test look good visually if possible */
 
761
        gcvbg.foreground = gcvfg.foreground = bg ^ fg;
 
762
        gcvbg.background = gcvfg.background = bg;
 
763
    } else {
 
764
        gcvfg.foreground = fg;
 
765
        gcvfg.background = bg;
 
766
        gcvbg.foreground = bg;
 
767
        gcvbg.background = fg;
 
768
    }
 
769
    xp->fggc = XCreateGC(xp->d, xp->w,
 
770
        GCForeground | GCBackground | GCGraphicsExposures
 
771
      | GCFunction | GCPlaneMask, &gcvfg);
 
772
    xp->bggc = XCreateGC(xp->d, xp->w, 
 
773
        GCForeground | GCBackground | GCGraphicsExposures
 
774
      | GCFunction | GCPlaneMask, &gcvbg);
 
775
 
 
776
}
 
777
 
 
778
static void 
 
779
DestroyPerfGCs(XParms xp)
 
780
{
 
781
    XFreeGC(xp->d, xp->fggc);
 
782
    XFreeGC(xp->d, xp->bggc);
 
783
}
 
784
 
 
785
static void 
 
786
DisplayStatus(Display *d, char *message, char *test, int try)
 
787
{
 
788
    char    s[500];
 
789
 
 
790
    XClearWindow(d, status);
 
791
    sprintf(s, "%d %s %s", try, message, test);
 
792
    /* We should really look at the height, descent of the font, etc. but
 
793
       who cares.  This works. */
 
794
    XDrawString(d, status, tgc, 10, 13, s, strlen(s));
 
795
}
 
796
 
 
797
 
 
798
static void 
 
799
ProcessTest(XParms xp, Test *test, int func, unsigned long pm, char *label, 
 
800
            int locreps)
 
801
{
 
802
    double  time, totalTime;
 
803
    int     reps;
 
804
    int     j;
 
805
 
 
806
    CreatePerfGCs(xp, func, pm);
 
807
    if ( showLabels == True )
 
808
    {
 
809
            fprintf( stderr, "'%s'\n", label );
 
810
            fflush( stderr );
 
811
    }
 
812
    if ( loCal == False )
 
813
    {
 
814
            DisplayStatus(xp->d, "Calibrating", label, 0);
 
815
            reps = CalibrateTest(xp, test, seconds, &time);
 
816
    }
 
817
    else
 
818
    {
 
819
        if (fixedReps != 0)
 
820
            reps = fixedReps;
 
821
        else
 
822
            reps = 5;
 
823
    }
 
824
    if ( locreps != -1 )
 
825
        reps = locreps;
 
826
    if (reps != 0) {
 
827
        XDestroySubwindows(xp->d, xp->w);
 
828
        XClearWindow(xp->d, xp->w);
 
829
 
 
830
        /* scale down the reps if needed */
 
831
 
 
832
        reps = (*test->init) (xp, &test->parms, reps);
 
833
        /* Create clip windows if requested */
 
834
        CreateClipWindows(xp, test->clips);
 
835
 
 
836
        totalTime = 0.0;
 
837
        for (j = 0; j != repeat; j++) {
 
838
            if ( sigBail == True )
 
839
                break;    
 
840
            DisplayStatus(xp->d, "Testing", label, j+1);
 
841
            time = DoTest(xp, test, reps);
 
842
            totalTime += time;
 
843
            ReportTimes (time, reps * test->parms.objects,
 
844
                    label, False);
 
845
        }
 
846
        if (repeat > 1) {
 
847
            ReportTimes(totalTime,
 
848
                repeat * reps * test->parms.objects,
 
849
                label, True);
 
850
        }
 
851
        (*test->cleanup) (xp, &test->parms);
 
852
        DestroyClipWindows(xp, test->clips);
 
853
    } else {
 
854
        /* Test failed to initialize properly */
 
855
    }
 
856
    printf ("\n");
 
857
    fflush(stdout);
 
858
    DestroyPerfGCs(xp);
 
859
} /* ProcessTest */
 
860
 
 
861
 
 
862
int
 
863
main(int argc, char *argv[])
 
864
{
 
865
    int         i, j, n;
 
866
    int         numTests;       /* Even though the linker knows, we don't. */
 
867
    char        hostname[100];
 
868
    char        *displayName;
 
869
    Bool        foundOne = False;
 
870
    Bool        synchronous = False;
 
871
    XGCValues   tgcv;
 
872
    int         screen;
 
873
    XVisualInfo *vinfolist, vinfotempl;
 
874
    unsigned long vmask;
 
875
    XieExtensionInfo        *xieInfo;
 
876
    XWindowAttributes attribs;
 
877
    XEvent  event;
 
878
    int done, cclass, timeout;
 
879
    int listTests = 0;
 
880
 
 
881
    CacheInit();
 
882
    dontClear = False;
 
883
    /* Save away argv, argc, for usage to print out */
 
884
    saveargc = argc;
 
885
    saveargv = (char **) malloc(argc * sizeof(char *));
 
886
    for (i = 0; i != argc; i++) {
 
887
        saveargv[i] = argv[i];
 
888
    }
 
889
 
 
890
    xparms.pack = False;
 
891
    xparms.version = 1;
 
892
 
 
893
    /* Count number of tests */
 
894
    ForEachTest(numTests);
 
895
    doit = (Bool *)calloc(numTests, sizeof(Bool));
 
896
 
 
897
    /* Parse arguments */
 
898
    program_name = argv[0];
 
899
    xparms.displayName = displayName = Get_Display_Name (&argc, argv);
 
900
    for (i = 1; i != argc; i++) {
 
901
        if (strcmp (argv[i], "-all") == 0) {
 
902
            ForEachTest (j)
 
903
                doit[j] = True;
 
904
            foundOne = True;
 
905
        } else if (strcmp (argv[i], "-labels") == 0) {
 
906
            labels = True;
 
907
        } else if (strcmp(argv[i], "-range") == 0) {
 
908
            char *cp1;
 
909
            char *cp2;
 
910
            
 
911
            if (argc <= ++i)
 
912
                usage();
 
913
            cp1 = argv[i];
 
914
            if (*cp1 == '-')
 
915
                cp1++;
 
916
            for (cp2 = cp1; *cp2 != '\0' && *cp2 != ','; cp2++) {};
 
917
            if (*cp2 == ',') {
 
918
                *cp2++ = '\0';
 
919
                if (*cp2 == '-')
 
920
                    cp2++;
 
921
            } else {
 
922
                cp2 = "-";
 
923
            }
 
924
            ForEachTest (j) {
 
925
                if (strcmp (cp1, (test[j].option) + 1) == 0 &&
 
926
                    (test[j].versions & xparms.version)) {
 
927
                    int k = j;
 
928
                    do {
 
929
                        doit[k] = True;
 
930
                    } while (strcmp(cp2, (test[k].option + 1)) != 0 &&
 
931
                             (test[k].versions & xparms.version) &&
 
932
                             test[++k].option != NULL);
 
933
                    if (*cp2 != '-' && test[k].option == NULL)
 
934
                        usage();
 
935
                    break;
 
936
                }
 
937
            }
 
938
            if (test[j].option == NULL)
 
939
                usage();
 
940
            foundOne = True;
 
941
        } else if (strcmp (argv[i], "-sync") == 0) {
 
942
            synchronous = True;
 
943
        } else if (strcmp (argv[i], "-images") == 0) {
 
944
                i++;
 
945
                if (argc <= i )
 
946
                        usage();
 
947
                imagepath = argv[i];
 
948
        } else if (strcmp (argv[i], "-timeout") == 0) {
 
949
            i++;
 
950
            if (argc <= i)
 
951
                usage ();
 
952
            timeout = atoi (argv[i]);
 
953
            if (timeout < 0)
 
954
               usage ();
 
955
            else
 
956
               SetTimeout( timeout );
 
957
            
 
958
        } else if (strcmp (argv[i], "-repeat") == 0) {
 
959
            i++;
 
960
            if (argc <= i)
 
961
                usage ();
 
962
            repeat = atoi (argv[i]);
 
963
            if (repeat <= 0)
 
964
               usage ();
 
965
        } else if (strcmp (argv[i], "-time") == 0) {
 
966
            i++;
 
967
            if (argc <= i)
 
968
                usage ();
 
969
            seconds = atoi (argv[i]);
 
970
            if (seconds <= 0)
 
971
               usage ();
 
972
        } else if (strcmp(argv[i], "-reps") == 0) {
 
973
            i++;
 
974
            if (argc <= i)
 
975
                usage ();
 
976
            fixedReps = atoi (argv[i]);
 
977
            if (fixedReps <= 0)
 
978
                usage ();
 
979
        } else if (strcmp(argv[i], "-depth") == 0) {
 
980
            i++;
 
981
            if (argc <= i)
 
982
                usage ();
 
983
            depth = atoi(argv[i]);
 
984
            if (depth <= 0)
 
985
                usage ();
 
986
        } else if (strcmp(argv[i], "-script") == 0) {
 
987
            i++;
 
988
            loadTests = True;
 
989
            if (argc <= i)
 
990
                usage();
 
991
            loadTestsFile = argv[i];
 
992
            foundOne = True;
 
993
        } else if (strcmp(argv[i], "-cache") == 0) {
 
994
            int val;
 
995
            i++;
 
996
            if (argc <= i)
 
997
                usage ();
 
998
            val = atoi(argv[i]);
 
999
            if ( val < 0 )
 
1000
                usage();
 
1001
            if ( val < CacheSizeMax )
 
1002
                val = CacheSizeMax;
 
1003
            CacheSizeMax = val; 
 
1004
        } else if (strcmp(argv[i], "-loCal") == 0) {
 
1005
                loCal = True;
 
1006
        } else if (strcmp(argv[i], "-showtechs") == 0) {
 
1007
                showTechs = True;
 
1008
        } else if (strcmp(argv[i], "-showlabels") == 0) {
 
1009
                showLabels = True;
 
1010
        } else if (strcmp(argv[i], "-events") == 0) {
 
1011
                runEvents = True;
 
1012
        } else if (strcmp(argv[i], "-errors") == 0) {
 
1013
                runErrors = True;
 
1014
        } else if (strcmp(argv[i], "-showevents") == 0) {
 
1015
                showErrors = True;
 
1016
        } else if (strcmp(argv[i], "-GrayScale") == 0) {
 
1017
                visualClass = GrayScale;
 
1018
        } else if (strcmp(argv[i], "-StaticGray") == 0) {
 
1019
                visualClass = StaticGray;
 
1020
        } else if (strcmp(argv[i], "-PseudoColor") == 0) {
 
1021
                visualClass = PseudoColor;
 
1022
        } else if (strcmp(argv[i], "-StaticColor") == 0) {
 
1023
                visualClass = StaticColor;
 
1024
        } else if (strcmp(argv[i], "-DirectColor") == 0) {
 
1025
                visualClass = DirectColor;
 
1026
        } else if (strcmp(argv[i], "-TrueColor") == 0) {
 
1027
                visualClass = TrueColor;
 
1028
        } else if (strcmp(argv[i], "-DIS") == 0) {
 
1029
                class_request = SUBSET_DIS;
 
1030
        } else if (strcmp(argv[i], "-WMSafe") == 0) {
 
1031
                WMSafe = True;
 
1032
        } else if (strcmp(argv[i], "-tests") == 0) {
 
1033
                j = 0;
 
1034
                while (test[j].option != NULL) {
 
1035
                        fprintf(stderr, "    %-24s   %s\n",
 
1036
                                test[j].option, test[j].label);
 
1037
                        j++;
 
1038
                }
 
1039
                exit(0);
 
1040
        } else if (strcmp(argv[i], "-mkscript") == 0) {
 
1041
                listTests = 1;
 
1042
        } else {
 
1043
            ForEachTest (j) {
 
1044
                if (strcmp (argv[i], test[j].option) == 0 &&
 
1045
                    (test[j].versions & xparms.version)) {
 
1046
                    doit[j] = True;
 
1047
                    goto LegalOption;
 
1048
                }
 
1049
            }
 
1050
            usage ();
 
1051
        LegalOption: 
 
1052
                foundOne = True;
 
1053
        }
 
1054
    }
 
1055
 
 
1056
    if ( listTests )
 
1057
    {
 
1058
            j = 0;
 
1059
            while (test[j].option != NULL) {
 
1060
                if ( fixedReps && repeat != DEFAULT_REPEAT )
 
1061
                        fprintf(stderr, "%-30s -repeat %d -reps %d\n",
 
1062
                                &test[j].option[ 1 ], repeat, fixedReps );
 
1063
                else if ( repeat != DEFAULT_REPEAT )
 
1064
                        fprintf(stderr, "%-30s -repeat %d\n",
 
1065
                                &test[j].option[ 1 ], repeat );
 
1066
                else
 
1067
                        fprintf(stderr, "%-30s\n", &test[j].option[ 1 ] );
 
1068
                
 
1069
                j++;
 
1070
            }
 
1071
            exit(0);
 
1072
    }
 
1073
 
 
1074
    if (labels) {
 
1075
        /* Just print out list of tests for use with .sh programs that
 
1076
           assemble data from different xieperf runs into a nice format */
 
1077
        ForEachTest (i) {
 
1078
            if (doit[i] && (test[i].versions & xparms.version)) {
 
1079
                printf ("%s\n", test[i].label);
 
1080
            }
 
1081
        }
 
1082
        exit(0);
 
1083
    }
 
1084
 
 
1085
    if (!foundOne)
 
1086
        usage ();
 
1087
    if ( loadTests == True )
 
1088
    {
 
1089
        if ( !strcmp( loadTestsFile, "-" ) )
 
1090
                fp = stdin;
 
1091
        else
 
1092
                fp = fopen( loadTestsFile, "r" );
 
1093
        if ( fp == ( FILE * ) NULL )
 
1094
        {
 
1095
                fprintf( stderr, "Couldn't open script file '%s'\n",
 
1096
                        loadTestsFile );
 
1097
                fprintf( stderr, "script argument will be ignored\n" );
 
1098
                loadTests = False;
 
1099
        }
 
1100
    }
 
1101
 
 
1102
    xparms.d = Open_Display (displayName);
 
1103
    screen = DefaultScreen(xparms.d);
 
1104
 
 
1105
    /* check for presence of XIE */
 
1106
 
 
1107
    printf("xieperf - XIE performance program, version 1.0\n");
 
1108
    if ( !XieInitialize(xparms.d, &xieInfo ) ) {
 
1109
        printf("\nXIE not supported on this display!\n");
 
1110
        exit(1);
 
1111
    }
 
1112
    printf("\nXIE V%d.%d\n", xieInfo->server_major_rev, 
 
1113
        xieInfo->server_minor_rev);
 
1114
 
 
1115
    capabilities = ( xieInfo->service_class << 8 );     
 
1116
    if ( IsDIS( capabilities ) )
 
1117
        printf( "DIS server\n" );
 
1118
    else
 
1119
        printf( "FULL server\n" );
 
1120
 
 
1121
    if ( IsFull( capabilities ) && IsDIS( class_request ) )
 
1122
    {
 
1123
        printf( "Service class is DIS - running DIS tests only\n" );
 
1124
        capabilities = SUBSET_DIS;
 
1125
    }
 
1126
 
 
1127
    InitEventInfo( xparms.d, xieInfo );
 
1128
    /* get visual info of default visual */
 
1129
    vmask = VisualIDMask | VisualScreenMask;
 
1130
    vinfotempl.visualid = XVisualIDFromVisual(XDefaultVisual(xparms.d, screen));
 
1131
    vinfotempl.screen = screen;
 
1132
    vinfolist = XGetVisualInfo(xparms.d, vmask, &vinfotempl, &n);
 
1133
    if (!vinfolist || n != 1) {
 
1134
        fprintf (stderr, "%s: can't get visual info of default visual\n",
 
1135
            program_name);
 
1136
        exit(1);
 
1137
    }
 
1138
 
 
1139
    if (depth == -1 && visualClass == -1) {
 
1140
        /* use the default visual and colormap */
 
1141
        xparms.vinfo = *vinfolist;
 
1142
        XFree( vinfolist );
 
1143
    } else {
 
1144
        /* find the specified visual */
 
1145
        vmask = VisualScreenMask;
 
1146
        vinfotempl.screen = screen;
 
1147
        if ( depth != -1 )
 
1148
        {
 
1149
                vmask |= VisualDepthMask;
 
1150
                vinfotempl.depth = depth;
 
1151
        }
 
1152
        if ( visualClass != -1 )
 
1153
        {
 
1154
                vmask |= VisualClassMask;
 
1155
#if     defined(__cplusplus) || defined(c_plusplus)
 
1156
                vinfotempl.c_class = visualClass;
 
1157
#else
 
1158
                vinfotempl.class = visualClass; 
 
1159
#endif
 
1160
        }
 
1161
        if ( vinfolist )
 
1162
                XFree( vinfolist );
 
1163
        vinfolist = XGetVisualInfo(xparms.d, vmask, &vinfotempl, &n);
 
1164
        if (!vinfolist) {
 
1165
            fprintf (stderr, 
 
1166
                "%s: can't find an appropriate visual for requested depth and/or class\n", program_name);
 
1167
            exit(1);
 
1168
        }
 
1169
        xparms.vinfo = *vinfolist;  /* use the first one in list */
 
1170
        XFree( vinfolist );
 
1171
    }
 
1172
 
 
1173
#if     defined(__cplusplus) || defined(c_plusplus)
 
1174
    cclass = xparms.vinfo.c_class;
 
1175
#else
 
1176
    cclass = xparms.vinfo.class;
 
1177
#endif
 
1178
    printf( "Screen visual class is " );
 
1179
    switch( cclass )
 
1180
    {
 
1181
        case GrayScale:
 
1182
                printf( "GrayScale\n" );
 
1183
                break;
 
1184
        case StaticGray:
 
1185
                printf( "StaticGray\n" );
 
1186
                break;
 
1187
        case PseudoColor:
 
1188
                printf( "PseudoColor\n" );
 
1189
                break;
 
1190
        case StaticColor:
 
1191
                printf( "StaticColor\n" );
 
1192
                break;
 
1193
        case TrueColor:
 
1194
                printf( "TrueColor\n" );
 
1195
                break;
 
1196
        case DirectColor:
 
1197
                printf( "DirectColor\n" );
 
1198
                break;
 
1199
        default:
 
1200
                printf( "Unknown\n" );
 
1201
                break;
 
1202
    }
 
1203
 
 
1204
    if ( cclass == GrayScale || cclass == PseudoColor || cclass == DirectColor )
 
1205
    {
 
1206
        cmap = graycmap = XCreateColormap(xparms.d, DefaultRootWindow(xparms.d),
 
1207
                xparms.vinfo.visual, AllocAll );
 
1208
        colorcmap = XCreateColormap(xparms.d, DefaultRootWindow(xparms.d),
 
1209
                xparms.vinfo.visual, AllocAll );
 
1210
        emptycmap = XCreateColormap(xparms.d, DefaultRootWindow(xparms.d),
 
1211
                xparms.vinfo.visual, AllocNone );
 
1212
    }
 
1213
    else
 
1214
    {
 
1215
        cmap = graycmap = XCreateColormap(xparms.d, DefaultRootWindow(xparms.d),
 
1216
                xparms.vinfo.visual, AllocNone );
 
1217
        colorcmap = XCreateColormap(xparms.d, DefaultRootWindow(xparms.d),
 
1218
                xparms.vinfo.visual, AllocNone );
 
1219
    }
 
1220
 
 
1221
    if ( WMSafe == False )
 
1222
        XInstallColormap( xparms.d, cmap );
 
1223
    if ( cclass == GrayScale || cclass == PseudoColor || cclass == DirectColor )
 
1224
    { 
 
1225
        AllocateGrayMapColors( &xparms );
 
1226
        xparms.foreground = blackidx;
 
1227
        xparms.background = whiteidx;
 
1228
        AllocateColorMapColors( &xparms );
 
1229
    }
 
1230
    else
 
1231
    {
 
1232
        XColor color;
 
1233
 
 
1234
        color.red = 65535; color.green = 65535; color.blue = 65535;
 
1235
        XAllocColor( xparms.d, cmap, &color );
 
1236
        xparms.background = color.pixel;
 
1237
        color.red = 0; color.green = 0; color.blue = 0;
 
1238
        XAllocColor( xparms.d, cmap, &color );
 
1239
        xparms.foreground = color.pixel;
 
1240
        if ( cclass == TrueColor )
 
1241
        {
 
1242
                int     n_colors;
 
1243
 
 
1244
                SetDirectTrueColorStuff( &xparms, &n_colors );
 
1245
        }
 
1246
        else
 
1247
        {
 
1248
                xparms.screenDepth = DepthFromLevels( xparms.vinfo.colormap_size );
 
1249
        }
 
1250
    }
 
1251
 
 
1252
    printf( "Colormap has %d entries\n", xparms.vinfo.colormap_size );
 
1253
    printf( "Effective depth is %d-bit\n\n", xparms.screenDepth );
 
1254
    if (!foreground) foreground = "Black";
 
1255
    if (!background) background = "White";
 
1256
 
 
1257
    XmuGetHostname (hostname, 100);
 
1258
    printf ("%s server version %d on %s\nfrom %s\n",
 
1259
            ServerVendor (xparms.d), VendorRelease (xparms.d),
 
1260
            DisplayString (xparms.d), hostname);
 
1261
    PrintTime ();
 
1262
 
 
1263
    /* Force screen out of screen-saver mode, grab current data, and set
 
1264
       time to blank to 8 hours.  We should just be able to turn the screen-
 
1265
       saver off, but this causes problems on some servers.  We also reset
 
1266
       the screen-saver timer each test, as 8 hours is about the maximum time
 
1267
       we can use, and that isn't long enough for some X terminals using a
 
1268
       serial protocol to finish all the tests.  As long as the tests run to 
 
1269
       completion, the old screen-saver values are restored. */
 
1270
    XForceScreenSaver(xparms.d, ScreenSaverReset);
 
1271
    XGetScreenSaver(xparms.d, &ssTimeout, &ssInterval, &ssPreferBlanking,
 
1272
        &ssAllowExposures);
 
1273
    (void) signal(SIGINT, Cleanup); /* ^C */
 
1274
#ifdef SIGQUIT
 
1275
    (void) signal(SIGQUIT, Cleanup);
 
1276
#endif
 
1277
    (void) signal(SIGTERM, Cleanup);
 
1278
#ifdef SIGHUP
 
1279
    (void) signal(SIGHUP, Cleanup);
 
1280
#endif
 
1281
    XSetScreenSaver(xparms.d, 8 * 3600, ssInterval, ssPreferBlanking, 
 
1282
        ssAllowExposures);
 
1283
 
 
1284
    if (drawToFakeServer) {
 
1285
        tileToQuery =
 
1286
            XCreatePixmap(xparms.d, DefaultRootWindow (xparms.d), 32, 32, 1);
 
1287
    }
 
1288
    if ( WMSafe == True )
 
1289
    {
 
1290
        xparms.p = CreateXIEParent( &xparms );
 
1291
        XSetTransientForHint( xparms.d, xparms.p, DefaultRootWindow (xparms.d) );
 
1292
        XMapRaised( xparms.d, xparms.p );
 
1293
    }
 
1294
    else
 
1295
        xparms.p = DefaultRootWindow( xparms.d );
 
1296
    xparms.w = CreatePerfWindowUnmapped(&xparms, 2, 2, WIDTH, HEIGHT);
 
1297
    if ( WMSafe == True )
 
1298
        XSetTransientForHint( xparms.d, xparms.w, xparms.p );
 
1299
    monitorWindow = CreatePerfWindowUnmapped(&xparms, WIDTH - 100, 
 
1300
        HEIGHT - 100, MONWIDTH, MONHEIGHT);
 
1301
    if ( WMSafe == True )
 
1302
        XSetTransientForHint( xparms.d, monitorWindow, xparms.p );
 
1303
    monitor2Window = CreatePerfWindowUnmapped(&xparms, WIDTH - 100, 
 
1304
        HEIGHT - 100, MONWIDTH, MONHEIGHT);
 
1305
    if ( WMSafe == True )
 
1306
        XSetTransientForHint( xparms.d, monitor2Window, xparms.p );
 
1307
 
 
1308
    drawableWindow = CreatePerfWindowUnmapped(&xparms, 610, 0, 
 
1309
        WIDTH, HEIGHT);
 
1310
    if ( WMSafe == True )
 
1311
        XSetTransientForHint( xparms.d, drawableWindow, xparms.p );
 
1312
    status = CreatePerfWindowUnmapped(&xparms, 2, HEIGHT+5, WIDTH, 20);
 
1313
    if ( WMSafe == True )
 
1314
        XSetTransientForHint( xparms.d, status, xparms.p );
 
1315
    tgcv.foreground = xparms.foreground;
 
1316
    tgcv.background = xparms.background;
 
1317
    tgc = XCreateGC(xparms.d, status, GCForeground | GCBackground, &tgcv);
 
1318
 
 
1319
    if (synchronous)
 
1320
        XSynchronize (xparms.d, True);
 
1321
 
 
1322
    /* Get mouse pointer out of the way of the performance window.  On
 
1323
       software cursor machines it will slow graphics performance.  On
 
1324
       all current MIT-derived servers it will slow window 
 
1325
       creation/configuration performance. */
 
1326
    XGetWindowAttributes( xparms.d, DefaultRootWindow( xparms.d ), &attribs );
 
1327
    XSync( xparms.d, 0 );
 
1328
 
 
1329
    /* wait for first expose event before we trudge forward */
 
1330
 
 
1331
    XSelectInput( xparms.d, xparms.w, ExposureMask );
 
1332
    XSync( xparms.d, 0 );
 
1333
    XMapWindow( xparms.d, xparms.w );
 
1334
    XMapWindow( xparms.d, status );
 
1335
 
 
1336
    done = 0;
 
1337
    while( done == 0 )
 
1338
    {
 
1339
        XNextEvent( xparms.d, &event );
 
1340
        switch( event.type )
 
1341
        {
 
1342
                case Expose:
 
1343
                        done = 1;
 
1344
                        break;
 
1345
        }
 
1346
    }
 
1347
 
 
1348
    if ( WMSafe == True )
 
1349
            XWarpPointer(xparms.d, None, xparms.p, 0, 0, 0, 0, 10, HEIGHT+30);
 
1350
    else
 
1351
            XWarpPointer(xparms.d, None, DefaultRootWindow( xparms.d ), 
 
1352
                0, 0, 0, 0, 10, HEIGHT+30);
 
1353
 
 
1354
    /* Figure out how long to call HardwareSync, so we can adjust for that
 
1355
       in our total elapsed time */
 
1356
 
 
1357
    (void) CalibrateTest(&xparms, &syncTest, 1, &syncTime);
 
1358
    printf("Sync time adjustment is %6.4f msecs.\n\n", syncTime/1000);
 
1359
 
 
1360
    if (showTechs)
 
1361
        ListAllTechs( &xparms );
 
1362
 
 
1363
    if ( loadTests == False )
 
1364
    {
 
1365
        ForEachTest (i) {
 
1366
 
 
1367
                char label[200];
 
1368
 
 
1369
                if ( !EventOrErrorValid( test[ i ].parms.description ) )
 
1370
                        continue;
 
1371
                if (doit[i] && (test[i].versions & xparms.version) && ServerIsCapable( test[ i ].parms.description ) ) {
 
1372
                        strcpy (label, test[i].label);
 
1373
                        ProcessTest(&xparms, &test[i], GXcopy, ~((unsigned long)0), label, -1);
 
1374
                        if ( sigBail == True )
 
1375
                            break;
 
1376
                } /* if doit */
 
1377
            } /* ForEachTest */
 
1378
    }
 
1379
    else
 
1380
    {
 
1381
        Bool    done;
 
1382
        int     repeattmp, 
 
1383
                repeatsave;
 
1384
        int     reps;
 
1385
        done = False;
 
1386
 
 
1387
        while ( done == False )
 
1388
        {
 
1389
                if ( sigBail == True )
 
1390
                    break;
 
1391
                repeattmp = repeatsave = -1;
 
1392
                if ( ( i = GetNextTest( fp, &repeattmp, &reps ) ) < 0 )
 
1393
                        done = True;
 
1394
                else
 
1395
                {
 
1396
                        char label[200];
 
1397
 
 
1398
                        if ( !EventOrErrorValid( test[ i ].parms.description ) )
 
1399
                                continue;
 
1400
                        if ((test[i].versions & xparms.version) && 
 
1401
                                ServerIsCapable( test[ i ].parms.description ) )
 
1402
                        {
 
1403
                                strcpy (label, test[i].label);
 
1404
                                if ( repeattmp != -1 )
 
1405
                                {
 
1406
                                        repeatsave = repeat;
 
1407
                                        repeat = repeattmp;
 
1408
                                }
 
1409
                                ProcessTest(&xparms, 
 
1410
                                        &test[i], GXcopy, ~0L, label, reps);
 
1411
                                if ( repeattmp != -1 )
 
1412
                                        repeat = repeatsave;
 
1413
                        }
 
1414
                }
 
1415
        }
 
1416
    }
 
1417
 
 
1418
    if ( fp != ( FILE * ) NULL )
 
1419
        fclose( fp );
 
1420
    ReclaimPhotomapMemory();    /* shut up Purify :-) */
 
1421
 
 
1422
    if ( WMSafe == True )
 
1423
    {
 
1424
            XUnmapWindow(xparms.d, xparms.p );
 
1425
            XSync( xparms.d, 0 );
 
1426
            XDestroyWindow(xparms.d, xparms.p );
 
1427
    }
 
1428
    else
 
1429
            XDestroyWindow(xparms.d, xparms.w);
 
1430
    /* Restore ScreenSaver to original state. */
 
1431
    XSetScreenSaver(xparms.d, ssTimeout, ssInterval, ssPreferBlanking,
 
1432
        ssAllowExposures);
 
1433
    if ( RGB_BESTStandardColormapObtained == True )
 
1434
        XmuDeleteStandardColormap( xparms.d, DefaultScreen( xparms.d ),
 
1435
                XA_RGB_BEST_MAP );
 
1436
    XCloseDisplay(xparms.d);
 
1437
    exit(0);
 
1438
}
 
1439
 
 
1440
int
 
1441
TestIndex(char *testname)
 
1442
{
 
1443
        int     j, found;
 
1444
 
 
1445
        found = -1;
 
1446
        ForEachTest (j) 
 
1447
        {
 
1448
                if (strcmp (testname, (test[j].option) + 1) == 0 )
 
1449
                {
 
1450
                        found = j;
 
1451
                        break;
 
1452
                }
 
1453
        }
 
1454
        return( found );
 
1455
}
 
1456
 
 
1457
static Window
 
1458
CreateXIEParent(XParms xp)
 
1459
{
 
1460
        Window root, ret;
 
1461
        unsigned int width, height, border_width, depth;
 
1462
        XSetWindowAttributes xswa;
 
1463
        int x, y;
 
1464
        int hasBS;
 
1465
        unsigned long value_mask;
 
1466
 
 
1467
/* 
 
1468
        Time for a little explaining...
 
1469
 
 
1470
        Xieperf puts up windows, moves them around, and associates
 
1471
        colormaps with windows. If no window manager is running, then 
 
1472
        things are fine - I don't even call this function. I just set 
 
1473
        the window attribute override_redirect = True at window creation 
 
1474
        time, and associate my grayscale colormap with the window at 
 
1475
        creation time also.
 
1476
 
 
1477
        If a window manager is running, I need to be nice. Nice means
 
1478
        allow the window manager to install colormaps as my windows
 
1479
        gain focus, and let the manager control any geometry changes
 
1480
        that I issue. 
 
1481
 
 
1482
        The user, when a window manager is running, is required to use 
 
1483
        the -WMSafe argument to xieperf to indicate to me that a window
 
1484
        manager is running. If this arg is given, then I do the following:
 
1485
 
 
1486
        I make a child window of the root window which acts as the parent 
 
1487
        window for xieperf's windows. I use XSetTransientForHint() to tell
 
1488
        the window manager essentially that each child window of this 
 
1489
        parent is a transient window so please don't mess with my geometry
 
1490
        requests and please install the colormap associated with each
 
1491
        child window as that window gains focus.
 
1492
 
 
1493
        Since the parent window has dimensions equal to the root window,
 
1494
        the app will have focus and my colormap ( which is also the color 
 
1495
        map of the parent window ) will be installed ( assuming the
 
1496
        graciousness of the window manager ). Also, any child windows will 
 
1497
        appear, disappear, and be moved at my command. Finally, it was
 
1498
        my goal to make the parent window transparent, so it has the usual 
 
1499
        root window appearance. This could be done by calling the function
 
1500
        XSetWindowBackgroundPixmap(), and specifying ParentRelative as its
 
1501
        final argument.
 
1502
 
 
1503
        But I ran into problems. I got the desired effects - namely window
 
1504
        placement, colormap handling, and the transparency thing all seemed
 
1505
        o.k., but under twm my parent window would not clear itself when
 
1506
        child windows were unmapped, nor would it respond to XClearWindow()
 
1507
        calls. Turning backing store on for the parent window fixed the
 
1508
        problem, but that is not a viable solution since backing store isn't
 
1509
        always around to help. And, when running under mwm, bizarro effects 
 
1510
        like side-by-side mirror images of a child window would appear. It
 
1511
        was dazzling, but unappreciated...
 
1512
 
 
1513
        My solution was simple. If this function is called, and the server 
 
1514
        currently supports backing store, I use that, go for the transparent
 
1515
        window, and things are happy.
 
1516
 
 
1517
        If this function is called and there is no backing store support, 
 
1518
        instead of having a transparent parent window, the parent window is 
 
1519
        created with a background pixel of BlackPixel ( also it was shown
 
1520
        that while the transparent version of the parent window never cleared 
 
1521
        either on its own or explicitly via XClearWindow(), windows that had
 
1522
        normal pixel-based backgrounds would clear themselves whenever the 
 
1523
        child windows were unmapped ).
 
1524
 
 
1525
        Comments would be appreciated... there should be a way to do this
 
1526
        that isn't too painful. The Xlib Programming Manual ( O'Reilly
 
1527
        Volume 1, p 96 ) states that if ParentRelative is used as a 
 
1528
        backround pixmap, the backgrounds are automatically repainted on
 
1529
        exposure. As the above states, they aren't. My feeling is that there 
 
1530
        is a bug in the R5 cfb code or...
 
1531
*/ 
 
1532
 
 
1533
        hasBS = DoesBackingStore( DefaultScreenOfDisplay( xp->d ) );
 
1534
        XGetGeometry( xp->d, DefaultRootWindow( xp->d ), &root, &x, &y,
 
1535
                &width, &height, &border_width, &depth );
 
1536
 
 
1537
        xswa.colormap = cmap;
 
1538
        if ( hasBS )
 
1539
        {
 
1540
                xswa.backing_store = WhenMapped;
 
1541
        }
 
1542
        else
 
1543
        {
 
1544
                xswa.background_pixel = 
 
1545
                        BlackPixel( xp->d, DefaultScreen( xp->d ) );
 
1546
        }
 
1547
        value_mask = CWColormap | ( hasBS ? CWBackingStore : CWBackPixel );
 
1548
        ret = XCreateWindow( xp->d, DefaultRootWindow( xp->d ),
 
1549
                x, y, width, height, border_width, xp->vinfo.depth, 
 
1550
                CopyFromParent, xp->vinfo.visual, 
 
1551
                value_mask, &xswa );
 
1552
 
 
1553
        if ( hasBS )
 
1554
        {
 
1555
                /* make it transparent */
 
1556
 
 
1557
                XSetWindowBackgroundPixmap( xp->d, ret, ParentRelative );       
 
1558
        }
 
1559
        return( ret );
 
1560
}
 
1561
 
 
1562
static void
 
1563
AllocateGrayMapColors(XParms xp)
 
1564
{
 
1565
        int     i, n_colors;
 
1566
        long    intensity, rintensity, gintensity, bintensity;
 
1567
        XColor  *gray = ( XColor * ) NULL;
 
1568
        int     cclass;
 
1569
        int     maxcoloridx;
 
1570
 
 
1571
        /* get what we can, and remember it. we should get all since
 
1572
           we created the colormap */
 
1573
 
 
1574
        gray = ( XColor * ) malloc(sizeof( XColor ) * xp->vinfo.colormap_size);
 
1575
        if ( gray == ( XColor * ) NULL )
 
1576
        {
 
1577
                fprintf( stderr, "Couldn't allocate XColor vector for XAllocColorCells\n" );
 
1578
                exit( 1 );
 
1579
        }
 
1580
 
 
1581
        n_colors = 0;
 
1582
#if     defined(__cplusplus) || defined(c_plusplus)
 
1583
        cclass = xp->vinfo.c_class;
 
1584
#else
 
1585
        cclass = xp->vinfo.class;
 
1586
#endif
 
1587
 
 
1588
        if ( cclass == DirectColor )
 
1589
        {
 
1590
                SetDirectTrueColorStuff( xp, &n_colors );
 
1591
        }
 
1592
        else
 
1593
        {
 
1594
                n_colors = xp->vinfo.colormap_size;
 
1595
                xp->screenDepth = DepthFromLevels( n_colors );
 
1596
        }
 
1597
 
 
1598
        /* do a grey scale ramp */
 
1599
 
 
1600
        maxcoloridx = n_colors - 1;
 
1601
 
 
1602
        if ( cclass == DirectColor )
 
1603
        {
 
1604
                for (i=0; i<n_colors; i++) {
 
1605
                        rintensity = ( (i*65535L) / (long) (n_colors-1) );
 
1606
                        gintensity = ( (i*65535L) / (long) (n_colors-1) );
 
1607
                        bintensity = ( (i*65535L) / (long) (n_colors-1) );
 
1608
                        gray[i].pixel = i * lowbit( DCRedMask );
 
1609
                        gray[i].pixel |= i * lowbit( DCGreenMask );
 
1610
                        gray[i].pixel |= i * lowbit( DCBlueMask );
 
1611
                        gray[i].red = rintensity;
 
1612
                        gray[i].green = gintensity;
 
1613
                        gray[i].blue = bintensity;
 
1614
                        gray[i].flags = DoRed | DoGreen | DoBlue;
 
1615
                }
 
1616
        }
 
1617
        else
 
1618
        {
 
1619
                for (i=0; i<n_colors; i++) {
 
1620
                        intensity = (i*65535L) / (long) (n_colors-1);
 
1621
                        gray[i].pixel = i;
 
1622
                        gray[i].red   = intensity;
 
1623
                        gray[i].green = intensity;
 
1624
                        gray[i].blue  = intensity;
 
1625
                        gray[i].flags = DoRed | DoGreen | DoBlue;
 
1626
                }
 
1627
        }
 
1628
        whiteidx = gray[ maxcoloridx ].pixel;
 
1629
        blackidx = gray[ 0 ].pixel;
 
1630
        if ( n_colors )
 
1631
        {
 
1632
                XStoreColors(xp->d,graycmap,gray,n_colors);
 
1633
                XSync(xp->d,0);
 
1634
        }       
 
1635
        else
 
1636
        {
 
1637
                fprintf( stderr, "Couldn't allocate colors in colormap\n" );
 
1638
                if ( gray )
 
1639
                        free( gray );
 
1640
                exit( 0 );
 
1641
        }
 
1642
        if ( gray )
 
1643
                free( gray );
 
1644
}
 
1645
 
 
1646
static void
 
1647
AllocateColorMapColors(XParms xp)
 
1648
{
 
1649
        int     i, n_colors;
 
1650
        long    intensity, rintensity, gintensity, bintensity;
 
1651
        XColor  *gray = ( XColor * ) NULL;
 
1652
        int     cclass;
 
1653
        int     maxcoloridx;
 
1654
 
 
1655
        /* get what we can, and remember it. we should get all since
 
1656
           we created the colormap */
 
1657
 
 
1658
        gray = ( XColor * ) malloc(sizeof( XColor ) * xp->vinfo.colormap_size);
 
1659
        if ( gray == ( XColor * ) NULL )
 
1660
        {
 
1661
                fprintf( stderr, "Couldn't allocate XColor vector for XAllocColorCells\n" );
 
1662
                exit( 1 );
 
1663
        }
 
1664
 
 
1665
        n_colors = 0;
 
1666
#if     defined(__cplusplus) || defined(c_plusplus)
 
1667
        cclass = xp->vinfo.c_class;
 
1668
#else
 
1669
        cclass = xp->vinfo.class;
 
1670
#endif
 
1671
 
 
1672
        if ( cclass == DirectColor )
 
1673
        {
 
1674
                SetDirectTrueColorStuff( xp, &n_colors );
 
1675
        }
 
1676
        else
 
1677
        {
 
1678
                n_colors = xp->vinfo.colormap_size;
 
1679
                xp->screenDepth = DepthFromLevels( n_colors );
 
1680
        }
 
1681
 
 
1682
        /* do a grey scale ramp */
 
1683
 
 
1684
        maxcoloridx = n_colors - 1;
 
1685
 
 
1686
        if ( cclass == DirectColor )
 
1687
        {
 
1688
                for (i=0; i<n_colors; i++) {
 
1689
                        rintensity = ( (i*65535L) / (long) (n_colors-1) );
 
1690
                        gintensity = ( (i*65535L) / (long) (n_colors-1) );
 
1691
                        bintensity = ( (i*65535L) / (long) (n_colors-1) );
 
1692
                        gray[i].pixel = i * lowbit( DCRedMask );
 
1693
                        gray[i].pixel |= i * lowbit( DCGreenMask );
 
1694
                        gray[i].pixel |= i * lowbit( DCBlueMask );
 
1695
                        gray[i].red = rintensity;
 
1696
                        gray[i].green = gintensity;
 
1697
                        gray[i].blue = bintensity;
 
1698
                        gray[i].flags = DoRed | DoGreen | DoBlue;
 
1699
                }
 
1700
        }
 
1701
        else
 
1702
        {
 
1703
                for (i=0; i<n_colors; i++) {
 
1704
                        intensity = (i*65535L) / (long) (n_colors-1);
 
1705
                        gray[i].pixel = i;
 
1706
                        gray[i].red   = intensity;
 
1707
                        gray[i].green = intensity;
 
1708
                        gray[i].blue  = intensity;
 
1709
                        gray[i].flags = DoRed | DoGreen | DoBlue;
 
1710
                }
 
1711
        }
 
1712
        if ( n_colors )
 
1713
        {
 
1714
                XStoreColors(xp->d,colorcmap,gray,n_colors);
 
1715
                XSync(xp->d,0);
 
1716
        }       
 
1717
        else
 
1718
        {
 
1719
                fprintf( stderr, "Couldn't allocate colors in colormap\n" );
 
1720
                if ( gray )
 
1721
                        free( gray );
 
1722
                exit( 0 );
 
1723
        }
 
1724
        if ( gray )
 
1725
                free( gray );
 
1726
}
 
1727
 
 
1728
static void
 
1729
SetDirectTrueColorStuff(XParms xp, int *n_colors )
 
1730
{
 
1731
        unsigned long mask;
 
1732
 
 
1733
        DCRedMask = xp->vinfo.red_mask;
 
1734
        DCGreenMask = xp->vinfo.green_mask;
 
1735
        DCBlueMask = xp->vinfo.blue_mask;
 
1736
 
 
1737
        mask = 1L << ( ( sizeof( long ) << 3 ) - 1 );
 
1738
        rbits = gbits = bbits = 0;
 
1739
 
 
1740
        while ( mask )
 
1741
        {
 
1742
                if ( mask & DCRedMask ) rbits+=1;
 
1743
                else if ( mask & DCGreenMask ) gbits+=1;
 
1744
                else if ( mask & DCBlueMask ) bbits+=1;
 
1745
                mask = mask >> 1;
 
1746
        }
 
1747
        xp->screenDepth = MIN( rbits, MIN( gbits, bbits ) );
 
1748
        if ( xp->screenDepth == rbits && xp->screenDepth == gbits &&
 
1749
                xp->screenDepth == bbits )
 
1750
        {
 
1751
                xp->screenDepth = rbits + gbits + bbits;
 
1752
                *n_colors = 1 << rbits;
 
1753
        }
 
1754
        else
 
1755
        {
 
1756
                *n_colors = 1 << xp->screenDepth;
 
1757
        }
 
1758
}
 
1759
 
 
1760
#ifdef notyet
 
1761
static int
 
1762
GetWords(int argi, int argc, char **argv, char **wordsp, int *nump)
 
1763
{
 
1764
    int     count;
 
1765
 
 
1766
    if (argc <= argi)
 
1767
        usage();
 
1768
    count = 0;
 
1769
    while (argv[argi] && *(argv[argi]) != '-') {
 
1770
        *wordsp++ = argv[argi];
 
1771
        ++argi;
 
1772
        count++;
 
1773
    }
 
1774
    *nump = count;
 
1775
    return count;
 
1776
}
 
1777
 
 
1778
static int
 
1779
atox(char *s)
 
1780
{
 
1781
    int     v, c;
 
1782
 
 
1783
    v = c = 0;
 
1784
    while (*s) {
 
1785
        if ('0' <= *s && *s <= '9')
 
1786
            c = *s - '0';
 
1787
        else if ('a' <= *s && *s <= 'f')
 
1788
            c = *s - 'a' + 10;
 
1789
        else if ('A' <= *s && *s <= 'F')
 
1790
            c = *s - 'A' + 10;
 
1791
        v = v * 16 + c;
 
1792
        s++;
 
1793
    }
 
1794
    return v;
 
1795
}
 
1796
 
 
1797
static int 
 
1798
GetNumbers(int argi, int argc, char **argv, int *intsp, int *nump)
 
1799
{
 
1800
    char    *words[256];
 
1801
    int     count;
 
1802
    int     i;
 
1803
    int     flip;
 
1804
 
 
1805
    count = GetWords (argi, argc, argv, words, nump);
 
1806
    for (i = 0; i < count; i++) {
 
1807
        flip = 0;
 
1808
        if (!strncmp (words[i], "~", 1)) {
 
1809
            words[i]++;
 
1810
            flip = ~0;
 
1811
        }
 
1812
        if (!strncmp (words[i], "0x", 2))
 
1813
            intsp[i] = atox(words[i] + 2) ^ flip;
 
1814
        else
 
1815
            intsp[i] = atoi (words[i]) ^ flip;
 
1816
    }
 
1817
    return count;
 
1818
}
 
1819
#endif
 
1820
 
 
1821
static void
 
1822
SendTripleBandPlaneDataSequential(XParms xp, Parms p, int flo_id, 
 
1823
                                  XiePhotospace photospace, int element, 
 
1824
                                  char *data, int size, 
 
1825
                                  unsigned char pixel_stride[3], 
 
1826
                                  unsigned char left_pad[3], 
 
1827
                                  unsigned char scanline_pad[3],
 
1828
                                  XieLTriplet width, XieLTriplet height )
 
1829
{
 
1830
        int     band1, band2, band3;
 
1831
 
 
1832
        /* calculate band sizes */
 
1833
 
 
1834
        band1 = ( ( left_pad[ 0 ] >> 3 ) + 
 
1835
                ( width[ 0 ] * ( pixel_stride[ 0 ] >> 3 ) ) ) * height[ 0 ];
 
1836
        ScanlinePad( &band1, scanline_pad[ 0 ] );
 
1837
        band2 = ( ( left_pad[ 1 ] >> 3 ) + 
 
1838
                ( width[ 1 ] * ( pixel_stride[ 1 ] >> 3 ) ) ) * height[ 1 ];
 
1839
        ScanlinePad( &band2, scanline_pad[ 1 ] );
 
1840
        band3 = ( ( left_pad[ 2 ] >> 3 ) + 
 
1841
                ( width[ 2 ] * ( pixel_stride[ 2 ] >> 3 ) ) ) * height[ 2 ];
 
1842
        ScanlinePad( &band3, scanline_pad[ 0 ] );
 
1843
 
 
1844
        /* fire away! */
 
1845
 
 
1846
        PumpTheClientData( xp, p, flo_id, photospace, element, data, band1, 0 );
 
1847
        data += band1;
 
1848
        PumpTheClientData( xp, p, flo_id, photospace, element, data, band2, 1 );
 
1849
        data += band2;
 
1850
        PumpTheClientData( xp, p, flo_id, photospace, element, data, band3, 2 );
 
1851
        data += band3;
 
1852
}
 
1853
 
 
1854
static void
 
1855
ScanlinePad(int *value, int pad)
 
1856
{
 
1857
        int     newval;
 
1858
 
 
1859
        if ( !( *value == 0 || pad == 0 || pad == 1 ) )
 
1860
        {
 
1861
                if ( ( *value % pad ) != 0 )
 
1862
                {
 
1863
                        if ( *value < pad )
 
1864
                        {
 
1865
                                *value = pad;
 
1866
                        }
 
1867
                        else
 
1868
                        {
 
1869
                                newval = pad;
 
1870
                                while ( newval < *value )
 
1871
                                        newval += pad;
 
1872
                                *value = newval;
 
1873
                        }
 
1874
                }
 
1875
        }
 
1876
}
 
1877
 
 
1878
void    
 
1879
PumpTheClientData(XParms xp, Parms p, int flo_id, XiePhotospace photospace, 
 
1880
                  int element, char *data, int size, int band_number )
 
1881
{
 
1882
        int     bytes_left, final, nbytes;
 
1883
 
 
1884
        final = 0;
 
1885
        bytes_left = size;
 
1886
        while (bytes_left > 0) {
 
1887
                nbytes = (bytes_left > p->buffer_size) ?
 
1888
                        p->buffer_size: bytes_left;
 
1889
                if (nbytes >= bytes_left)
 
1890
                        final = 1;
 
1891
                XiePutClientData (
 
1892
                        xp->d,
 
1893
                        photospace,
 
1894
                        flo_id,
 
1895
                        element,        /* element */
 
1896
                        final,          /* signal that this is all the data */
 
1897
                        band_number,    /* 0 for all but triple band data 
 
1898
                                           BandByPlane, which then may be
 
1899
                                           0, 1, or 2 */
 
1900
                        (unsigned char *) data,
 
1901
                        nbytes
 
1902
                );
 
1903
                bytes_left -= nbytes;
 
1904
                data += nbytes;
 
1905
        }
 
1906
}
 
1907
 
 
1908
int     
 
1909
ReadNotifyExportData(XParms xp, Parms p, unsigned long namespace, int flo_id, 
 
1910
                     XiePhototag element, unsigned int elementsz, 
 
1911
                     unsigned int numels, char **data, int *done )
 
1912
{
 
1913
        char    *cp, *ptr;
 
1914
        Bool    terminate = False;
 
1915
        XieExportState new_state_ret;
 
1916
        unsigned int nbytes;
 
1917
        unsigned int nbytes_ret;
 
1918
        Bool    no_errors, reallocFlag;
 
1919
        unsigned int cnt;
 
1920
        int bytes;
 
1921
 
 
1922
        *done = 0;
 
1923
        if ( numels == 0 )
 
1924
        {
 
1925
                numels = WaitForXIEEvent( xp, xieEvnNoExportAvailable,
 
1926
                        flo_id, element, False );
 
1927
                if ( numels == 0 )
 
1928
                        return( -1 );
 
1929
        }
 
1930
 
 
1931
        nbytes = numels * elementsz;    
 
1932
        bytes = nbytes;
 
1933
        no_errors = True;
 
1934
        reallocFlag = False;
 
1935
        cnt = 0;
 
1936
        if ( *data == ( char * ) NULL )
 
1937
        {
 
1938
                if ( ( *data = ( char * ) malloc( nbytes ) ) == ( char * ) NULL )
 
1939
                {
 
1940
                        fprintf( stderr, "ReadNotifyExportData: couldn't allocate data\n" );
 
1941
                        return( 0 );
 
1942
                }
 
1943
        }
 
1944
        ptr = *data;
 
1945
        while ( 1 )             
 
1946
        {  
 
1947
                XieGetClientData ( xp->d, namespace, flo_id, element,  
 
1948
                        bytes > 2048 ? 2048 : bytes, terminate, 0,
 
1949
                        &new_state_ret, (unsigned char **)&cp, &nbytes_ret );
 
1950
 
 
1951
                if ( nbytes_ret && reallocFlag )
 
1952
                {
 
1953
                        *data = realloc( *data, cnt + nbytes_ret );
 
1954
                        if ( *data == ( char * ) NULL )
 
1955
                        {
 
1956
                                /* oh no */
 
1957
                                        
 
1958
                                fprintf( stderr, "ReadNotifyExportData: realloc failed\n" );    
 
1959
                                no_errors = False;
 
1960
                                break;
 
1961
                        }       
 
1962
                        ptr = *data + cnt;
 
1963
                }
 
1964
 
 
1965
/* this rots */
 
1966
 
 
1967
                memcpy( ptr, cp, nbytes_ret * sizeof( char ) ); 
 
1968
                ptr += nbytes_ret * sizeof( char );
 
1969
                XFree( cp );
 
1970
 
 
1971
                cnt += nbytes_ret;      
 
1972
                bytes -= nbytes_ret;
 
1973
                if ( new_state_ret == xieValExportEmpty )
 
1974
                        WaitForXIEEvent( xp, xieEvnNoExportAvailable,
 
1975
                                flo_id, element, False );
 
1976
                else if ( new_state_ret == xieValExportMore ) 
 
1977
                {
 
1978
                        if ( bytes <= 0 )
 
1979
                        {
 
1980
                                reallocFlag = True;
 
1981
                                bytes = 2048;
 
1982
                        }
 
1983
                }
 
1984
                else if ( new_state_ret == xieValExportDone ) 
 
1985
                {
 
1986
                        *done = 1;
 
1987
                        break;
 
1988
                }
 
1989
                else if ( new_state_ret == xieValExportError )
 
1990
                {
 
1991
                        fprintf( stderr, "ReadNotifyExportData: xieValExportError received from XieGetClientData\n" );
 
1992
                        no_errors = False;
 
1993
                        break;
 
1994
                }
 
1995
 
 
1996
                if ( bytes <= 0 && reallocFlag == False )
 
1997
                {
 
1998
                        /* if we get here, we didn't get an ExportDone,
 
1999
                           and we have no buffer space left. So turn on 
 
2000
                           the realloc flag. Also, server could be not
 
2001
                           sending the ExportDone for some reason...
 
2002
                           if so XIE or xieperf or both may be broken. */
 
2003
                        
 
2004
                        bytes = 2048;
 
2005
                        reallocFlag = True;
 
2006
                }
 
2007
        }
 
2008
        if ( no_errors == False )
 
2009
        {
 
2010
                return( -1 );
 
2011
        }
 
2012
        return( cnt );
 
2013
}
 
2014
 
 
2015
int     
 
2016
ReadNotifyExportTripleData(XParms xp, Parms p, unsigned long namespace, 
 
2017
                           int flo_id, XiePhototag element, 
 
2018
                           unsigned int elementsz, 
 
2019
                           unsigned int numels, char **data, int *done )
 
2020
{
 
2021
        char    *cp, *ptr;
 
2022
        Bool    terminate = False;
 
2023
        XieExportState new_state_ret;
 
2024
        unsigned int nbytes;
 
2025
        unsigned int nbytes_ret;
 
2026
        Bool    no_errors, reallocFlag;
 
2027
        unsigned int cnt;
 
2028
        int bytes;
 
2029
        int band;
 
2030
 
 
2031
        *done = 0;
 
2032
        if ( numels == 0 )
 
2033
        {
 
2034
                numels = WaitForXIEEvent( xp, xieEvnNoExportAvailable,
 
2035
                        flo_id, element, False );
 
2036
                if ( numels == 0 )
 
2037
                        return( -1 );
 
2038
                fprintf( stderr, "There are %d elements available\n", numels );
 
2039
        }
 
2040
 
 
2041
        nbytes = numels * elementsz;    
 
2042
        bytes = nbytes;
 
2043
        no_errors = True;
 
2044
        reallocFlag = False;
 
2045
        cnt = 0;
 
2046
        if ( *data == ( char * ) NULL )
 
2047
        {
 
2048
                if ( ( *data = ( char * ) malloc( nbytes ) ) == ( char * ) NULL )
 
2049
                {
 
2050
                        fprintf( stderr, "ReadNotifyExportTripleData: couldn't allocate data\n" );
 
2051
                        return( 0 );
 
2052
                }
 
2053
        }
 
2054
        ptr = *data;
 
2055
        for ( band = 0; band < 3; band++ )
 
2056
        {
 
2057
                while ( 1 )             
 
2058
                {  
 
2059
                        XieGetClientData ( xp->d, namespace, flo_id, element,  
 
2060
                                bytes > 2048 ? 2048 : bytes, terminate, band,
 
2061
                                &new_state_ret, (unsigned char **)&cp, 
 
2062
                                &nbytes_ret );
 
2063
 
 
2064
                        if ( nbytes_ret && reallocFlag )
 
2065
                        {
 
2066
                                *data = realloc( *data, cnt + nbytes_ret );
 
2067
                                if ( *data == ( char * ) NULL )
 
2068
                                {
 
2069
                                        /* oh no */
 
2070
                                                
 
2071
                                        fprintf( stderr, "ReadNotifyExportTripleData: realloc failed\n" );      
 
2072
                                        no_errors = False;
 
2073
                                        break;
 
2074
                                }       
 
2075
                                ptr = *data + cnt;
 
2076
                        }
 
2077
 
 
2078
                        memcpy( ptr, cp, nbytes_ret * sizeof( char ) ); 
 
2079
                        ptr += nbytes_ret * sizeof( char );
 
2080
                        XFree( cp );
 
2081
 
 
2082
                        cnt += nbytes_ret;      
 
2083
                        bytes -= nbytes_ret;
 
2084
                        if ( new_state_ret == xieValExportEmpty )
 
2085
                                WaitForXIEEvent( xp, xieEvnNoExportAvailable,
 
2086
                                        flo_id, element, False );
 
2087
                        else if ( new_state_ret == xieValExportMore ) 
 
2088
                        {
 
2089
                                if ( bytes <= 0 )
 
2090
                                        reallocFlag = True;
 
2091
                                bytes = 2048;
 
2092
                        }
 
2093
                        else if ( new_state_ret == xieValExportDone ) 
 
2094
                        {
 
2095
                                *done = 1;
 
2096
                                break;
 
2097
                        }
 
2098
                        else if ( new_state_ret == xieValExportError )
 
2099
                        {
 
2100
                                fprintf( stderr, "ReadNotifyExportTripleData: xieValExportError received from XieGetClientData\n" );
 
2101
                                no_errors = False;
 
2102
                                break;
 
2103
                        }
 
2104
                        if ( bytes <= 0 && reallocFlag == False )
 
2105
                        {
 
2106
                                bytes = 2048;
 
2107
                                reallocFlag = True;
 
2108
                        }
 
2109
                }
 
2110
        }
 
2111
        if ( no_errors == False )
 
2112
        {
 
2113
                return( -1 );
 
2114
        }
 
2115
        return( cnt );
 
2116
}
 
2117
 
 
2118
unsigned int
 
2119
CheckSum(char *data, unsigned int size)
 
2120
{
 
2121
        unsigned int sum, i;
 
2122
 
 
2123
        sum = 0;
 
2124
        for ( i = 0; i < size; i++ )
 
2125
        {
 
2126
                sum += *(data++);
 
2127
        }
 
2128
        return( sum );
 
2129
}
 
2130
 
 
2131
XiePhotomap
 
2132
GetXIEFAXPhotomap(XParms xp, Parms p, int which, Bool radiometric)
 
2133
{
 
2134
        XIEimage *image = ( XIEimage * ) NULL;
 
2135
        XiePhotospace photospace;
 
2136
        int     flo_id, flo_notify;
 
2137
        XiePhotoElement *flograph;
 
2138
        XieDecodeG42DParam *g42d_decode_params=NULL;
 
2139
        XieDecodeG32DParam *g32d_decode_params=NULL;
 
2140
        XieDecodeG31DParam *g31d_decode_params=NULL;
 
2141
        XieDecodeTIFF2Param *tiff2_decode_params=NULL;
 
2142
        XieDecodeTIFFPackBitsParam *tiffpb_decode_params=NULL;
 
2143
        char *decode_params;
 
2144
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
2145
        char *encode_params=NULL;
 
2146
        XieLTriplet width, height, levels;
 
2147
        XiePhotomap     tmp;
 
2148
        int     size;
 
2149
 
 
2150
        if ( which == 1 )
 
2151
        {
 
2152
                image = p->finfo.image1;
 
2153
 
 
2154
        }
 
2155
        else if ( which == 2 )
 
2156
        {
 
2157
                image = p->finfo.image2;
 
2158
 
 
2159
        }
 
2160
        else if ( which == 3 )
 
2161
        {
 
2162
                image = p->finfo.image3;
 
2163
        }
 
2164
        else if ( which == 4 )
 
2165
        {
 
2166
                image = p->finfo.image4;
 
2167
        }
 
2168
        if ( !image )
 
2169
                return( XiePhotomap ) NULL;
 
2170
        
 
2171
        if ( IsImageInCache( image ) == True )
 
2172
        {
 
2173
                return( PhotomapOfImage( image ) );
 
2174
        }
 
2175
 
 
2176
        if ( !GetImageData( xp, p, which ) )
 
2177
                return( ( XiePhotomap ) NULL );
 
2178
 
 
2179
        if ( TechniqueSupported( xp, xieValDecode, image->decode ) == False )
 
2180
                return( XiePhotomap ) NULL;
 
2181
 
 
2182
        size = image->fsize;
 
2183
        image->chksum = CheckSum( image->data, size );
 
2184
        width[ 0 ] = image->width[ 0 ];
 
2185
        height[ 0 ] = image->height[ 0 ];
 
2186
        levels[ 0 ] = image->levels[ 0 ];
 
2187
 
 
2188
        /* create a photomap */
 
2189
 
 
2190
        tmp = XieCreatePhotomap(xp->d);
 
2191
 
 
2192
        /* get the data from the client into the photomap */
 
2193
 
 
2194
        photospace = XieCreatePhotospace(xp->d);
 
2195
 
 
2196
        if ( image->decode == xieValDecodeG42D )  {
 
2197
            g42d_decode_params = XieTecDecodeG42D(
 
2198
                image->fill_order, 
 
2199
                True,
 
2200
                radiometric
 
2201
            );
 
2202
            decode_params = (char *) g42d_decode_params;
 
2203
        }
 
2204
        else if ( image->decode == xieValDecodeG32D )  {
 
2205
            g32d_decode_params = XieTecDecodeG32D(
 
2206
                image->fill_order, 
 
2207
                True,
 
2208
                radiometric
 
2209
            );
 
2210
            decode_params = (char *) g32d_decode_params;
 
2211
        }
 
2212
        else if ( image->decode == xieValDecodeTIFF2 )  {
 
2213
            tiff2_decode_params = XieTecDecodeTIFF2(
 
2214
                image->fill_order, 
 
2215
                True,
 
2216
                radiometric
 
2217
            );
 
2218
            decode_params = (char *) tiff2_decode_params;
 
2219
        }
 
2220
        else if ( image->decode == xieValDecodeTIFFPackBits )  {
 
2221
            tiffpb_decode_params = XieTecDecodeTIFFPackBits(
 
2222
                image->fill_order, 
 
2223
                True
 
2224
            );
 
2225
            decode_params = (char *) tiffpb_decode_params;
 
2226
        }
 
2227
        else if ( image->decode == xieValDecodeG31D )  {
 
2228
            g31d_decode_params = XieTecDecodeG31D(
 
2229
                image->fill_order, 
 
2230
                True,
 
2231
                radiometric
 
2232
            );
 
2233
            decode_params = (char *) g31d_decode_params;
 
2234
        }
 
2235
        else {
 
2236
                return( XiePhotomap ) NULL;
 
2237
        }
 
2238
 
 
2239
        flograph = XieAllocatePhotofloGraph(2);
 
2240
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2241
        {
 
2242
                fprintf( stderr, "GetXIEFAXPhotomap: XieAllocatePhotofloGraph failed\n" );
 
2243
                XieDestroyPhotomap( xp->d, tmp );
 
2244
                if ( decode_params )
 
2245
                        XFree( decode_params );
 
2246
                return( XiePhotomap ) NULL;
 
2247
        }
 
2248
 
 
2249
        XieFloImportClientPhoto(&flograph[0],
 
2250
                image->bandclass,
 
2251
                width, height, levels,
 
2252
                False,
 
2253
                image->decode, (char *)decode_params
 
2254
        );
 
2255
 
 
2256
        XieFloExportPhotomap(&flograph[1],
 
2257
                1,              /* source phototag number */
 
2258
                tmp,
 
2259
                encode_tech,
 
2260
                encode_params
 
2261
        );
 
2262
 
 
2263
        flo_id = 1;
 
2264
        flo_notify = True;
 
2265
        XieExecuteImmediate(xp->d, photospace,
 
2266
                flo_id,
 
2267
                flo_notify,
 
2268
                flograph,       /* photoflo specification */
 
2269
                2               /* number of elements */
 
2270
        );
 
2271
        XSync( xp->d, 0 );
 
2272
        PumpTheClientData( xp, p, flo_id, photospace, 1, image->data, size, 0 );
 
2273
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2274
        XieFreePhotofloGraph(flograph,2);
 
2275
        XieDestroyPhotospace(xp->d, photospace);
 
2276
        XFree( decode_params );
 
2277
        AddToCache( image, tmp );
 
2278
        return tmp;
 
2279
}
 
2280
 
 
2281
XiePhotomap
 
2282
GetXIETriplePhotomap(XParms xp, Parms p, int which)
 
2283
{
 
2284
        XIEimage *image = ( XIEimage * ) NULL;
 
2285
        XiePhotospace photospace;
 
2286
        int     flo_id, flo_notify;
 
2287
        XiePhotoElement *flograph;
 
2288
        char *decode_params=NULL;
 
2289
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
2290
        char *encode_params=NULL;
 
2291
        XieLTriplet width, height, levels;
 
2292
        unsigned char pixel_stride[ 3 ];
 
2293
        unsigned char left_pad[ 3 ];
 
2294
        unsigned char scanline_pad[ 3 ];
 
2295
        XiePhotomap     tmp;
 
2296
        int     size;
 
2297
 
 
2298
        if ( which == 1 )
 
2299
        {
 
2300
                image = p->finfo.image1; 
 
2301
        }
 
2302
        else if ( which == 2 )
 
2303
        {
 
2304
                image = p->finfo.image2; 
 
2305
        }
 
2306
        else if ( which == 3 )
 
2307
        {
 
2308
                image = p->finfo.image3; 
 
2309
        }
 
2310
        else if ( which == 4 )
 
2311
        {
 
2312
                image = p->finfo.image4; 
 
2313
        }
 
2314
        if ( !image )
 
2315
                return( XiePhotomap ) NULL;
 
2316
 
 
2317
        if ( IsImageInCache( image ) == True )
 
2318
        {
 
2319
                TouchImage( image );
 
2320
                return( PhotomapOfImage( image ) );
 
2321
        }
 
2322
 
 
2323
        if ( !GetImageData( xp, p, which ) )
 
2324
                return( ( XiePhotomap ) NULL );
 
2325
 
 
2326
        if ( TechniqueSupported( xp, xieValDecode, image->decode ) == False )
 
2327
                return( XiePhotomap ) NULL;
 
2328
        
 
2329
        size = image->fsize;
 
2330
        image->chksum = CheckSum( image->data, size );
 
2331
 
 
2332
        /* create a photomap */
 
2333
 
 
2334
        tmp = XieCreatePhotomap(xp->d);
 
2335
 
 
2336
        /* get the data from the client into the photomap */
 
2337
 
 
2338
        photospace = XieCreatePhotospace(xp->d);
 
2339
 
 
2340
        width[ 0 ] = image->width[ 0 ];
 
2341
        width[ 1 ] = image->width[ 1 ];
 
2342
        width[ 2 ] = image->width[ 2 ];
 
2343
        height[ 0 ] = image->height[ 0 ];
 
2344
        height[ 1 ] = image->height[ 1 ];
 
2345
        height[ 2 ] = image->height[ 2 ];
 
2346
        levels[ 0 ] = image->levels[ 0 ];
 
2347
        levels[ 1 ] = image->levels[ 1 ];
 
2348
        levels[ 2 ] = image->levels[ 2 ];
 
2349
 
 
2350
        if ( image->decode == xieValDecodeUncompressedTriple )
 
2351
        {
 
2352
                pixel_stride[ 0 ] = image->pixel_stride[ 0 ];
 
2353
                pixel_stride[ 1 ] = image->pixel_stride[ 1 ];
 
2354
                pixel_stride[ 2 ] = image->pixel_stride[ 2 ];
 
2355
                left_pad[ 0 ] = image->left_pad[ 0 ];
 
2356
                left_pad[ 1 ] = image->left_pad[ 1 ];
 
2357
                left_pad[ 2 ] = image->left_pad[ 2 ];
 
2358
                scanline_pad[ 0 ] = image->scanline_pad[ 0 ];
 
2359
                scanline_pad[ 1 ] = image->scanline_pad[ 1 ];
 
2360
                scanline_pad[ 2 ] = image->scanline_pad[ 2 ];
 
2361
 
 
2362
                decode_params = ( char * ) XieTecDecodeUncompressedTriple(
 
2363
                        image->fill_order,
 
2364
                        xieValLSFirst,          
 
2365
                        xieValLSFirst,          
 
2366
                        image->interleave,      
 
2367
                        pixel_stride,
 
2368
                        left_pad,
 
2369
                        scanline_pad
 
2370
                );
 
2371
        }
 
2372
        else if ( image->decode == xieValDecodeJPEGBaseline )
 
2373
        {
 
2374
                decode_params = ( char * ) XieTecDecodeJPEGBaseline(
 
2375
                        image->interleave,
 
2376
                        image->band_order,
 
2377
                        True
 
2378
                );      
 
2379
        }
 
2380
        else if ( image->decode == xieValDecodeJPEGLossless )
 
2381
        {
 
2382
                decode_params = ( char * ) XieTecDecodeJPEGLossless(
 
2383
                        image->interleave,
 
2384
                        image->band_order
 
2385
                );      
 
2386
        }
 
2387
        else
 
2388
        {
 
2389
                fprintf( stderr, "GetXIETriplePhotomap: invalid decode technique\n" );
 
2390
                XieDestroyPhotomap( xp->d, tmp );
 
2391
                return( XiePhotomap ) NULL;
 
2392
        }       
 
2393
 
 
2394
        flograph = XieAllocatePhotofloGraph(2);
 
2395
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2396
        {
 
2397
                fprintf( stderr, "GetXIETriplePhotomap: XieAllocatePhotofloGraph failed\n" );
 
2398
                XieDestroyPhotomap( xp->d, tmp );
 
2399
                return( XiePhotomap ) NULL;
 
2400
        }
 
2401
 
 
2402
        XieFloImportClientPhoto(&flograph[0],
 
2403
                image->bandclass,
 
2404
                width, height, levels,
 
2405
                False,
 
2406
                image->decode, (char *)decode_params
 
2407
        );
 
2408
 
 
2409
        XieFloExportPhotomap(&flograph[1],
 
2410
                1,              /* source phototag number */
 
2411
                tmp,
 
2412
                encode_tech,
 
2413
                encode_params
 
2414
        );
 
2415
 
 
2416
        flo_id = 1;
 
2417
        flo_notify = True;
 
2418
        XieExecuteImmediate(xp->d, photospace,
 
2419
                flo_id,
 
2420
                flo_notify,
 
2421
                flograph,       /* photoflo specification */
 
2422
                2               /* number of elements */
 
2423
        );
 
2424
        XSync( xp->d, 0 );
 
2425
        if ( image->interleave == xieValBandByPixel )
 
2426
        {
 
2427
                PumpTheClientData( xp, p, flo_id, photospace, 
 
2428
                        1, image->data, size, 0 );
 
2429
        }
 
2430
        else
 
2431
        {
 
2432
                SendTripleBandPlaneDataSequential( xp, p, flo_id, photospace,
 
2433
                        1, image->data, size, pixel_stride,
 
2434
                        left_pad, scanline_pad, width, height );
 
2435
        } 
 
2436
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2437
        XieFreePhotofloGraph(flograph,2);
 
2438
        XieDestroyPhotospace(xp->d, photospace);
 
2439
        if ( decode_params )
 
2440
                XFree( decode_params );
 
2441
        AddToCache( image, tmp );
 
2442
        return tmp;
 
2443
}
 
2444
 
 
2445
XiePhotomap
 
2446
GetXIEPhotomap(XParms xp, Parms p, int which)
 
2447
{
 
2448
        XIEimage *image = ( XIEimage * ) NULL;
 
2449
        XiePhotospace photospace;
 
2450
        int     flo_id, flo_notify;
 
2451
        XiePhotoElement *flograph;
 
2452
        XieDecodeUncompressedSingleParam *decode_params=NULL;
 
2453
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
2454
        char *encode_params=NULL;
 
2455
        XieLTriplet width, height, levels;
 
2456
        XiePhotomap     tmp;
 
2457
        int     size;
 
2458
 
 
2459
        if ( which == 1 )
 
2460
        {
 
2461
                image = p->finfo.image1; 
 
2462
        }
 
2463
        else if ( which == 2 )
 
2464
        {
 
2465
                image = p->finfo.image2;
 
2466
        }
 
2467
        else if ( which == 3 )
 
2468
        {
 
2469
                image = p->finfo.image3;
 
2470
        }
 
2471
        else if ( which == 4 )
 
2472
        {
 
2473
                image = p->finfo.image4;
 
2474
        }
 
2475
 
 
2476
        if ( !image )
 
2477
                return( XiePhotomap ) NULL;
 
2478
 
 
2479
        if ( IsImageInCache( image ) == True )
 
2480
        {
 
2481
                TouchImage( image );
 
2482
                return( PhotomapOfImage( image ) );
 
2483
        }
 
2484
 
 
2485
        if ( !GetImageData( xp, p, which ) )
 
2486
                return( ( XiePhotomap ) NULL );
 
2487
 
 
2488
        size = image->fsize;
 
2489
        image->chksum = CheckSum( image->data, size );
 
2490
 
 
2491
        width[ 0 ] = width[ 1 ] = width[ 2 ] = image->width[ 0 ];
 
2492
        height[ 0 ] = height[ 1 ] = height[ 2 ] = image->height[ 0 ];
 
2493
        levels[ 0 ] = levels[ 1 ] = levels[ 2 ] = image->levels[ 0 ];
 
2494
 
 
2495
        /* create a photomap */
 
2496
 
 
2497
        tmp = XieCreatePhotomap(xp->d);
 
2498
 
 
2499
        /* get the data from the client into the photomap */
 
2500
 
 
2501
        photospace = XieCreatePhotospace(xp->d);
 
2502
 
 
2503
        decode_params = XieTecDecodeUncompressedSingle(
 
2504
                image->fill_order,
 
2505
                image->pixel_order,
 
2506
                image->pixel_stride[ 0 ],
 
2507
                image->left_pad[ 0 ],
 
2508
                image->scanline_pad[ 0 ]
 
2509
        );
 
2510
 
 
2511
        flograph = XieAllocatePhotofloGraph(2);
 
2512
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2513
        {
 
2514
                fprintf( stderr, "GetXIEPhotomap: XieAllocatePhotofloGraph failed\n" );
 
2515
                XieDestroyPhotomap( xp->d, tmp );
 
2516
                return( XiePhotomap ) NULL;
 
2517
        }
 
2518
 
 
2519
        XieFloImportClientPhoto(&flograph[0],
 
2520
                image->bandclass,
 
2521
                width, height, levels,
 
2522
                False,
 
2523
                image->decode, (char *)decode_params
 
2524
        );
 
2525
 
 
2526
        XieFloExportPhotomap(&flograph[1],
 
2527
                1,              /* source phototag number */
 
2528
                tmp,
 
2529
                encode_tech,
 
2530
                encode_params
 
2531
        );
 
2532
 
 
2533
        flo_id = 1;
 
2534
        flo_notify = True;
 
2535
        XieExecuteImmediate(xp->d, photospace,
 
2536
                flo_id,
 
2537
                flo_notify,
 
2538
                flograph,       /* photoflo specification */
 
2539
                2               /* number of elements */
 
2540
        );
 
2541
        XSync( xp->d, 0 );
 
2542
        PumpTheClientData( xp, p, flo_id, photospace, 1, image->data, size, 0 );
 
2543
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2544
        XieFreePhotofloGraph(flograph,2);
 
2545
        XieDestroyPhotospace(xp->d, photospace);
 
2546
        if ( decode_params )
 
2547
                XFree( decode_params );
 
2548
        AddToCache( image, tmp );
 
2549
        return tmp;
 
2550
}
 
2551
 
 
2552
XiePhotomap
 
2553
GetXIEPointPhotomap(XParms xp, Parms p, int which, 
 
2554
                    int inlevels, Bool useLevels )
 
2555
{
 
2556
        XIEimage *image = ( XIEimage * ) NULL;
 
2557
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
2558
        char *encode_params=NULL;
 
2559
        XiePhotospace photospace;
 
2560
        int flo_id, flo_notify;
 
2561
        XiePhotoElement *flograph;
 
2562
        XiePhotomap XIEPhotomap, tmp;
 
2563
        XieLut XIELut;
 
2564
        XieProcessDomain domain;
 
2565
 
 
2566
        tmp = GetXIEPhotomap( xp, p, which );
 
2567
 
 
2568
        if ( which == 1 )
 
2569
                image = p->finfo.image1;
 
2570
        else if ( which == 2 )
 
2571
                image = p->finfo.image2;
 
2572
        else if ( which == 3 )
 
2573
                image = p->finfo.image3;
 
2574
        else if ( which == 4 )
 
2575
                image = p->finfo.image4;
 
2576
 
 
2577
        if ( tmp == ( XiePhotomap ) NULL )
 
2578
                return( tmp );
 
2579
 
 
2580
        XIELut = CreatePointLut( xp, p, 1 << image->depth[ 0 ], inlevels,
 
2581
                useLevels );
 
2582
        if ( XIELut == ( XieLut ) NULL )
 
2583
                return( ( XiePhotomap ) NULL );
 
2584
 
 
2585
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
2586
 
 
2587
        /* get the data from the client into the photomap */
 
2588
 
 
2589
        photospace = XieCreatePhotospace(xp->d);
 
2590
 
 
2591
        flograph = XieAllocatePhotofloGraph(4);
 
2592
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2593
        {
 
2594
                fprintf( stderr, "GetXIEPointPhotomap: XieAllocatePhotofloGraph failed\n" );
 
2595
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
2596
                return( XiePhotomap ) NULL;
 
2597
        }
 
2598
 
 
2599
        XieFloImportPhotomap(&flograph[0],
 
2600
                tmp,
 
2601
                False
 
2602
        );
 
2603
 
 
2604
        XieFloImportLUT(&flograph[1], XIELut );
 
2605
 
 
2606
        domain.offset_x = 0;
 
2607
        domain.offset_y = 0;
 
2608
        domain.phototag = 0;
 
2609
        
 
2610
        XieFloPoint(&flograph[2],
 
2611
                1,
 
2612
                &domain,
 
2613
                2,
 
2614
                0x1
 
2615
        );
 
2616
                
 
2617
        XieFloExportPhotomap(&flograph[3],
 
2618
                3,              /* source phototag number */
 
2619
                XIEPhotomap,
 
2620
                encode_tech,
 
2621
                encode_params
 
2622
        );
 
2623
 
 
2624
        flo_id = 1;
 
2625
        flo_notify = True;
 
2626
        XieExecuteImmediate(xp->d, photospace,
 
2627
                flo_id,
 
2628
                flo_notify,
 
2629
                flograph,       /* photoflo specification */
 
2630
                4               /* number of elements */
 
2631
        );
 
2632
        XSync( xp->d, 0 );
 
2633
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2634
        XieFreePhotofloGraph(flograph,4);
 
2635
        XieDestroyPhotospace(xp->d, photospace);
 
2636
        if ( XIELut )
 
2637
                XieDestroyLUT( xp->d, XIELut );
 
2638
        return XIEPhotomap;
 
2639
}
 
2640
 
 
2641
XiePhotomap
 
2642
GetXIEGeometryPhotomap(XParms xp, Parms p, GeometryParms *geo, int which)
 
2643
{
 
2644
        XiePhotospace photospace;
 
2645
        int flo_id, flo_notify;
 
2646
        XiePhotoElement *flograph;
 
2647
 
 
2648
        static XieConstant constant = { 0.0, 0.0, 0.0 };
 
2649
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
2650
        char *encode_params=NULL;
 
2651
        float coeffs[ 6 ];
 
2652
        XiePhotomap tmp, XIEPhotomap;
 
2653
 
 
2654
        tmp = GetXIEPhotomap( xp, p, which );
 
2655
 
 
2656
        /* create a photomap */
 
2657
 
 
2658
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
2659
 
 
2660
        if ( XIEPhotomap == ( XiePhotomap ) NULL )
 
2661
                return( ( XiePhotomap ) NULL );
 
2662
 
 
2663
        photospace = XieCreatePhotospace(xp->d);
 
2664
 
 
2665
        flograph = XieAllocatePhotofloGraph(3);
 
2666
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2667
        {
 
2668
                fprintf( stderr, "GetXIEGeometryPhotomap: XieAllocatePhotofloGraph failed\n" );
 
2669
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
2670
                return( XiePhotomap ) NULL;
 
2671
        }
 
2672
 
 
2673
        XieFloImportPhotomap(&flograph[0],
 
2674
                tmp,
 
2675
                False
 
2676
        );
 
2677
 
 
2678
        SetCoefficients( xp, p, 1, geo, coeffs );
 
2679
 
 
2680
        XieFloGeometry(&flograph[1],
 
2681
                1,
 
2682
                geo->geoWidth,
 
2683
                geo->geoHeight,  
 
2684
                coeffs,
 
2685
                constant,
 
2686
                7,
 
2687
                geo->geoTech,
 
2688
                ( char * ) NULL 
 
2689
        ); 
 
2690
 
 
2691
        XieFloExportPhotomap(&flograph[2],
 
2692
                2,              /* source phototag number */
 
2693
                XIEPhotomap,
 
2694
                encode_tech,
 
2695
                encode_params
 
2696
        );
 
2697
 
 
2698
        flo_id = 1;
 
2699
        flo_notify = True;
 
2700
        XieExecuteImmediate(xp->d, photospace,
 
2701
                flo_id,
 
2702
                flo_notify,
 
2703
                flograph,       /* photoflo specification */
 
2704
                3               /* number of elements */
 
2705
        );
 
2706
        XSync( xp->d, 0 );
 
2707
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2708
        XieFreePhotofloGraph(flograph,3);
 
2709
        XieDestroyPhotospace(xp->d, photospace);
 
2710
        return XIEPhotomap;
 
2711
}
 
2712
 
 
2713
int
 
2714
GetXIEGeometryWindow(XParms xp, Parms p, Window w, 
 
2715
                     GeometryParms *geo, int which )
 
2716
{
 
2717
        XIEimage *image;
 
2718
        XiePhotospace photospace;
 
2719
        int flo_id, flo_notify;
 
2720
        XiePhotoElement *flograph;
 
2721
        float coeffs[ 6 ];
 
2722
        static XieConstant constant = { 0.0, 0.0, 0.0 };
 
2723
        XieLut XIELut;
 
2724
        XieProcessDomain domain;
 
2725
        XiePhotomap tmp;
 
2726
 
 
2727
        switch( which )
 
2728
        {
 
2729
        case 1:
 
2730
                image = p->finfo.image1;
 
2731
                break;
 
2732
        case 2:
 
2733
                image = p->finfo.image2;
 
2734
                break;
 
2735
        case 3:
 
2736
                image = p->finfo.image3;
 
2737
                break;
 
2738
        case 4:
 
2739
                image = p->finfo.image4;
 
2740
                break;
 
2741
        default:
 
2742
                fprintf( stderr, "Invalid image\n" );
 
2743
                return( 0 );
 
2744
        };
 
2745
 
 
2746
        tmp = GetXIEPhotomap( xp, p, which );
 
2747
 
 
2748
        if ( ( XIELut = CreatePointLut( xp, p, 1 << image->depth[ 0 ], 
 
2749
                1 << xp->screenDepth, False ) ) == ( XieLut ) NULL )
 
2750
        {
 
2751
                return( 0 );
 
2752
        }
 
2753
 
 
2754
        photospace = XieCreatePhotospace(xp->d);
 
2755
 
 
2756
        flograph = XieAllocatePhotofloGraph(5);
 
2757
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2758
        {
 
2759
                fprintf( stderr, "GetXIEGeometryPhotomap: XieAllocatePhotofloGraph failed\n" );
 
2760
                return( 0 );
 
2761
        }
 
2762
 
 
2763
        XieFloImportPhotomap(&flograph[0],
 
2764
                tmp,
 
2765
                False
 
2766
        );
 
2767
 
 
2768
        SetCoefficients( xp, p, 1, geo, coeffs );
 
2769
 
 
2770
        XieFloGeometry(&flograph[1],
 
2771
                1,
 
2772
                geo->geoWidth,
 
2773
                geo->geoHeight,  
 
2774
                coeffs,
 
2775
                constant,
 
2776
                7,
 
2777
                geo->geoTech,
 
2778
                ( char * ) NULL 
 
2779
        ); 
 
2780
 
 
2781
        XieFloImportLUT(&flograph[2], XIELut );
 
2782
 
 
2783
        domain.offset_x = 0;
 
2784
        domain.offset_y = 0;
 
2785
        domain.phototag = 0;
 
2786
 
 
2787
        XieFloPoint(&flograph[3],
 
2788
                2,
 
2789
                &domain,
 
2790
                3,
 
2791
                0x7
 
2792
        );
 
2793
                
 
2794
        XieFloExportDrawable(&flograph[4],
 
2795
                4,              /* source phototag number */
 
2796
                w,
 
2797
                xp->fggc,
 
2798
                0,
 
2799
                0
 
2800
        );
 
2801
 
 
2802
        flo_id = 1;
 
2803
        flo_notify = True;
 
2804
        XieExecuteImmediate(xp->d, photospace,
 
2805
                flo_id,
 
2806
                flo_notify,
 
2807
                flograph,       /* photoflo specification */
 
2808
                5               /* number of elements */
 
2809
        );
 
2810
        XSync( xp->d, 0 );
 
2811
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2812
        XieFreePhotofloGraph(flograph,5);
 
2813
        XieDestroyPhotospace(xp->d, photospace);
 
2814
        XieDestroyLUT( xp->d, XIELut );
 
2815
        return( 1 );
 
2816
}
 
2817
 
 
2818
int
 
2819
GetXIEPixmap(XParms xp, Parms p, Pixmap pixmap, int which)
 
2820
{
 
2821
        XIEimage *image;
 
2822
        XiePhotospace photospace;
 
2823
        int flo_elements, flo_id, flo_notify;
 
2824
        XiePhotoElement *flograph;
 
2825
        XieLut  XIELut;
 
2826
        XiePhotomap XIEPhotomap;
 
2827
        XieProcessDomain domain;
 
2828
 
 
2829
        XIEPhotomap = GetXIEPhotomap( xp, p, which );
 
2830
        if ( XIEPhotomap == ( XiePhotomap ) NULL )
 
2831
                return( 0 );
 
2832
 
 
2833
        switch( which )
 
2834
        {
 
2835
        case 1:
 
2836
                image = p->finfo.image1;
 
2837
                break;
 
2838
        case 2:
 
2839
                image = p->finfo.image2;
 
2840
                break;
 
2841
        case 3:
 
2842
                image = p->finfo.image3;
 
2843
                break;
 
2844
        case 4:
 
2845
                image = p->finfo.image4;
 
2846
                break;
 
2847
        default:
 
2848
                image = ( XIEimage * ) NULL;
 
2849
                break;
 
2850
        }
 
2851
 
 
2852
        if ( image == ( XIEimage * ) NULL )
 
2853
                return( 0 );
 
2854
 
 
2855
        if ( ( XIELut = CreatePointLut( xp, p, 1 << image->depth[ 0 ], 
 
2856
               1 << xp->screenDepth, False ) ) == ( XieLut ) NULL )
 
2857
        {
 
2858
                return 0;
 
2859
        }
 
2860
 
 
2861
        photospace = XieCreatePhotospace(xp->d);
 
2862
 
 
2863
        flo_elements = 4;
 
2864
        flograph = XieAllocatePhotofloGraph(flo_elements);
 
2865
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2866
        {
 
2867
                fprintf( stderr, "GetXIEPixmap: XieAllocatePhotofloGraph failed\n" );
 
2868
                if ( XIELut )
 
2869
                        XieDestroyLUT( xp->d, XIELut );
 
2870
                return( 0 );
 
2871
        }
 
2872
 
 
2873
        XieFloImportPhotomap(&flograph[0],
 
2874
                XIEPhotomap,
 
2875
                False
 
2876
        );
 
2877
 
 
2878
        XieFloImportLUT(&flograph[1], XIELut );
 
2879
 
 
2880
        domain.offset_x = 0;
 
2881
        domain.offset_y = 0;
 
2882
        domain.phototag = 0;
 
2883
 
 
2884
        XieFloPoint(&flograph[2],
 
2885
                1,
 
2886
                &domain,
 
2887
                2,
 
2888
                0x1
 
2889
        );
 
2890
 
 
2891
        XieFloExportDrawable(&flograph[flo_elements - 1],
 
2892
                flo_elements - 1,       /* source phototag number */
 
2893
                pixmap,
 
2894
                xp->fggc,
 
2895
                0,       /* x offset in window */
 
2896
                0        /* y offset in window */
 
2897
        );
 
2898
 
 
2899
        flo_id = 1;
 
2900
        flo_notify = True;
 
2901
        XieExecuteImmediate(xp->d, photospace,
 
2902
                flo_id,
 
2903
                flo_notify,
 
2904
                flograph,       /* photoflo specification */
 
2905
                flo_elements    /* number of elements */
 
2906
        );
 
2907
        XSync( xp->d, 0 );
 
2908
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
2909
        XieFreePhotofloGraph(flograph,flo_elements);
 
2910
        XieDestroyPhotospace( xp->d, photospace );
 
2911
        if ( XIELut )
 
2912
                XieDestroyLUT( xp->d, XIELut );
 
2913
        return 1;
 
2914
}
 
2915
 
 
2916
int
 
2917
GetXIEWindow(XParms xp, Parms p, Window window, int which)
 
2918
{
 
2919
        XiePhotospace photospace;
 
2920
        int flo_elements, flo_id, flo_notify;
 
2921
        XiePhotoElement *flograph;
 
2922
        XieLut  XIELut;
 
2923
        XIEimage *image;
 
2924
        XiePhotomap XIEPhotomap;
 
2925
        XieProcessDomain domain;
 
2926
 
 
2927
        switch( which )
 
2928
        {
 
2929
        case 1:
 
2930
                image = p->finfo.image1;
 
2931
                break;
 
2932
        case 2:
 
2933
                image = p->finfo.image2;
 
2934
                break;
 
2935
        case 3:
 
2936
                image = p->finfo.image3;
 
2937
                break;
 
2938
        case 4:
 
2939
                image = p->finfo.image4;
 
2940
                break;
 
2941
        default:
 
2942
                image = ( XIEimage * ) NULL;
 
2943
                break;
 
2944
        }
 
2945
 
 
2946
        XIEPhotomap = GetXIEPhotomap( xp, p, which );
 
2947
        if ( XIEPhotomap == ( XiePhotomap ) NULL )
 
2948
                return( 0 );
 
2949
        
 
2950
        if ( ( XIELut = CreatePointLut( xp, p, 1 << image->depth[ 0 ], 
 
2951
                1 << xp->screenDepth, False ) ) == ( XieLut ) NULL )
 
2952
        {
 
2953
                return 0;
 
2954
        }
 
2955
 
 
2956
        photospace = XieCreatePhotospace(xp->d);
 
2957
 
 
2958
        flo_elements = 4;
 
2959
 
 
2960
        flograph = XieAllocatePhotofloGraph(flo_elements);
 
2961
        if ( flograph == ( XiePhotoElement * ) NULL )
 
2962
        {
 
2963
                fprintf( stderr, "GetXIEWindow: XieAllocatePhotofloGraph failed\n" );
 
2964
                if ( XIELut )
 
2965
                        XieDestroyLUT( xp->d, XIELut );
 
2966
                return( 0 );
 
2967
        }
 
2968
 
 
2969
        XieFloImportPhotomap(&flograph[0],
 
2970
                XIEPhotomap,
 
2971
                False
 
2972
        );
 
2973
 
 
2974
        XieFloImportLUT(&flograph[1], XIELut );
 
2975
 
 
2976
        domain.offset_x = 0;
 
2977
        domain.offset_y = 0;
 
2978
        domain.phototag = 0;
 
2979
 
 
2980
        XieFloPoint(&flograph[2],
 
2981
                1,
 
2982
                &domain,
 
2983
                2,
 
2984
                0x1
 
2985
        );
 
2986
 
 
2987
        XieFloExportDrawable(&flograph[3],
 
2988
                3,     /* source phototag number */
 
2989
                window,
 
2990
                xp->fggc,
 
2991
                0,       /* x offset in window */
 
2992
                0        /* y offset in window */
 
2993
        );
 
2994
 
 
2995
        flo_id = 1;
 
2996
        flo_notify = True;
 
2997
        XieExecuteImmediate(xp->d, photospace,
 
2998
                flo_id,
 
2999
                flo_notify,
 
3000
                flograph,       /* photoflo specification */
 
3001
                flo_elements    /* number of elements */
 
3002
        );
 
3003
        XSync( xp->d, 0 );
 
3004
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3005
        XieFreePhotofloGraph(flograph,flo_elements);
 
3006
        XieDestroyPhotospace( xp->d, photospace );
 
3007
 
 
3008
        if ( XIELut )
 
3009
                XieDestroyLUT( xp->d, XIELut );
 
3010
        return 1;
 
3011
}
 
3012
 
 
3013
int
 
3014
GetXIEDitheredWindow(XParms xp, Parms p, Window window, int which, int level)
 
3015
{
 
3016
        XiePhotospace photospace;
 
3017
        int flo_id, flo_notify;
 
3018
        XiePhotoElement *flograph;
 
3019
        char *tech_parms=NULL;
 
3020
        XieLut XIELut;
 
3021
        XieLTriplet levels;
 
3022
        XiePhotomap tmp;
 
3023
        XieProcessDomain domain;
 
3024
        XIEimage *image;
 
3025
 
 
3026
        switch( which )
 
3027
        {
 
3028
        case 1:
 
3029
                image = p->finfo.image1;
 
3030
                break;
 
3031
        case 2:
 
3032
                image = p->finfo.image2;
 
3033
                break;
 
3034
        case 3:
 
3035
                image = p->finfo.image3;
 
3036
                break;
 
3037
        case 4:
 
3038
                image = p->finfo.image4;
 
3039
                break;
 
3040
        }
 
3041
 
 
3042
        tmp = GetXIEPhotomap( xp, p, which );
 
3043
        if ( tmp == ( XiePhotomap ) NULL )
 
3044
                return( 0 );
 
3045
 
 
3046
        photospace = XieCreatePhotospace(xp->d);
 
3047
 
 
3048
        flograph = XieAllocatePhotofloGraph(5);
 
3049
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3050
        {
 
3051
                fprintf( stderr, "GetXIEDitheredWindow: XieAllocatePhotofloGraph failed\n" );
 
3052
                return ( 0 );
 
3053
        }
 
3054
 
 
3055
        if ( ( XIELut = CreatePointLut( xp, p, level, 
 
3056
                1 << xp->screenDepth, False ) ) == ( XieLut ) NULL )
 
3057
        {
 
3058
                return 0;
 
3059
        }
 
3060
 
 
3061
        XieFloImportPhotomap(&flograph[0],
 
3062
                tmp,
 
3063
                False
 
3064
        );
 
3065
 
 
3066
        levels[ 0 ] = level;            
 
3067
        levels[ 1 ] = 0;
 
3068
        levels[ 2 ] = 0;
 
3069
 
 
3070
        tech_parms = ( char * ) NULL;
 
3071
 
 
3072
        XieFloDither(&flograph[ 1 ],
 
3073
                1,
 
3074
                1,
 
3075
                levels,
 
3076
                xieValDitherDefault,
 
3077
                tech_parms
 
3078
        );
 
3079
 
 
3080
        XieFloImportLUT(&flograph[2], XIELut );
 
3081
 
 
3082
        domain.offset_x = 0;
 
3083
        domain.offset_y = 0;
 
3084
        domain.phototag = 0;
 
3085
 
 
3086
        XieFloPoint(&flograph[3],
 
3087
                2,
 
3088
                &domain,
 
3089
                3,
 
3090
                0x1
 
3091
        );
 
3092
 
 
3093
        XieFloExportDrawable(&flograph[4],
 
3094
                4,              /* source phototag number */
 
3095
                xp->w,
 
3096
                xp->fggc,
 
3097
                0,
 
3098
                0
 
3099
        );
 
3100
 
 
3101
        flo_id = 1;
 
3102
        flo_notify = True;
 
3103
        XieExecuteImmediate(xp->d, photospace,
 
3104
                flo_id,
 
3105
                flo_notify,
 
3106
                flograph,       /* photoflo specification */
 
3107
                5               /* number of elements */
 
3108
        );
 
3109
        XSync( xp->d, 0 );
 
3110
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3111
        XieFreePhotofloGraph(flograph,5);
 
3112
        XieDestroyLUT( xp->d, XIELut );
 
3113
        return 1;
 
3114
}
 
3115
 
 
3116
XiePhotomap
 
3117
GetXIEDitheredPhotomap(XParms xp, Parms p, int which, int level)
 
3118
{
 
3119
        XiePhotospace photospace;
 
3120
        int flo_id, flo_notify;
 
3121
        XiePhotoElement *flograph;
 
3122
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
3123
        char *encode_params=NULL;
 
3124
        XieLTriplet levels;
 
3125
        char *tech_parms=NULL;
 
3126
        XiePhotomap tmp, XIEPhotomap;
 
3127
 
 
3128
        tmp = GetXIEPhotomap( xp, p, which );
 
3129
        if ( tmp == ( XiePhotomap ) NULL )
 
3130
                return( ( XiePhotomap ) NULL );
 
3131
 
 
3132
        /* create a photomap */
 
3133
 
 
3134
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
3135
 
 
3136
        /* get the data from the client into the photomap */
 
3137
 
 
3138
        photospace = XieCreatePhotospace(xp->d);
 
3139
 
 
3140
        flograph = XieAllocatePhotofloGraph(3);
 
3141
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3142
        {
 
3143
                fprintf( stderr, "GetXIEDitheredPhotomap: XieAllocatePhotofloGraph failed\n" );
 
3144
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
3145
                return ( XiePhotomap ) NULL;
 
3146
        }
 
3147
 
 
3148
        XieFloImportPhotomap(&flograph[0],
 
3149
                tmp,
 
3150
                False
 
3151
        );
 
3152
 
 
3153
        levels[ 0 ] = level;            
 
3154
        levels[ 1 ] = 0;
 
3155
        levels[ 2 ] = 0;
 
3156
 
 
3157
        tech_parms = ( char * ) NULL;
 
3158
 
 
3159
        XieFloDither(&flograph[ 1 ],
 
3160
                1,
 
3161
                1,
 
3162
                levels,
 
3163
                xieValDitherDefault,
 
3164
                tech_parms
 
3165
        );
 
3166
 
 
3167
        XieFloExportPhotomap(&flograph[2],
 
3168
                2,              /* source phototag number */
 
3169
                XIEPhotomap,
 
3170
                encode_tech,
 
3171
                encode_params
 
3172
        );
 
3173
 
 
3174
        flo_id = 1;
 
3175
        flo_notify = True;
 
3176
        XieExecuteImmediate(xp->d, photospace,
 
3177
                flo_id,
 
3178
                flo_notify,
 
3179
                flograph,       /* photoflo specification */
 
3180
                3               /* number of elements */
 
3181
        );
 
3182
        XSync( xp->d, 0 );
 
3183
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3184
        XieFreePhotofloGraph(flograph,3);
 
3185
        return XIEPhotomap;
 
3186
}
 
3187
 
 
3188
XiePhotomap
 
3189
GetXIEDitheredTriplePhotomap(XParms xp, Parms p, int which, int ditherTech, 
 
3190
                             int threshold, XieLTriplet levels)
 
3191
{
 
3192
        XiePhotomap tmp;
 
3193
        XiePhotomap triple;
 
3194
        XiePhotospace photospace;
 
3195
        XiePhotoElement *flograph;
 
3196
        char *dithertech_parms=NULL;
 
3197
        static XieEncodeTechnique encode_tech = xieValEncodeServerChoice;
 
3198
        char *encode_param = ( char * ) NULL;
 
3199
        int flo_id, flo_notify;
 
3200
 
 
3201
        if ( ( triple = GetXIETriplePhotomap( xp, p, which ) ) ==
 
3202
                ( XiePhotomap ) NULL )
 
3203
        {
 
3204
                return( ( XiePhotomap ) NULL );
 
3205
        }
 
3206
 
 
3207
        /* create a photomap */
 
3208
 
 
3209
        tmp = XieCreatePhotomap(xp->d);
 
3210
        if ( tmp == ( XiePhotomap ) NULL )
 
3211
        {
 
3212
                XieDestroyPhotomap( xp->d, triple );
 
3213
                return( ( XiePhotomap ) NULL );
 
3214
        }
 
3215
 
 
3216
        /* get the data from the client into the photomap */
 
3217
 
 
3218
        photospace = XieCreatePhotospace(xp->d);
 
3219
 
 
3220
        flograph = XieAllocatePhotofloGraph(3);
 
3221
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3222
        {
 
3223
                fprintf( stderr, "GetXIEDitheredTriplePhotomap: XieAllocatePhotofloGraph failed\n" );
 
3224
                XieDestroyPhotomap( xp->d, tmp );
 
3225
                XieDestroyPhotomap( xp->d, triple );
 
3226
                return ( XiePhotomap ) NULL;
 
3227
        }
 
3228
 
 
3229
        XieFloImportPhotomap(&flograph[0], triple, False);
 
3230
 
 
3231
        dithertech_parms = ( char * ) NULL;
 
3232
        if ( ditherTech == xieValDitherOrdered )
 
3233
        {
 
3234
                dithertech_parms = ( char * )
 
3235
                        XieTecDitherOrderedParam(threshold);
 
3236
                if ( dithertech_parms == ( char * ) NULL )
 
3237
                {
 
3238
                        fprintf( stderr,
 
3239
                        "Trouble loading dither technique parameters\n" );
 
3240
                        XieFreePhotofloGraph(flograph,3);
 
3241
                        XieDestroyPhotospace( xp->d, photospace );
 
3242
                        XieDestroyPhotomap( xp->d, tmp );
 
3243
                        XieDestroyPhotomap( xp->d, triple );
 
3244
                        return( 0 );
 
3245
                }
 
3246
        }
 
3247
 
 
3248
        XieFloDither( &flograph[ 1 ],
 
3249
                1,
 
3250
                0x7,
 
3251
                levels,
 
3252
                ditherTech,
 
3253
                dithertech_parms
 
3254
        );
 
3255
 
 
3256
        XieFloExportPhotomap(&flograph[2],
 
3257
                2,              /* source phototag number */
 
3258
                tmp,
 
3259
                encode_tech,
 
3260
                encode_param
 
3261
        );
 
3262
 
 
3263
        flo_id = 1;
 
3264
        flo_notify = True;
 
3265
 
 
3266
        XieExecuteImmediate(xp->d, photospace,
 
3267
                flo_id,
 
3268
                flo_notify,
 
3269
                flograph,       /* photoflo specification */
 
3270
                3               /* number of elements */
 
3271
        );
 
3272
        XSync( xp->d, 0 );
 
3273
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3274
        XieFreePhotofloGraph(flograph,3);
 
3275
        XieDestroyPhotospace( xp->d, photospace );
 
3276
        if ( dithertech_parms )
 
3277
                XFree( dithertech_parms );
 
3278
        return tmp;
 
3279
}
 
3280
 
 
3281
XiePhotomap
 
3282
GetXIEConstrainedPhotomap(XParms xp, Parms p, int which, 
 
3283
                          XieLTriplet cliplevels, int cliptype,
 
3284
                          XieConstant in_low, XieConstant in_high, 
 
3285
                          XieLTriplet out_low, XieLTriplet out_high )
 
3286
{
 
3287
        XiePhotospace photospace;
 
3288
        int flo_id, flo_notify;
 
3289
        XiePhotoElement *flograph;
 
3290
        XieEncodeTechnique encode_tech=xieValEncodeServerChoice;
 
3291
        char *encode_params=NULL;
 
3292
        char *tech_parms=NULL;
 
3293
        XiePhotomap tmp, XIEPhotomap;
 
3294
 
 
3295
        tmp = GetXIEPhotomap( xp, p, which );
 
3296
        if ( tmp == ( XiePhotomap ) NULL )
 
3297
                return( ( XiePhotomap ) NULL );
 
3298
 
 
3299
        /* create a photomap */
 
3300
 
 
3301
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
3302
 
 
3303
        /* get the data from the client into the photomap */
 
3304
 
 
3305
        photospace = XieCreatePhotospace(xp->d);
 
3306
 
 
3307
        flograph = XieAllocatePhotofloGraph(3);
 
3308
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3309
        {
 
3310
                fprintf( stderr, "GetXIEConstrainedPhotomap: XieAllocatePhotofloGraph failed\n" );
 
3311
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
3312
                return ( XiePhotomap ) NULL;
 
3313
        }
 
3314
 
 
3315
        XieFloImportPhotomap(&flograph[0],
 
3316
                tmp,
 
3317
                False
 
3318
        );
 
3319
 
 
3320
        if ( cliptype == xieValConstrainHardClip )
 
3321
        {
 
3322
                tech_parms = ( char * ) NULL;
 
3323
        }
 
3324
        else
 
3325
        {
 
3326
                tech_parms = ( char * ) XieTecClipScale( in_low, in_high, 
 
3327
                        out_low, out_high);
 
3328
                if ( tech_parms == ( char * ) NULL )
 
3329
                {
 
3330
                        fprintf( stderr,
 
3331
                                "GetXIEConstrainedPhotomap: Trouble loading ClipScale technique parameters\n" );
 
3332
                        fprintf( stderr, "Reverting to HardClip technique\n" );
 
3333
                        cliptype = xieValConstrainHardClip;
 
3334
                }
 
3335
        }
 
3336
 
 
3337
        XieFloConstrain( &flograph[1],
 
3338
                1,
 
3339
                cliplevels,
 
3340
                cliptype,
 
3341
                tech_parms
 
3342
        );
 
3343
 
 
3344
        XieFloExportPhotomap(&flograph[2],
 
3345
                2,
 
3346
                XIEPhotomap,
 
3347
                encode_tech,
 
3348
                encode_params
 
3349
        );
 
3350
 
 
3351
        flo_id = 1;
 
3352
        flo_notify = True;
 
3353
        XieExecuteImmediate(xp->d, photospace,
 
3354
                flo_id,
 
3355
                flo_notify,
 
3356
                flograph,       /* photoflo specification */
 
3357
                3               /* number of elements */
 
3358
        );
 
3359
        XSync( xp->d, 0 );
 
3360
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3361
        XieFreePhotofloGraph(flograph,3);
 
3362
        if ( tech_parms )
 
3363
                XFree( tech_parms );
 
3364
        return XIEPhotomap;
 
3365
}
 
3366
 
 
3367
XiePhotomap
 
3368
GetXIEConstrainedTriplePhotomap(XParms xp, Parms p, int which, 
 
3369
                                XieLTriplet cliplevels, int cliptype, 
 
3370
                                XieConstant in_low, XieConstant in_high, 
 
3371
                                XieLTriplet out_low, XieLTriplet out_high )
 
3372
{
 
3373
        XiePhotomap tmp, XIEPhotomap;
 
3374
        XiePhotospace photospace;
 
3375
        XiePhotoElement *flograph;
 
3376
        char *tech_parms = ( char * ) NULL;
 
3377
        static XieEncodeTechnique encode_tech = xieValEncodeServerChoice;
 
3378
        char *encode_params = ( char * ) NULL;
 
3379
        int flo_id, flo_notify;
 
3380
 
 
3381
        if ( ( tmp = GetXIETriplePhotomap( xp, p, which ) ) ==
 
3382
                ( XiePhotomap ) NULL )
 
3383
        {
 
3384
                return( ( XiePhotomap ) NULL );
 
3385
        }
 
3386
 
 
3387
        /* create a photomap */
 
3388
 
 
3389
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
3390
        if ( XIEPhotomap == ( XiePhotomap ) NULL )
 
3391
        {
 
3392
                return( ( XiePhotomap ) NULL );
 
3393
        }
 
3394
 
 
3395
        /* get the data from the client into the photomap */
 
3396
 
 
3397
        photospace = XieCreatePhotospace(xp->d);
 
3398
 
 
3399
        flograph = XieAllocatePhotofloGraph(3);
 
3400
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3401
        {
 
3402
                fprintf( stderr, "GetXIEConstrainedTriplePhotomap: XieAllocatePhotofloGraph failed\n" );
 
3403
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
3404
                return ( XiePhotomap ) NULL;
 
3405
        }
 
3406
 
 
3407
        XieFloImportPhotomap(&flograph[0], tmp, False);
 
3408
 
 
3409
        if ( cliptype == xieValConstrainHardClip )
 
3410
        {
 
3411
                tech_parms = ( char * ) NULL;
 
3412
        }
 
3413
        else
 
3414
        {
 
3415
                tech_parms = ( char * ) XieTecClipScale( in_low, in_high,
 
3416
                        out_low, out_high);
 
3417
                if ( tech_parms == ( char * ) NULL )
 
3418
                {
 
3419
                        fprintf( stderr,
 
3420
                                "GetXIEConstrainedPhotomap: Trouble loading ClipScale technique parameters\n" );
 
3421
                        fprintf( stderr, "Reverting to HardClip technique\n" );
 
3422
                        cliptype = xieValConstrainHardClip;
 
3423
                }
 
3424
        }
 
3425
 
 
3426
        XieFloConstrain( &flograph[1],
 
3427
                1,
 
3428
                cliplevels,
 
3429
                cliptype,
 
3430
                tech_parms
 
3431
        );
 
3432
 
 
3433
        XieFloExportPhotomap(&flograph[2],
 
3434
                2,              /* source phototag number */
 
3435
                XIEPhotomap,
 
3436
                encode_tech,
 
3437
                encode_params
 
3438
        );
 
3439
 
 
3440
        flo_id = 1;
 
3441
        flo_notify = True;
 
3442
 
 
3443
        XieExecuteImmediate(xp->d, photospace,
 
3444
                flo_id,
 
3445
                flo_notify,
 
3446
                flograph,       /* photoflo specification */
 
3447
                3               /* number of elements */
 
3448
        );
 
3449
        XSync( xp->d, 0 );
 
3450
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3451
        XieFreePhotofloGraph(flograph,3);
 
3452
        XieDestroyPhotospace( xp->d, photospace );
 
3453
        if ( tech_parms )
 
3454
                XFree( tech_parms );
 
3455
        return XIEPhotomap;
 
3456
}
 
3457
 
 
3458
XiePhotomap
 
3459
GetXIEConstrainedGeometryTriplePhotomap(XParms xp, Parms p, int which, 
 
3460
                                        XieLTriplet cliplevels, int cliptype, 
 
3461
                                        XieConstant in_low, 
 
3462
                                        XieConstant in_high, 
 
3463
                                        XieLTriplet out_low, 
 
3464
                                        XieLTriplet out_high, 
 
3465
                                        GeometryParms *geo )
 
3466
{
 
3467
        XiePhotomap tmp, XIEPhotomap;
 
3468
        XiePhotospace photospace;
 
3469
        XiePhotoElement *flograph;
 
3470
        char *tech_parms = ( char * ) NULL;
 
3471
        static XieEncodeTechnique encode_tech = xieValEncodeServerChoice;
 
3472
        char *encode_params = ( char * ) NULL;
 
3473
        int flo_id, flo_notify;
 
3474
        float coeffs[ 6 ];
 
3475
        static XieConstant constant = { 0.0, 0.0, 0.0 };
 
3476
 
 
3477
        if ( ( tmp = GetXIETriplePhotomap( xp, p, which ) ) ==
 
3478
                ( XiePhotomap ) NULL )
 
3479
        {
 
3480
                return( ( XiePhotomap ) NULL );
 
3481
        }
 
3482
 
 
3483
        /* create a photomap */
 
3484
 
 
3485
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
3486
        if ( XIEPhotomap == ( XiePhotomap ) NULL )
 
3487
        {
 
3488
                return( ( XiePhotomap ) NULL );
 
3489
        }
 
3490
 
 
3491
        /* get the data from the client into the photomap */
 
3492
 
 
3493
        photospace = XieCreatePhotospace(xp->d);
 
3494
 
 
3495
        flograph = XieAllocatePhotofloGraph(4);
 
3496
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3497
        {
 
3498
                fprintf( stderr, "GetXIEConstrainedTriplePhotomap: XieAllocatePhotofloGraph failed\n" );
 
3499
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
3500
                return ( XiePhotomap ) NULL;
 
3501
        }
 
3502
 
 
3503
        XieFloImportPhotomap(&flograph[0], tmp, False);
 
3504
 
 
3505
        SetCoefficients( xp, p, 1, geo, coeffs );
 
3506
 
 
3507
        XieFloGeometry(&flograph[1],
 
3508
                1,
 
3509
                geo->geoWidth,
 
3510
                geo->geoHeight,
 
3511
                coeffs,
 
3512
                constant,
 
3513
                7,
 
3514
                geo->geoTech,
 
3515
                ( char * ) NULL
 
3516
        );
 
3517
 
 
3518
        if ( cliptype == xieValConstrainHardClip )
 
3519
        {
 
3520
                tech_parms = ( char * ) NULL;
 
3521
        }
 
3522
        else
 
3523
        {
 
3524
                tech_parms = ( char * ) XieTecClipScale( in_low, in_high,
 
3525
                        out_low, out_high);
 
3526
                if ( tech_parms == ( char * ) NULL )
 
3527
                {
 
3528
                        fprintf( stderr,
 
3529
                                "GetXIEConstrainedPhotomap: Trouble loading ClipScale technique parameters\n" );
 
3530
                        fprintf( stderr, "Reverting to HardClip technique\n" );
 
3531
                        cliptype = xieValConstrainHardClip;
 
3532
                }
 
3533
        }
 
3534
 
 
3535
        XieFloConstrain( &flograph[2],
 
3536
                2,
 
3537
                cliplevels,
 
3538
                cliptype,
 
3539
                tech_parms
 
3540
        );
 
3541
 
 
3542
        XieFloExportPhotomap(&flograph[3],
 
3543
                3,              /* source phototag number */
 
3544
                XIEPhotomap,
 
3545
                encode_tech,
 
3546
                encode_params
 
3547
        );
 
3548
 
 
3549
        flo_id = 1;
 
3550
        flo_notify = True;
 
3551
 
 
3552
        XieExecuteImmediate(xp->d, photospace,
 
3553
                flo_id,
 
3554
                flo_notify,
 
3555
                flograph,       /* photoflo specification */
 
3556
                4               /* number of elements */
 
3557
        );
 
3558
        XSync( xp->d, 0 );
 
3559
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3560
        XieFreePhotofloGraph(flograph,4);
 
3561
        XieDestroyPhotospace( xp->d, photospace );
 
3562
        if ( tech_parms )
 
3563
                XFree( tech_parms );
 
3564
        return XIEPhotomap;
 
3565
}
 
3566
 
 
3567
XiePhotomap
 
3568
GetXIEGeometryTriplePhotomap(XParms xp, Parms p, int which, 
 
3569
                             GeometryParms *geo)
 
3570
{
 
3571
        XiePhotomap tmp, XIEPhotomap;
 
3572
        XiePhotospace photospace;
 
3573
        XiePhotoElement *flograph;
 
3574
        char *tech_parms = ( char * ) NULL;
 
3575
        static XieEncodeTechnique encode_tech = xieValEncodeServerChoice;
 
3576
        char *encode_params = ( char * ) NULL;
 
3577
        int flo_id, flo_notify;
 
3578
        float coeffs[ 6 ];
 
3579
        static XieConstant constant = { 0.0, 0.0, 0.0 };
 
3580
 
 
3581
        if ( ( tmp = GetXIETriplePhotomap( xp, p, which ) ) ==
 
3582
                ( XiePhotomap ) NULL )
 
3583
        {
 
3584
                return( ( XiePhotomap ) NULL );
 
3585
        }
 
3586
 
 
3587
        /* create a photomap */
 
3588
 
 
3589
        XIEPhotomap = XieCreatePhotomap(xp->d);
 
3590
        if ( XIEPhotomap == ( XiePhotomap ) NULL )
 
3591
        {
 
3592
                return( ( XiePhotomap ) NULL );
 
3593
        }
 
3594
 
 
3595
        /* get the data from the client into the photomap */
 
3596
 
 
3597
        photospace = XieCreatePhotospace(xp->d);
 
3598
 
 
3599
        flograph = XieAllocatePhotofloGraph(3);
 
3600
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3601
        {
 
3602
                fprintf( stderr, "GetXIEGeometryTriplePhotomap: XieAllocatePhotofloGraph failed\n" );
 
3603
                XieDestroyPhotomap( xp->d, XIEPhotomap );
 
3604
                return ( XiePhotomap ) NULL;
 
3605
        }
 
3606
 
 
3607
        XieFloImportPhotomap(&flograph[0], tmp, False);
 
3608
 
 
3609
        SetCoefficients( xp, p, 1, geo, coeffs );
 
3610
 
 
3611
        XieFloGeometry(&flograph[1],
 
3612
                1,
 
3613
                geo->geoWidth,
 
3614
                geo->geoHeight,
 
3615
                coeffs,
 
3616
                constant,
 
3617
                7,
 
3618
                geo->geoTech,
 
3619
                ( char * ) NULL
 
3620
        );
 
3621
 
 
3622
        XieFloExportPhotomap(&flograph[2],
 
3623
                2,              /* source phototag number */
 
3624
                XIEPhotomap,
 
3625
                encode_tech,
 
3626
                encode_params
 
3627
        );
 
3628
 
 
3629
        flo_id = 1;
 
3630
        flo_notify = True;
 
3631
 
 
3632
        XieExecuteImmediate(xp->d, photospace,
 
3633
                flo_id,
 
3634
                flo_notify,
 
3635
                flograph,       /* photoflo specification */
 
3636
                3               /* number of elements */
 
3637
        );
 
3638
        XSync( xp->d, 0 );
 
3639
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3640
        XieFreePhotofloGraph(flograph,3);
 
3641
        XieDestroyPhotospace( xp->d, photospace );
 
3642
        if ( tech_parms )
 
3643
                XFree( tech_parms );
 
3644
        return XIEPhotomap;
 
3645
}
 
3646
 
 
3647
int
 
3648
GetXIEDitheredTripleWindow(XParms xp, Parms p, Window w, int which, 
 
3649
                           int ditherTech, int threshold, XieLTriplet levels )
 
3650
{
 
3651
        XiePhotomap ditheredPhoto;
 
3652
        XiePhotospace photospace;
 
3653
        XiePhotoElement *flograph;
 
3654
        int flo_id, flo_notify;
 
3655
        XieColorList clist;
 
3656
        XWindowAttributes xwa;
 
3657
        XieColorAllocAllParam *color_parm;
 
3658
        int     flo_elements, idx;
 
3659
 
 
3660
        flo_elements = 3;
 
3661
        color_parm = ( XieColorAllocAllParam * ) NULL;
 
3662
        clist = ( XieColorList ) NULL;
 
3663
        color_parm = XieTecColorAllocAll( 123 );
 
3664
        if ( color_parm == ( XieColorAllocAllParam * ) NULL )
 
3665
        {
 
3666
                return( 0 );
 
3667
        }
 
3668
 
 
3669
        if ( ( clist = XieCreateColorList( xp->d ) ) == ( XieColorList ) NULL )
 
3670
        {
 
3671
                if ( color_parm )
 
3672
                        XFree( color_parm );
 
3673
                return( 0 );
 
3674
        }
 
3675
 
 
3676
        if ( ( ditheredPhoto = GetXIEDitheredTriplePhotomap( xp, p, which,
 
3677
                ditherTech, threshold, levels ) ) == ( XiePhotomap ) NULL )
 
3678
        {
 
3679
                if ( clist )
 
3680
                        XieDestroyColorList( xp->d, clist );
 
3681
                if ( color_parm )
 
3682
                        XFree( color_parm );
 
3683
                return( 0 );
 
3684
        }
 
3685
 
 
3686
        photospace = XieCreatePhotospace(xp->d);
 
3687
 
 
3688
        flograph = XieAllocatePhotofloGraph(flo_elements);
 
3689
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3690
        {
 
3691
                fprintf( stderr, "GetXIEDitheredTripleWindow: XieAllocatePhotofloGraph failed\n" );
 
3692
                if ( color_parm )
 
3693
                        XFree( color_parm );
 
3694
                if ( clist )
 
3695
                        XieDestroyColorList( xp->d, clist );
 
3696
                return( 0 );
 
3697
        }
 
3698
 
 
3699
        idx = 0;
 
3700
        XieFloImportPhotomap(&flograph[idx], ditheredPhoto, False);
 
3701
        idx++;
 
3702
 
 
3703
        XGetWindowAttributes( xp->d, xp->w, &xwa );
 
3704
        XieFloConvertToIndex(&flograph[idx],
 
3705
                idx,
 
3706
                xwa.colormap,
 
3707
                clist,
 
3708
                False,
 
3709
                xieValColorAllocAll,
 
3710
                (char *)color_parm
 
3711
        );
 
3712
        idx++;
 
3713
 
 
3714
        XieFloExportDrawable(&flograph[idx],
 
3715
                2,              /* source phototag number */
 
3716
                xp->w,
 
3717
                xp->fggc,
 
3718
                0,
 
3719
                0 
 
3720
        );
 
3721
 
 
3722
        flo_id = 1;
 
3723
        flo_notify = True;
 
3724
 
 
3725
        XieExecuteImmediate(xp->d, photospace,
 
3726
                flo_id,
 
3727
                flo_notify,
 
3728
                flograph,       /* photoflo specification */
 
3729
                flo_elements    /* number of elements */
 
3730
        );
 
3731
        XSync( xp->d, 0 );
 
3732
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3733
        XieFreePhotofloGraph(flograph,3);
 
3734
        XieDestroyPhotospace( xp->d, photospace );
 
3735
 
 
3736
        if ( clist )
 
3737
                XieDestroyColorList( xp->d, clist );
 
3738
        if ( color_parm )
 
3739
                XFree( color_parm );
 
3740
        return( 1 );
 
3741
}
 
3742
 
 
3743
int
 
3744
GetXIEDitheredStdTripleWindow(XParms xp, Parms p, Window w, int which, 
 
3745
                              int ditherTech, int threshold, 
 
3746
                              XieLTriplet levels, XStandardColormap *stdCmap)
 
3747
{
 
3748
        XiePhotomap ditheredPhoto;
 
3749
        XiePhotospace photospace;
 
3750
        XiePhotoElement *flograph;
 
3751
        int flo_id, flo_notify;
 
3752
        XieConstant c1;
 
3753
        float bias;
 
3754
 
 
3755
        if ( ( ditheredPhoto = GetXIEDitheredTriplePhotomap( xp, p, which,
 
3756
                ditherTech, threshold, levels ) ) == ( XiePhotomap ) NULL )
 
3757
        {
 
3758
                return( 0 );
 
3759
        }
 
3760
 
 
3761
        photospace = XieCreatePhotospace(xp->d);
 
3762
 
 
3763
        flograph = XieAllocatePhotofloGraph(3);
 
3764
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3765
        {
 
3766
                fprintf( stderr, "GetXIEDitheredStdTripleWindow: XieAllocatePhotofloGraph failed\n" );
 
3767
                return( 0 );
 
3768
        }
 
3769
 
 
3770
        XieFloImportPhotomap(&flograph[0], ditheredPhoto, False);
 
3771
 
 
3772
        c1[ 0 ] = stdCmap->red_mult;
 
3773
        c1[ 1 ] = stdCmap->green_mult;
 
3774
        c1[ 2 ] = stdCmap->blue_mult;
 
3775
        bias = ( float ) stdCmap->base_pixel;
 
3776
 
 
3777
        XieFloBandExtract( &flograph[1], 1, 1 << xp->vinfo.depth, bias, c1 );
 
3778
 
 
3779
        XieFloExportDrawable(&flograph[2],
 
3780
                2,              /* source phototag number */
 
3781
                xp->w,
 
3782
                xp->fggc,
 
3783
                0,
 
3784
                0 
 
3785
        );
 
3786
 
 
3787
        flo_id = 1;
 
3788
        flo_notify = True;
 
3789
 
 
3790
        XieExecuteImmediate(xp->d, photospace,
 
3791
                flo_id,
 
3792
                flo_notify,
 
3793
                flograph,       /* photoflo specification */
 
3794
                3               /* number of elements */
 
3795
        );
 
3796
        XSync( xp->d, 0 );
 
3797
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3798
        XieFreePhotofloGraph(flograph,3);
 
3799
        XieDestroyPhotospace( xp->d, photospace );
 
3800
        XieDestroyPhotomap( xp->d, ditheredPhoto );
 
3801
        return( 1 );
 
3802
}
 
3803
 
 
3804
int
 
3805
GetFileSize(char *path)
 
3806
{
 
3807
        int     size;
 
3808
        struct stat _Stat_Buffer;
 
3809
#define file_size(path) ( stat(path,&_Stat_Buffer)== 0 ? \
 
3810
                _Stat_Buffer.st_size :  -1)
 
3811
 
 
3812
        /* open the file */
 
3813
 
 
3814
        if ( ( size = file_size( path ) ) < 0 )
 
3815
        {
 
3816
                fprintf( stderr, "Couldn't stat %s\n", path );
 
3817
                return 0;
 
3818
        }
 
3819
        return( size );
 
3820
}
 
3821
 
 
3822
int
 
3823
GetImageData(XParms xp, Parms p, int which)
 
3824
{
 
3825
        int     fd;
 
3826
        int     *size;
 
3827
        XIEimage *image = ( XIEimage * ) NULL;
 
3828
        char    *name;
 
3829
        char    buf[ 64 ];
 
3830
 
 
3831
        if ( which == 1 )
 
3832
        {
 
3833
                image = p->finfo.image1;
 
3834
        }
 
3835
        else if ( which == 2 )
 
3836
        {
 
3837
                image = p->finfo.image2;
 
3838
        }       
 
3839
        else if ( which == 3 )
 
3840
        {
 
3841
                image = p->finfo.image3;
 
3842
        }
 
3843
        else if ( which == 4 )
 
3844
        {
 
3845
                image = p->finfo.image4;
 
3846
        }
 
3847
 
 
3848
        if (!image)
 
3849
                return( 0 );
 
3850
 
 
3851
        if ( p->buffer_size <= 0 )
 
3852
        {
 
3853
                fprintf( stderr, "buffer_size is invalid\n" );
 
3854
                return 0;
 
3855
        }
 
3856
 
 
3857
        size = &image->fsize;
 
3858
        name = image->fname;
 
3859
        sprintf( buf, "%s/%s", imagepath, name );
 
3860
 
 
3861
        *size = GetFileSize( buf );
 
3862
 
 
3863
        if ( *size == 0 )
 
3864
                return( 0 );
 
3865
 
 
3866
        if ( ( fd = open( buf, O_RDONLY|O_BINARY ) ) == -1 )
 
3867
        {
 
3868
                fprintf( stderr, "Couldn't open %s\n", buf );
 
3869
                goto out;
 
3870
        }
 
3871
 
 
3872
        /* allocate the data buffer */
 
3873
 
 
3874
        if ( image->data == ( char * ) NULL )
 
3875
        {
 
3876
                if ( ( image->data = 
 
3877
                        (char *)malloc( *size ) ) == ( char * ) NULL )
 
3878
                {
 
3879
                        fprintf( stderr, "Couldn't allocate buffer\n" );
 
3880
                        goto out;
 
3881
                }
 
3882
        }
 
3883
 
 
3884
        /* read the data */
 
3885
 
 
3886
        if ( read( fd, image->data, *size ) != *size )
 
3887
        {
 
3888
                fprintf( stderr, "Couldn't read data\n" );
 
3889
                goto out;
 
3890
        }
 
3891
 
 
3892
        /* close the file */
 
3893
 
 
3894
        close( fd );
 
3895
        return( 1 );
 
3896
 
 
3897
out:    if ( fd )
 
3898
        {
 
3899
                close( fd );
 
3900
        }
 
3901
        return 0;
 
3902
}
 
3903
 
 
3904
XieLut
 
3905
GetXIELut(XParms xp, Parms p, unsigned char *lut, int lutSize, int lutLevels)
 
3906
{
 
3907
        XiePhotospace photospace;
 
3908
        int     flo_id, flo_notify;
 
3909
        XiePhotoElement *flograph;
 
3910
        XieDataClass    cclass;
 
3911
        XieOrientation  band_order;
 
3912
        XieLTriplet     length, levels;
 
3913
        Bool    merge;
 
3914
        XieLTriplet     start;
 
3915
        XieLut  tmp;
 
3916
 
 
3917
        /* create a LUT for starters */
 
3918
 
 
3919
        tmp = XieCreateLUT(xp->d);
 
3920
 
 
3921
        photospace = XieCreatePhotospace(xp->d);
 
3922
 
 
3923
        flograph = XieAllocatePhotofloGraph(2);
 
3924
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3925
        {
 
3926
                fprintf(stderr,"GetXIELut: XieAllocatePhotofloGraph failed\n");
 
3927
                XieDestroyLUT( xp->d, tmp );
 
3928
                return ( XieLut ) NULL;
 
3929
        }
 
3930
 
 
3931
        cclass = xieValSingleBand;
 
3932
        band_order = xieValMSFirst;
 
3933
        length[ 0 ] = lutSize;
 
3934
        length[ 1 ] = 0;
 
3935
        length[ 2 ] = 0;
 
3936
        levels[ 0 ] = lutLevels;
 
3937
        levels[ 1 ] = 0;
 
3938
        levels[ 2 ] = 0;
 
3939
 
 
3940
        XieFloImportClientLUT(&flograph[0],
 
3941
                cclass,
 
3942
                band_order,
 
3943
                length,
 
3944
                levels
 
3945
        );
 
3946
 
 
3947
        merge = False;
 
3948
        start[ 0 ] = 0; 
 
3949
        start[ 1 ] = 0; 
 
3950
        start[ 2 ] = 0; 
 
3951
 
 
3952
        XieFloExportLUT(&flograph[1],
 
3953
                1,              /* source phototag number */
 
3954
                tmp,
 
3955
                merge,
 
3956
                start
 
3957
        );
 
3958
 
 
3959
        flo_id = 1;
 
3960
        flo_notify = True;
 
3961
        XieExecuteImmediate(xp->d, photospace,
 
3962
                flo_id,
 
3963
                flo_notify,
 
3964
                flograph,       /* photoflo specification */
 
3965
                2               /* number of elements */
 
3966
        );
 
3967
        XSync( xp->d, 0 );
 
3968
        PumpTheClientData( xp, p, flo_id, photospace, 1, (char *)lut, lutSize,
 
3969
                           0 );
 
3970
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
3971
        XieFreePhotofloGraph(flograph,2);
 
3972
        return tmp;
 
3973
}
 
3974
 
 
3975
XieRoi
 
3976
GetXIERoi(XParms xp, Parms p, XieRectangle *rects, int rectsSize)
 
3977
{
 
3978
        XiePhotospace photospace;
 
3979
        int     flo_id, flo_notify;
 
3980
        XiePhotoElement *flograph;
 
3981
        XieRoi  tmp;
 
3982
 
 
3983
        /* create an ROI */
 
3984
 
 
3985
        tmp = XieCreateROI(xp->d);
 
3986
 
 
3987
        photospace = XieCreatePhotospace(xp->d);
 
3988
 
 
3989
        flograph = XieAllocatePhotofloGraph(2);
 
3990
        if ( flograph == ( XiePhotoElement * ) NULL )
 
3991
        {
 
3992
                fprintf(stderr,"GetXIERoi: XieAllocatePhotofloGraph failed\n");
 
3993
                XieDestroyROI( xp->d, tmp );
 
3994
                return ( XieRoi ) NULL;
 
3995
        }
 
3996
 
 
3997
        XieFloImportClientROI(&flograph[0],
 
3998
                rectsSize
 
3999
        );
 
4000
 
 
4001
        XieFloExportROI(&flograph[1],
 
4002
                1,              /* source phototag number */
 
4003
                tmp 
 
4004
        );
 
4005
 
 
4006
        flo_id = 1;
 
4007
        flo_notify = True;
 
4008
        XieExecuteImmediate(xp->d, photospace,
 
4009
                flo_id,
 
4010
                flo_notify,
 
4011
                flograph,       /* photoflo specification */
 
4012
                2               /* number of elements */
 
4013
        );
 
4014
        XSync( xp->d, 0 );
 
4015
        PumpTheClientData( xp, p, flo_id, photospace, 1, (char *)rects,
 
4016
                           rectsSize * sizeof( XieRectangle ), 0 );
 
4017
        WaitForXIEEvent( xp, xieEvnNoPhotofloDone, flo_id, 0, False );
 
4018
 
 
4019
        XieFreePhotofloGraph(flograph,2);
 
4020
        return tmp;
 
4021
}
 
4022
 
 
4023
static int
 
4024
EventOrErrorValid(unsigned short testcp)
 
4025
{
 
4026
        if ( IsEvent( testcp ) && runEvents == False )
 
4027
                return( 0 );
 
4028
        else if ( IsError( testcp ) && runErrors == False )
 
4029
                return( 0 );
 
4030
        return( 1 );
 
4031
}
 
4032
 
 
4033
int     
 
4034
IsDISServer(void)
 
4035
{
 
4036
        return( IsDIS( capabilities ) );
 
4037
}
 
4038
 
 
4039
static int
 
4040
ServerIsCapable(unsigned short testcp)
 
4041
{
 
4042
        if ( IsFull( testcp ) && IsDIS( capabilities ) )
 
4043
                return( 0 );
 
4044
        return( 1 );
 
4045
}
 
4046
 
 
4047
Bool
 
4048
TechniqueSupported(XParms xp, XieTechniqueGroup group, unsigned int tech)
 
4049
{
 
4050
        XieTechnique    *techVector;            
 
4051
        int             numTech, i;
 
4052
        Bool            gotIt;
 
4053
 
 
4054
        gotIt = False;
 
4055
        if ( !XieQueryTechniques( xp->d, group, &numTech, &techVector ) )
 
4056
        {
 
4057
                fprintf( stderr, 
 
4058
                        "TechniqueSupported: XieQueryTechniques failed\n" );
 
4059
        }
 
4060
        else
 
4061
        {       
 
4062
                /* search for it */
 
4063
 
 
4064
                for ( i = 0; i < numTech; i++ )
 
4065
                {
 
4066
                        if ( tech == techVector[ i ].number )
 
4067
                        {
 
4068
                                gotIt = True;
 
4069
                        }
 
4070
                        if ( techVector[ i ].name )
 
4071
                                XFree( techVector[ i ].name );  
 
4072
                }
 
4073
                if ( techVector )
 
4074
                        XFree( techVector );
 
4075
        }
 
4076
        
 
4077
        return( gotIt );
 
4078
}       
 
4079
 
 
4080
/* list all of the techniques supported. this isn't used by xieperf, but was
 
4081
   used to validate TechniqueSupported() */
 
4082
 
 
4083
struct _tech {
 
4084
        char    *name;
 
4085
        unsigned int tech; 
 
4086
};
 
4087
 
 
4088
struct _class {
 
4089
        char *name;
 
4090
        Bool full;
 
4091
        XieTechniqueGroup group;
 
4092
        struct _tech *techs; 
 
4093
        int     n;
 
4094
};
 
4095
 
 
4096
static struct _tech ColorAllocTechs[] = {
 
4097
        { "ColorAllocAll", xieValColorAllocAll },
 
4098
        { "ColorAllocMatch", xieValColorAllocMatch },
 
4099
        { "ColorAllocRequantize", xieValColorAllocRequantize } };
 
4100
 
 
4101
static struct _tech ConstrainTechs[] = {
 
4102
        { "ConstrainClipScale", xieValConstrainClipScale },
 
4103
        { "ConstrainHardClip", xieValConstrainHardClip } };
 
4104
 
 
4105
static struct _tech ConvolveTechs[] = {
 
4106
        { "ConvolveConstant", xieValConvolveConstant },
 
4107
        { "ConvolveReplicate", xieValConvolveReplicate } };
 
4108
 
 
4109
static struct _tech DecodeTechs[] = {
 
4110
        { "DecodeUncompressedSingle", xieValDecodeUncompressedSingle },
 
4111
        { "DecodeUncompressedTriple", xieValDecodeUncompressedTriple },
 
4112
        { "DecodeG31D", xieValDecodeG31D },
 
4113
        { "DecodeG32D", xieValDecodeG32D },
 
4114
        { "DecodeG42D", xieValDecodeG42D },
 
4115
        { "DecodeJPEGBaseline", xieValDecodeJPEGBaseline },
 
4116
        { "DecodeJPEGLossless", xieValDecodeJPEGLossless },
 
4117
        { "DecodeTIFF2", xieValDecodeTIFF2 },
 
4118
        { "DecodeTIFFPackBits", xieValDecodeTIFFPackBits } };
 
4119
 
 
4120
static struct _tech DitherTechs[] = {
 
4121
        { "DitherErrorDiffusion", xieValDitherErrorDiffusion },
 
4122
        { "DitherOrdered", xieValDitherOrdered } };
 
4123
 
 
4124
static struct _tech ColorspaceTechs[] = {
 
4125
        { "CIELab", xieValCIELabToRGB },
 
4126
        { "CIEXYZ", xieValCIEXYZToRGB },
 
4127
        { "YCbCr",  xieValYCbCrToRGB },
 
4128
        { "YCC",    xieValYCCToRGB } };
 
4129
 
 
4130
static struct _tech EncodeTechs[] = {
 
4131
        { "EncodeUncompressedSingle", xieValEncodeUncompressedSingle },
 
4132
        { "EncodeUncompressedTriple", xieValEncodeUncompressedTriple },
 
4133
        { "EncodeG31D", xieValEncodeG31D },
 
4134
        { "EncodeG32D", xieValEncodeG32D },
 
4135
        { "EncodeG42D", xieValEncodeG42D },
 
4136
        { "EncodeJPEGBaseline", xieValEncodeJPEGBaseline },
 
4137
        { "EncodeJPEGLossless", xieValEncodeJPEGLossless },
 
4138
        { "EncodeTIFF2", xieValEncodeTIFF2 },
 
4139
        { "EncodeTIFFPackBits", xieValEncodeTIFFPackBits } };
 
4140
 
 
4141
static struct _tech GeometryTechs[] = {
 
4142
        { "GeometryAntialias", xieValGeomAntialias },
 
4143
        { "GeometryAntialiasByArea", xieValGeomAntialiasByArea },
 
4144
        { "GeometryAntialiasByLowpass", xieValGeomAntialiasByLPF },
 
4145
        { "GeometryBilinearInterpolation", xieValGeomBilinearInterp },
 
4146
        { "GeometryGaussian", xieValGeomGaussian },
 
4147
        { "GeometryNearestNeighbor", xieValGeomNearestNeighbor } };
 
4148
 
 
4149
static struct _tech GamutTechs[] = {
 
4150
        { "GamutNone", xieValGamutNone },
 
4151
        { "GamutClipRGB", xieValGamutClipRGB } };
 
4152
 
 
4153
static struct _tech HistogramTechs[] = {
 
4154
        { "HistogramFlat", xieValHistogramFlat },
 
4155
        { "HistogramGaussian", xieValHistogramGaussian },
 
4156
        { "HistogramHyperbolic", xieValHistogramHyperbolic } };
 
4157
 
 
4158
static struct _tech WhiteAdjustTechs[] = {
 
4159
        { "WhiteAdjustNone", xieValWhiteAdjustNone },
 
4160
        { "WhiteAdjustCIELabShift", xieValWhiteAdjustCIELabShift } };
 
4161
 
 
4162
static struct _class classes[] = { 
 
4163
        { "ColorAlloc", True, xieValColorAlloc, ColorAllocTechs, 
 
4164
                sizeof( ColorAllocTechs ) / sizeof( struct _tech )  },
 
4165
        { "Constrain", True, xieValConstrain,  ConstrainTechs,
 
4166
                sizeof( ConstrainTechs ) / sizeof( struct _tech )  },
 
4167
        { "Convolve", True, xieValConvolve, ConvolveTechs, 
 
4168
                sizeof( ConvolveTechs ) / sizeof( struct _tech )  },
 
4169
        { "ConvertFromRGB", True, xieValConvertFromRGB, ColorspaceTechs, 
 
4170
                sizeof( ColorspaceTechs ) / sizeof( struct _tech )  },
 
4171
        { "ConvertToRGB", True, xieValConvertToRGB, ColorspaceTechs, 
 
4172
                sizeof( ColorspaceTechs ) / sizeof( struct _tech )  },
 
4173
        { "Decode", False, xieValDecode, DecodeTechs, 
 
4174
                sizeof( DecodeTechs ) / sizeof( struct _tech )  },
 
4175
        { "Dither", True, xieValDither, DitherTechs, 
 
4176
                sizeof( DitherTechs ) / sizeof( struct _tech )  },
 
4177
        { "Encode", False, xieValEncode, EncodeTechs, 
 
4178
                sizeof( EncodeTechs ) / sizeof( struct _tech )  },
 
4179
        { "Gamut", True, xieValGamut, GamutTechs, 
 
4180
                sizeof( GamutTechs ) / sizeof( struct _tech )  },
 
4181
        { "Geometry", False, xieValGeometry, GeometryTechs, 
 
4182
                sizeof( GeometryTechs ) / sizeof( struct _tech )  },
 
4183
        { "Histogram", True, xieValHistogram, HistogramTechs, 
 
4184
                sizeof( HistogramTechs ) / sizeof( struct _tech )  },
 
4185
        { "WhiteAdjust", True, xieValWhiteAdjust, WhiteAdjustTechs, 
 
4186
                sizeof( WhiteAdjustTechs ) / sizeof( struct _tech )  } };
 
4187
                  
 
4188
static void
 
4189
ListAllTechs(XParms xp)
 
4190
{
 
4191
        int     i, j;
 
4192
 
 
4193
        for ( i = 0; i < sizeof( classes ) / sizeof( struct _class ); i++ )
 
4194
        {
 
4195
                printf( "Class name: %s\n", classes[ i ].name );
 
4196
                for ( j = 0; j < classes[ i ].n; j++ )
 
4197
                {
 
4198
                        printf( "\tTechnique %s:", classes[ i ].techs[ j ].name );
 
4199
                        if (classes[ i ].full==True && IsDIS( capabilities ))
 
4200
                        {
 
4201
                                printf( " is not supported\n" ); 
 
4202
                        }
 
4203
                        else if ( TechniqueSupported( xp, classes[ i ].group,
 
4204
                                classes[ i ].techs[ j ].tech ) == True )
 
4205
                        {
 
4206
                                printf( " is supported\n" );
 
4207
                        }
 
4208
                        else
 
4209
                        {
 
4210
                                printf( " is not supported\n" );
 
4211
                        }
 
4212
                }
 
4213
        }
 
4214
        printf( "\n" );
 
4215
 
4216
 
 
4217
#ifdef notyet
 
4218
static void
 
4219
FillHisto(XieHistogramData histos[], int size, int levels)
 
4220
{
 
4221
        int     i;
 
4222
        int     sy;
 
4223
 
 
4224
        sy = levels / size;
 
4225
        for ( i = 0; i < size; i++ )
 
4226
        {
 
4227
                histos[ i ].value = i + 40;
 
4228
                histos[ i ].count = i * sy;
 
4229
        }       
 
4230
}
 
4231
#endif
 
4232
 
 
4233
void
 
4234
DrawHistogram(XParms xp, Window w, XieHistogramData histos[], int size, 
 
4235
              unsigned long levels)
 
4236
{
 
4237
        unsigned long maxcount;
 
4238
        int     i;
 
4239
        float   sx, sy;
 
4240
        XRectangle *rects;
 
4241
        short   yadd, xadd;
 
4242
        char    buf[ 32 ];
 
4243
 
 
4244
        maxcount = 0;
 
4245
        levels = 0;
 
4246
        for ( i = 0; i < size; i++ )
 
4247
        {
 
4248
                if ( histos[ i ].count > maxcount )
 
4249
                        maxcount = histos[ i ].count;
 
4250
                if ( histos[ i ].value > levels  )
 
4251
                        levels = histos[ i ].value;
 
4252
        }
 
4253
 
 
4254
        if ( maxcount == 0 )
 
4255
                return;
 
4256
 
 
4257
        xadd = ( short ) ( ( float ) MONWIDTH * 0.15 );
 
4258
        yadd = xadd; 
 
4259
 
 
4260
        sx = ( float ) ( MONWIDTH - xadd ) / ( float ) ( levels + 1 ); 
 
4261
        sy = ( float ) ( MONHEIGHT - yadd ) / ( float ) maxcount;
 
4262
 
 
4263
        XClearWindow( xp->d, w );
 
4264
 
 
4265
        /* label x */
 
4266
 
 
4267
        XDrawImageString( xp->d, w, tgc, xadd,
 
4268
                MONHEIGHT - 3, "0", 1 );
 
4269
        sprintf( buf, "%ld", levels );
 
4270
        XDrawImageString( xp->d, w, tgc, MONWIDTH -
 
4271
                strlen( buf ) * 14, MONHEIGHT - 3, buf, strlen( buf ) );
 
4272
 
 
4273
        /* label y */
 
4274
 
 
4275
        sprintf( buf, "%ld", maxcount );
 
4276
        XDrawImageString( xp->d, w, tgc, 3,
 
4277
                20, buf, strlen( buf ) );
 
4278
        XDrawImageString( xp->d, w, tgc, 3,
 
4279
                MONHEIGHT - yadd, "0", 1 );
 
4280
 
 
4281
        /* y axis */
 
4282
 
 
4283
        XDrawLine( xp->d, w, tgc, xadd, MONHEIGHT - yadd, 
 
4284
                xadd, 0 );
 
4285
 
 
4286
        /* x axis */
 
4287
 
 
4288
        XDrawLine( xp->d, w, tgc, xadd, MONHEIGHT - yadd,
 
4289
                MONWIDTH, MONHEIGHT - yadd );
 
4290
 
 
4291
        rects = ( XRectangle * ) malloc( sizeof( XRectangle ) * size );
 
4292
        if ( rects == ( XRectangle * ) NULL )
 
4293
                return;
 
4294
 
 
4295
        /* create the rectangles */
 
4296
 
 
4297
        for ( i = 0; i < size; i++ )
 
4298
        {
 
4299
                rects[ i ].width = ( short ) ceil( sx );
 
4300
                rects[ i ].height = ( short ) ( sy * histos[ i ].count );
 
4301
                rects[ i ].x = xadd + ( short ) ( sx * histos[ i ].value );
 
4302
                rects[ i ].y = ( short ) MONHEIGHT - yadd - rects[ i ].height;
 
4303
        }
 
4304
 
 
4305
        /* draw it */
 
4306
 
 
4307
        XFillRectangles( xp->d, w, tgc, rects, size );
 
4308
        XSync( xp->d, 0 );
 
4309
 
 
4310
        free( rects );
 
4311
}
 
4312
 
 
4313
int
 
4314
GetStandardColormap(XParms xp, XStandardColormap *stdColormap, Atom atom)
 
4315
{
 
4316
        int     status, i;
 
4317
        int     numberColormaps;
 
4318
        XStandardColormap *colormapsReturned;
 
4319
        VisualID        visualId;
 
4320
 
 
4321
        visualId = XVisualIDFromVisual( xp->vinfo.visual );
 
4322
        if ( !XGetRGBColormaps(xp->d, RootWindow(xp->d, DefaultScreen( xp->d )),
 
4323
                &colormapsReturned, &numberColormaps, atom ) )
 
4324
        {
 
4325
                status = XmuLookupStandardColormap( xp->d, 
 
4326
                        DefaultScreen( xp->d ),
 
4327
                        visualId,       
 
4328
                        xp->vinfo.depth,
 
4329
                        atom,
 
4330
                        True,           /* Don't replace existing cmap */
 
4331
                        True );
 
4332
                if ( status != 0 )
 
4333
                {
 
4334
                        status = XGetRGBColormaps( xp->d,
 
4335
                                RootWindow( xp->d, DefaultScreen( xp->d ) ),
 
4336
                                &colormapsReturned,
 
4337
                                &numberColormaps,
 
4338
                                atom );
 
4339
                }
 
4340
        }
 
4341
        else
 
4342
                status = 1;
 
4343
        if ( status != 0 )
 
4344
        {
 
4345
                for ( i = 0; i < numberColormaps; i++ )
 
4346
                {
 
4347
                        if (visualId == colormapsReturned[i].visualid)
 
4348
                        {
 
4349
                                memcpy( ( char * ) stdColormap,
 
4350
                                        ( char * ) &colormapsReturned[ i ],
 
4351
                                        sizeof( XStandardColormap ) );
 
4352
                                XFree( colormapsReturned );
 
4353
                                if ( atom == XA_RGB_BEST_MAP )
 
4354
                                        RGB_BESTStandardColormapObtained = True;
 
4355
                                return( True );
 
4356
                        }
 
4357
                }
 
4358
                XFree( colormapsReturned );
 
4359
        }
 
4360
        return( False );
 
4361
}
 
4362
 
 
4363
#define SETLUT if ( lutCellSize == sizeof( char ) ) {\
 
4364
        *( ( unsigned char * ) ptr ) = val; \
 
4365
        ptr+=sizeof(char); } \
 
4366
else if ( lutCellSize == sizeof( short ) ) { \
 
4367
        *( ( unsigned short * ) ptr ) = val; \
 
4368
        ptr+=sizeof(short); } \
 
4369
else if ( lutCellSize == sizeof( int ) ) { \
 
4370
        *( ( unsigned int * ) ptr ) = val; \
 
4371
        ptr+=sizeof(int); } \
 
4372
else { \
 
4373
        *( ( unsigned long * ) ptr) = val; \
 
4374
        ptr+=sizeof(long); }
 
4375
 
 
4376
#define SETTDLUT if ( lutCellSize == sizeof( char ) ) {\
 
4377
        *( ( unsigned char * ) ptr ) = val * lowbit( DCRedMask ); \
 
4378
        *( ( unsigned char * ) ptr ) |= val * lowbit( DCGreenMask ); \
 
4379
        *( ( unsigned char * ) ptr ) |= val * lowbit( DCBlueMask ); \
 
4380
        ptr+=sizeof(char); } \
 
4381
else if ( lutCellSize == sizeof( short ) ) { \
 
4382
        *( ( unsigned short * ) ptr ) = val * lowbit( DCRedMask ); \
 
4383
        *( ( unsigned short * ) ptr ) |= val * lowbit( DCGreenMask ); \
 
4384
        *( ( unsigned short * ) ptr ) |= val * lowbit( DCBlueMask ); \
 
4385
        ptr+=sizeof(short); } \
 
4386
else if ( lutCellSize == sizeof( int ) ) { \
 
4387
        *( ( unsigned int * ) ptr ) = val * lowbit( DCRedMask ); \
 
4388
        *( ( unsigned int * ) ptr ) |= val * lowbit( DCGreenMask ); \
 
4389
        *( ( unsigned int * ) ptr ) |= val * lowbit( DCBlueMask ); \
 
4390
        ptr+=sizeof(int); } \
 
4391
else { \
 
4392
        *( ( unsigned long * ) ptr ) = val * lowbit( DCRedMask ); \
 
4393
        *( ( unsigned long * ) ptr ) |= val * lowbit( DCGreenMask ); \
 
4394
        *( ( unsigned long * ) ptr ) |= val * lowbit( DCBlueMask ); \
 
4395
        ptr+=sizeof(long); }
 
4396
 
 
4397
int 
 
4398
DepthFromLevels(int levels)
 
4399
{
 
4400
        unsigned int mask;
 
4401
        int     bp;
 
4402
 
 
4403
        bp = ( sizeof( int ) << 3 ) - 1;
 
4404
        mask = 1 << bp;
 
4405
        while ( mask && !( mask & levels ) ) 
 
4406
        {
 
4407
                bp--;
 
4408
                mask = ( ( mask >> 1 ) & ~mask );
 
4409
        }
 
4410
        return( bp );
 
4411
}
 
4412
 
 
4413
static int
 
4414
TDLutCellSize(XParms xp)
 
4415
{
 
4416
        int     bp, max;
 
4417
 
 
4418
        max = 0;
 
4419
        bp = DepthFromLevels( DCRedMask );
 
4420
        if ( bp > max )
 
4421
                max = bp;
 
4422
        bp = DepthFromLevels( DCGreenMask );
 
4423
        if ( bp > max )
 
4424
                max = bp;
 
4425
        bp = DepthFromLevels( DCBlueMask );
 
4426
        if ( bp > max )
 
4427
                max = bp;
 
4428
        max++;
 
4429
        return( LutCellSize( max ) );
 
4430
}
 
4431
 
 
4432
static int
 
4433
LutCellSize(int depth)
 
4434
{
 
4435
        if ( depth >= 0 && depth <= 7 )
 
4436
                depth = 8;
 
4437
        else if ( depth > 8 && depth <= 15 )
 
4438
                depth = 16;
 
4439
        else if ( depth > 16 && depth <= 31 )
 
4440
                depth = 32;
 
4441
        return( ( depth + 7 ) >> 3 );  
 
4442
}
 
4443
 
 
4444
XieLut
 
4445
CreatePointLut(XParms xp, Parms p, int inlevels, int outlevels, 
 
4446
               Bool computeLutFromLevels )
 
4447
{
 
4448
        unsigned char *lut, *ptr;
 
4449
        int     lutSize;
 
4450
        int     lutCellSize;
 
4451
        int     i, j, val, cclass;
 
4452
        int     step, increment;
 
4453
        int     outdepth;
 
4454
        XieLut  retval;
 
4455
 
 
4456
#if     defined(__cplusplus) || defined(c_plusplus)
 
4457
        cclass = xp->vinfo.c_class;
 
4458
#else
 
4459
        cclass = xp->vinfo.class;
 
4460
#endif
 
4461
 
 
4462
        lutSize = inlevels;
 
4463
        outdepth = DepthFromLevels( outlevels );
 
4464
        if ( ( cclass == DirectColor || cclass == TrueColor ) &&
 
4465
                computeLutFromLevels == False )
 
4466
        {
 
4467
                lutCellSize = TDLutCellSize( xp );              
 
4468
        }
 
4469
        else
 
4470
        {
 
4471
                lutCellSize = LutCellSize( outdepth );
 
4472
        }
 
4473
 
 
4474
        if ( lutCellSize != sizeof( char ) && lutCellSize != sizeof( short )
 
4475
             && lutCellSize != sizeof( int ) && lutCellSize != sizeof( long ) )
 
4476
        {
 
4477
                fprintf( stderr, "CreatePointLut: cell size not supported\n" );
 
4478
                return( ( XieLut ) NULL );
 
4479
        }
 
4480
 
 
4481
        if ( inlevels == outlevels )
 
4482
        {
 
4483
                increment = 1;
 
4484
                step = 1;
 
4485
        }
 
4486
        else if ( inlevels > outlevels )
 
4487
        {
 
4488
                increment = 1; 
 
4489
                step = inlevels / outlevels;
 
4490
        }
 
4491
        else /* outlevels > inlevels */
 
4492
        {
 
4493
                increment = (outlevels - 1) / (inlevels - 1);
 
4494
                step = 1;
 
4495
        }
 
4496
 
 
4497
        lut = (unsigned char *) malloc( lutSize * lutCellSize );
 
4498
        ptr = lut;
 
4499
        if ( lut == ( unsigned char * ) NULL )
 
4500
        {
 
4501
                fprintf( stderr, "CreatePointLut: malloc failed allocating lut\n" );
 
4502
                return( ( XieLut ) NULL );
 
4503
        }
 
4504
 
 
4505
        /* initialize the lut */
 
4506
 
 
4507
        val = 0;
 
4508
        j = 0;
 
4509
        for ( i = 0; i < lutSize; i++ )
 
4510
        {
 
4511
                if ( cclass != DirectColor && cclass != TrueColor ) {
 
4512
                        SETLUT
 
4513
                } else {
 
4514
                        SETTDLUT
 
4515
                }
 
4516
                j++;
 
4517
                if ( j == step )
 
4518
                {
 
4519
                        j = 0;
 
4520
                        val += increment;
 
4521
                }
 
4522
        }
 
4523
 
 
4524
        if ( ( cclass == DirectColor || cclass == TrueColor ) && 
 
4525
                computeLutFromLevels == False )
 
4526
        {
 
4527
                outlevels = TrueOrDirectLevels( xp );
 
4528
        } 
 
4529
 
 
4530
        retval = GetXIELut( xp, p, lut, lutSize * lutCellSize, 
 
4531
                outlevels );
 
4532
        free( lut );
 
4533
        return( retval );
 
4534
}
 
4535
 
 
4536
int
 
4537
TrueOrDirectLevels(XParms xp)
 
4538
{
 
4539
        int     depth = xp->screenDepth;
 
4540
 
 
4541
        if ( rbits != gbits || gbits != bbits )
 
4542
        {
 
4543
                return( 1 << (  rbits + gbits + bbits ) );
 
4544
        } 
 
4545
        else
 
4546
        {
 
4547
                return( 1 << depth );
 
4548
        }
 
4549
}
 
4550
 
 
4551
int
 
4552
TripleTrueOrDirectLevels(XParms xp)
 
4553
{
 
4554
        int     depth = xp->screenDepth;
 
4555
 
 
4556
        if ( rbits != gbits || gbits != bbits )
 
4557
        {
 
4558
                return( 1 << depth );
 
4559
        } 
 
4560
        else
 
4561
        {
 
4562
                return( xp->vinfo.colormap_size );
 
4563
        }
 
4564
}
 
4565
 
 
4566
/* generate red_mult, green_mult, and blue_mult, and red_max, green_max,
 
4567
   blue_max, like in StandardColormaps */
 
4568
 
 
4569
int
 
4570
CreateStandardColormap(XParms xp, XStandardColormap *stdCmap, int atom)
 
4571
{
 
4572
        XWindowAttributes xwa;
 
4573
        unsigned long mask;
 
4574
        int     i, cclass;
 
4575
        int     r_mask, g_mask, b_mask;
 
4576
 
 
4577
#if     defined(__cplusplus) || defined(c_plusplus)
 
4578
        cclass = xp->vinfo.c_class;
 
4579
#else
 
4580
        cclass = xp->vinfo.class;
 
4581
#endif
 
4582
 
 
4583
        XGetWindowAttributes( xp->d, xp->w, &xwa );
 
4584
        stdCmap->colormap = xwa.colormap;
 
4585
 
 
4586
        if ( IsTrueColorOrDirectColor( cclass ) )
 
4587
        {
 
4588
                stdCmap->red_max = ( 1 << rbits ) - 1; 
 
4589
                stdCmap->green_max = ( 1 << gbits ) - 1;
 
4590
                stdCmap->blue_max = ( 1 << bbits ) - 1; 
 
4591
        }
 
4592
        else
 
4593
        {
 
4594
                XmuGetColormapAllocation(&xp->vinfo, atom, 
 
4595
                        &stdCmap->red_max, 
 
4596
                        &stdCmap->green_max, 
 
4597
                                &stdCmap->blue_max);
 
4598
        }
 
4599
 
 
4600
        r_mask = xp->vinfo.red_mask;
 
4601
        g_mask = xp->vinfo.green_mask;
 
4602
        b_mask = xp->vinfo.blue_mask;
 
4603
 
 
4604
        if ( r_mask )
 
4605
        {
 
4606
                mask = 1; i = 0;
 
4607
                while ( !( mask & r_mask ) ) { i+=1; mask = mask << 1; } 
 
4608
                stdCmap->red_mult = 1 << i; 
 
4609
        }
 
4610
        else
 
4611
        {
 
4612
                stdCmap->red_mult = 1;
 
4613
        }
 
4614
 
 
4615
        if ( g_mask )
 
4616
        {
 
4617
                mask = 1; i = 0;
 
4618
                while ( !( mask & g_mask ) ) { i+=1; mask = mask << 1; } 
 
4619
                stdCmap->green_mult = 1 << i; 
 
4620
        }
 
4621
        else
 
4622
        {
 
4623
                stdCmap->green_mult = 1;
 
4624
        }
 
4625
 
 
4626
        if ( b_mask )
 
4627
        {
 
4628
                mask = 1; i = 0;
 
4629
                while ( !( mask & b_mask ) ) { i+=1; mask = mask << 1; } 
 
4630
                stdCmap->blue_mult = 1 << i; 
 
4631
        }
 
4632
        else
 
4633
        {
 
4634
                stdCmap->blue_mult = 1;
 
4635
        }
 
4636
 
 
4637
        return( 1 );
 
4638
}
 
4639
 
 
4640
XiePhotomap 
 
4641
GetControlPlane(XParms xp, int which)
 
4642
{
 
4643
        ParmRec p;
 
4644
        XiePhotomap ControlPlane;
 
4645
 
 
4646
        ControlPlane = ( XiePhotomap ) NULL;
 
4647
        p.finfo.image1 = GetImageStruct( which ); 
 
4648
        p.buffer_size = 2048;
 
4649
        if ( p.finfo.image1 != ( XIEimage * ) NULL )
 
4650
        { 
 
4651
                ControlPlane = GetXIEPointPhotomap( xp, &p, 1, 2, True );
 
4652
        }
 
4653
        return( ControlPlane );
 
4654
}
 
4655
 
 
4656
/*
 
4657
 * integer cube roots by Newton's method
 
4658
 *
 
4659
 * Stephen Gildea, MIT X Consortium, July 1991
 
4660
 */
 
4661
 
 
4662
/* Newton's Method:  x_n+1 = x_n - ( f(x_n) / f'(x_n) ) */
 
4663
 
 
4664
/* for cube roots, x^3 - a = 0,  x_new = x - 1/3 (x - a/x^2) */
 
4665
 
 
4666
/*
 
4667
 * Quick and dirty cube roots.  Nothing fancy here, just Newton's method.
 
4668
 * Only works for positive integers (since that's all we need).
 
4669
 * We actually return floor(cbrt(a)) because that's what we need here, too.
 
4670
 */
 
4671
 
 
4672
static int 
 
4673
icbrt_with_guess(int a, int guess)
 
4674
{
 
4675
    register int delta;
 
4676
 
 
4677
    if (a <= 0)
 
4678
        return 0;
 
4679
    if (guess < 1)
 
4680
        guess = 1;
 
4681
 
 
4682
    do {
 
4683
        delta = (guess - a/(guess*guess))/3;
 
4684
        guess -= delta;
 
4685
    } while (delta != 0);
 
4686
 
 
4687
    if (guess*guess*guess > a)
 
4688
        guess--;
 
4689
 
 
4690
    return guess;
 
4691
}
 
4692
 
 
4693
static int 
 
4694
icbrt_with_bits(int a, 
 
4695
                int bits)       /* log 2 of a */
 
4696
 
 
4697
{
 
4698
    return icbrt_with_guess(a, a>>2*bits/3);
 
4699
}
 
4700
 
 
4701
int 
 
4702
icbrt(int a)            /* integer cube root */
 
4703
{
 
4704
    register int bits = 0;
 
4705
    register unsigned n = a;
 
4706
 
 
4707
    while (n)
 
4708
    {
 
4709
        bits++;
 
4710
        n >>= 1;
 
4711
    }
 
4712
    return icbrt_with_bits(a, bits);
 
4713
}