~sbeattie/ubuntu/lucid/vnc4/lp556147

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/XIE/mixie/process/mpcnst.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: mpcnst.c,v 1.4 2001/02/09 02:04:30 xorgcvs Exp $ */
 
2
/* AGE Logic - Oct 15 1995 - Larry Hare */
 
3
/**** module mpcnst.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
        mpcnst.c -- DDXIE constrain element
 
70
  
 
71
        Dean Verheiden && Larry Hare -- AGE Logic, Inc. May, 1993
 
72
  
 
73
*****************************************************************************/
 
74
/* $XFree86: xc/programs/Xserver/XIE/mixie/process/mpcnst.c,v 3.5 2001/12/14 19:58:44 dawes Exp $ */
 
75
 
 
76
 
 
77
#define _XIEC_MPCNST
 
78
#define _XIEC_PCNST
 
79
 
 
80
/*
 
81
 *  Include files
 
82
 */
 
83
 
 
84
/*
 
85
 *  Core X Includes
 
86
 */
 
87
#include <X.h>
 
88
#include <Xproto.h>
 
89
/*
 
90
 *  XIE Includes
 
91
 */
 
92
#include <XIE.h>
 
93
#include <XIEproto.h>
 
94
/*
 
95
 *  more X server includes.
 
96
 */
 
97
#include <misc.h>
 
98
#include <dixstruct.h>
 
99
/*
 
100
 *  Server XIE Includes
 
101
 */
 
102
#include <error.h>
 
103
#include <macro.h>
 
104
#include <element.h>
 
105
#include <texstr.h>
 
106
#include <xiemd.h>
 
107
#include <memory.h>
 
108
 
 
109
/*
 
110
 *  routines referenced by other DDXIE modules
 
111
 */
 
112
int     miAnalyzeConstrain();
 
113
 
 
114
/*
 
115
 *  routines used internal to this module
 
116
 */
 
117
static int CreateConstrain();
 
118
static int InitializeConstrain();
 
119
static int ActivateConstrain();
 
120
static int ResetConstrain();
 
121
static int DestroyConstrain();
 
122
 
 
123
/*
 
124
 * DDXIE ImportClientPhoto entry points
 
125
 */
 
126
static ddElemVecRec ConstrainVec = {
 
127
  CreateConstrain,
 
128
  InitializeConstrain,
 
129
  ActivateConstrain,
 
130
  (xieBoolProc)NULL,
 
131
  ResetConstrain,
 
132
  DestroyConstrain
 
133
  };
 
134
 
 
135
 
 
136
/*------------------------------------------------------------------------
 
137
------------------------  Local declares and defines  --------------------
 
138
------------------------------------------------------------------------*/
 
139
 
 
140
typedef struct _mpconstraindef {
 
141
        void    (*action) ();
 
142
        pointer lut;
 
143
        double  pad[7];
 
144
} mpCnstPvtRec, *mpCnstPvtPtr;
 
145
 
 
146
 
 
147
static void (*hc_nop())();
 
148
static void (*HCp_Rb())(), (*HCp_bb())(), (*HCp_Bb())(),
 
149
                           (*HCp_Pb())(), (*HCp_Qb())();
 
150
static void (*HCp_RB())(), (*HCp_bB())(), (*HCp_BB())(),
 
151
                           (*HCp_PB())(), (*HCp_QB())();
 
152
static void (*HCp_RP())(), (*HCp_bP())(), (*HCp_BP())(),
 
153
                           (*HCp_PP())(), (*HCp_QP())();
 
154
static void (*HCp_RQ())(), (*HCp_bQ())(), (*HCp_BQ())(),
 
155
                           (*HCp_PQ())(), (*HCp_QQ())();
 
156
 
 
157
static void (*(*prep_hc[5][5])())() = {
 
158
        hc_nop, hc_nop, hc_nop, hc_nop, hc_nop, /* [out=0][inp=0...4] */
 
159
        HCp_Rb, HCp_bb, HCp_Bb, HCp_Pb, HCp_Qb, /* [out=1][inp=0...4] */
 
160
        HCp_RB, HCp_bB, HCp_BB, HCp_PB, HCp_QB, /* [out=2][inp=0...4] */
 
161
        HCp_RP, HCp_bP, HCp_BP, HCp_PP, HCp_QP, /* [out=3][inp=0...4] */
 
162
        HCp_RQ, HCp_bQ, HCp_BQ, HCp_PQ, HCp_QQ, /* [out=4][inp=0...4] */
 
163
};
 
164
 
 
165
static void (*cs_nop())();
 
166
static void (*CSp_Rb())(), (*CSp_bb())(), (*CSp_Bb())(),
 
167
                           (*CSp_Pb())(), (*CSp_Qb())();
 
168
static void (*CSp_RB())(), (*CSp_bB())(), (*CSp_BB())(),
 
169
                           (*CSp_PB())(), (*CSp_QB())();
 
170
static void (*CSp_RP())(), (*CSp_bP())(), (*CSp_BP())(),
 
171
                           (*CSp_PP())(), (*CSp_QP())();
 
172
static void (*CSp_RQ())(), (*CSp_bQ())(), (*CSp_BQ())(),
 
173
                           (*CSp_PQ())(), (*CSp_QQ())();
 
174
 
 
175
static void (*(*prep_cs[5][5])())() = {
 
176
        cs_nop, cs_nop, cs_nop, cs_nop, cs_nop, /* [0][0...4] */
 
177
        CSp_Rb, CSp_bb, CSp_Bb, CSp_Pb, CSp_Qb, /* [1][0...4] */
 
178
        CSp_RB, CSp_bB, CSp_BB, CSp_PB, CSp_QB, /* [2][0...4] */
 
179
        CSp_RP, CSp_bP, CSp_BP, CSp_PP, CSp_QP, /* [3][0...4] */
 
180
        CSp_RQ, CSp_bQ, CSp_BQ, CSp_PQ, CSp_QQ, /* [4][0...4] */
 
181
};
 
182
 
 
183
/*------------------------------------------------------------------------
 
184
------------------------  fill in the vector  ---------------------------
 
185
------------------------------------------------------------------------*/
 
186
int miAnalyzeConstrain(flo,ped)
 
187
    floDefPtr flo;
 
188
    peDefPtr  ped;
 
189
{
 
190
 
 
191
    ped->ddVec = ConstrainVec;
 
192
 
 
193
    /* based on the technique, fill in the appropriate entry point vector */
 
194
 
 
195
    switch(((xieFloConstrain *)ped->elemRaw)->constrain) {
 
196
        case    xieValConstrainClipScale:
 
197
        case    xieValConstrainHardClip:
 
198
                break;
 
199
        default:
 
200
                ImplementationError(flo,ped, return(FALSE));
 
201
    }
 
202
 
 
203
    return TRUE;
 
204
}
 
205
 
 
206
 
 
207
/*------------------------------------------------------------------------
 
208
---------------------------- create peTex . . . --------------------------
 
209
------------------------------------------------------------------------*/
 
210
static int CreateConstrain(flo,ped)
 
211
    floDefPtr flo;
 
212
    peDefPtr  ped;
 
213
{
 
214
    int auxsize = xieValMaxBands * sizeof(mpCnstPvtRec);
 
215
 
 
216
    return MakePETex(flo,ped,auxsize,NO_SYNC,NO_SYNC);
 
217
 
218
 
 
219
 
 
220
/*------------------------------------------------------------------------
 
221
---------------------------- initialize peTex . . . ----------------------
 
222
------------------------------------------------------------------------*/
 
223
 
 
224
static int InitializeConstrain(flo,ped)
 
225
    floDefPtr flo;
 
226
    peDefPtr  ped;
 
227
{
 
228
    peTexPtr  pet = ped->peTex;
 
229
    pCnstDefPtr techpvt = (pCnstDefPtr)ped->techPvt;
 
230
    mpCnstPvtPtr pvt = (mpCnstPvtPtr) pet->private;
 
231
    bandPtr oband;
 
232
    bandPtr iband;
 
233
    int band, nbands, status;
 
234
 
 
235
    status =  InitReceptors(flo,ped,NO_DATAMAP,1) &&
 
236
                InitEmitter(flo,ped,NO_DATAMAP,NO_INPLACE);
 
237
 
 
238
    nbands = pet->receptor[SRCtag].inFlo->bands;
 
239
    iband = &(pet->receptor[SRCtag].band[0]);
 
240
    oband = &(pet->emitter[0]);
 
241
 
 
242
    for(band = 0; band < nbands; band++, pvt++, iband++, oband++) {
 
243
 
 
244
        int oo = IndexClass(oband->format->class);
 
245
        int ii = IndexClass(iband->format->class);
 
246
 
 
247
        switch(((xieFloConstrain *)ped->elemRaw)->constrain) {
 
248
 
 
249
        case    xieValConstrainClipScale:
 
250
                pvt->action =
 
251
                    ((*(prep_cs[oo][ii])) (iband, oband, pvt, techpvt, band)); 
 
252
                break;
 
253
        case    xieValConstrainHardClip:
 
254
                pvt->action =
 
255
                    ((*(prep_hc[oo][ii])) (iband, oband, pvt, techpvt, band)); 
 
256
                break;
 
257
        }
 
258
    }
 
259
    return status;
 
260
}
 
261
 
 
262
/*------------------------------------------------------------------------
 
263
----------------------------- crank some data ----------------------------
 
264
------------------------------------------------------------------------*/
 
265
static int ActivateConstrain(flo,ped,pet)
 
266
     floDefPtr flo;
 
267
     peDefPtr  ped;
 
268
     peTexPtr  pet;
 
269
{
 
270
    mpCnstPvtPtr pvt = (mpCnstPvtPtr) pet->private;
 
271
    int band, nbands = pet->receptor[SRCtag].inFlo->bands;
 
272
    bandPtr iband = &(pet->receptor[SRCtag].band[0]);
 
273
    bandPtr oband = &(pet->emitter[0]);
 
274
 
 
275
    for(band = 0; band < nbands; band++, pvt++, iband++, oband++) {
 
276
        register int bw = iband->format->width;
 
277
        pointer ivoid, ovoid;
 
278
 
 
279
        if (!(ivoid = GetCurrentSrc(flo,pet,iband)))
 
280
                continue;
 
281
 
 
282
        if (!pvt->action) {
 
283
            do { /* pass a clone of the current src strip downstream */
 
284
                if(!PassStrip(flo,pet,oband,iband->strip))
 
285
                    return(FALSE);
 
286
                ivoid = GetSrc(flo,pet,iband,iband->maxLocal,TRUE);
 
287
            } while (!ferrCode(flo) && ivoid) ;
 
288
            FreeData(flo, pet, iband, iband->current);
 
289
            continue;
 
290
        }
 
291
 
 
292
        if (!(ovoid = GetCurrentDst(flo,pet,oband)))
 
293
                continue;
 
294
 
 
295
        do {
 
296
            (*(pvt->action)) (ivoid, ovoid, pvt, bw);
 
297
            ivoid = GetNextSrc(flo,pet,iband,TRUE);
 
298
            ovoid = GetNextDst(flo,pet,oband,TRUE);
 
299
        } while (!ferrCode(flo) && ivoid && ovoid) ;
 
300
 
 
301
        FreeData(flo, pet, iband, iband->current);
 
302
    }
 
303
    return TRUE;
 
304
}
 
305
 
 
306
 
 
307
/*------------------------------------------------------------------------
 
308
------------------------ get rid of run-time stuff -----------------------
 
309
------------------------------------------------------------------------*/
 
310
static int ResetConstrain(flo,ped)
 
311
    floDefPtr flo;
 
312
    peDefPtr  ped;
 
313
{
 
314
    mpCnstPvtPtr pvt = (mpCnstPvtPtr) ped->peTex->private;
 
315
    int band;
 
316
 
 
317
    /* free any dynamic private data */
 
318
    for (band = 0 ; band < xieValMaxBands ; band++, pvt++)
 
319
        if (pvt->lut)
 
320
            pvt->lut = (pointer) XieFree(pvt->lut);
 
321
 
 
322
    ResetReceptors(ped);
 
323
    ResetEmitter(ped);
 
324
  
 
325
    return TRUE;
 
326
}
 
327
 
 
328
/*------------------------------------------------------------------------
 
329
-------------------------- get rid of this element -----------------------
 
330
------------------------------------------------------------------------*/
 
331
static int DestroyConstrain(flo,ped)
 
332
     floDefPtr flo;
 
333
     peDefPtr  ped;
 
334
{
 
335
    /* get rid of the peTex structure  */
 
336
    ped->peTex = (peTexPtr) XieFree(ped->peTex);
 
337
 
 
338
    /* zap this element's entry point vector */
 
339
    ped->ddVec.create = (xieIntProc)NULL;
 
340
    ped->ddVec.initialize = (xieIntProc)NULL;
 
341
    ped->ddVec.activate = (xieIntProc)NULL;
 
342
    ped->ddVec.reset = (xieIntProc)NULL;
 
343
    ped->ddVec.destroy = (xieIntProc)NULL;
 
344
 
 
345
    return TRUE;
 
346
 
347
 
 
348
/*------------------------------------------------------------------------
 
349
------------------------  This guy must be nuts  -------------------------
 
350
------------------------------------------------------------------------*/
 
351
 
 
352
/*----------------------------- HardClip  --------------------------------*/
 
353
 
 
354
/*
 
355
**  DO_HCb      - consume bits, produce bits.
 
356
**  DO_HCc      - consume bits, produce otype.
 
357
**  DO_HCcx     - consume bits, produce otype (using bitexpand).
 
358
**  DO_HCp      - consume itype, produce bits..
 
359
**  DO_HCfp     - consume floats, produce bits.
 
360
**  DO_HClt     - consume itype, produce otype (itype < otype).
 
361
**  DO_HCeq     - consume itype, produce otype (itype == otype).
 
362
**  DO_HCgt     - consume itype, produce otype (itype > otype)
 
363
**  DO_HCf      - consume floats, produce otype.
 
364
*/
 
365
 
 
366
static void constrain_nop(INP,OUTP,pvt,bw)
 
367
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;
 
368
{
 
369
        return;
 
370
}
 
371
static void (*hc_nop(iband,oband,pvt,techpvt,band))()
 
372
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;
 
373
{
 
374
        return constrain_nop;
 
375
}
 
376
static void (*cs_nop(iband,oband,pvt,techpvt,band))()
 
377
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;
 
378
{
 
379
        return constrain_nop;
 
380
}
 
381
 
 
382
static void clearbitline(INP,OUTP,pvt,bw)
 
383
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;
 
384
{
 
385
        action_clear(OUTP, bw, 0);
 
386
}
 
387
 
 
388
static void setbitline(INP,OUTP,pvt,bw)
 
389
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;
 
390
{
 
391
        action_set(OUTP, bw, 0);
 
392
}
 
393
 
 
394
static void copybitline(INP,OUTP,pvt,bw)
 
395
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;
 
396
{
 
397
        passcopy_bit(OUTP, INP, bw, 0);
 
398
}
 
399
 
 
400
static void invertbitline(INP,OUTP,pvt,bw)
 
401
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;
 
402
{
 
403
        passcopy_bit (OUTP, INP, bw, 0);
 
404
        action_invert(OUTP, bw, 0);
 
405
}
 
406
 
 
407
#define LEVELSM1(T) *((T *) &(pvt->pad[0]))
 
408
 
 
409
#define DO_HCb(fn_prep,fn_do_a, fn_do_b,itype,otype)                    \
 
410
static void                                                             \
 
411
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
412
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
413
{                                                                       \
 
414
        if (iband->format->levels == 1)                                 \
 
415
                return clearbitline;                                    \
 
416
        if (oband->format->levels == 1)                                 \
 
417
                return clearbitline;                                    \
 
418
        return copybitline;                                             \
 
419
 
420
 
 
421
#define DO_HCc(fn_prep,fn_do_a, fn_do_b,itype,otype)                    \
 
422
static void                                                             \
 
423
fn_do_a(INP,OUTP,pvt,bw)                                                \
 
424
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
425
{                                                                       \
 
426
        LogInt inval, M, *inp = (LogInt *) INP;                         \
 
427
        otype *outp = (otype *) OUTP;                                   \
 
428
        for ( ; bw >= LOGSIZE ; bw -= LOGSIZE)                          \
 
429
                for (M=LOGLEFT, inval = *inp++; M; LOGRIGHT(M))         \
 
430
                        *outp++ =  (inval & M) ? (otype) 1 : (otype) 0; \
 
431
        if (bw > 0)                                                     \
 
432
                for (M=LOGLEFT, inval = *inp++; bw; bw--, LOGRIGHT(M))  \
 
433
                        *outp++ =  (inval & M) ? (otype) 1 : (otype) 0; \
 
434
}                                                                       \
 
435
static void                                                             \
 
436
fn_do_b(INP,OUTP,pvt,bw)                                                \
 
437
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
438
{                                                                       \
 
439
        bzero((char *)OUTP, bw * sizeof(otype));                        \
 
440
        /* action_clear(OUTP, (bw * sizeof(otype)) << 3, 0); */         \
 
441
}                                                                       \
 
442
static void                                                             \
 
443
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
444
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
445
{                                                                       \
 
446
        if (iband->format->levels == 1)                                 \
 
447
                return fn_do_b;                                         \
 
448
        return fn_do_a;                                                 \
 
449
 
450
 
 
451
#define DO_HCcx(fn_prep,fn_do,fn_do_b,itype,otype)                      \
 
452
static void                                                             \
 
453
fn_do(INP,OUTP,pvt,bw)                                                  \
 
454
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
455
{                                                                       \
 
456
        bitexpand(INP, OUTP, bw, 0, 1);                                 \
 
457
}                                                                       \
 
458
static void                                                             \
 
459
fn_do_b(INP,OUTP,pvt,bw)                                                \
 
460
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
461
{                                                                       \
 
462
        bzero((char *)OUTP, bw * sizeof(otype));                        \
 
463
        /* action_clear(OUTP, (bw * sizeof(otype)) << 3, 0); */         \
 
464
}                                                                       \
 
465
static void                                                             \
 
466
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
467
    bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
468
{                                                                       \
 
469
        if (iband->format->levels == 1)                                 \
 
470
                return fn_do_b;                                         \
 
471
        return fn_do;                                                   \
 
472
 
473
 
 
474
#define DO_HCp(fn_prep,fn_do_a, fn_do_b,itype,otype)                    \
 
475
static void                                                             \
 
476
fn_do_a(INP,OUTP,pvt,bw)                                                \
 
477
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
478
{                                                                       \
 
479
        itype *inp = (itype *) INP;                                     \
 
480
        LogInt outval, M, *outp = (LogInt *) OUTP;                      \
 
481
        for ( ; bw >= LOGSIZE ; *outp++ = outval, bw -= LOGSIZE)        \
 
482
                for (M=LOGLEFT, outval = 0; M; LOGRIGHT(M))             \
 
483
                        if (*inp++)                                     \
 
484
                                outval |= M;                            \
 
485
        if (bw > 0) {                                                   \
 
486
                for (M=LOGLEFT, outval = 0; bw; bw--, LOGRIGHT(M))      \
 
487
                        if (*inp++)                                     \
 
488
                                outval |= M;                            \
 
489
                *outp = outval;                                         \
 
490
        }                                                               \
 
491
}                                                                       \
 
492
static void                                                             \
 
493
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
494
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
495
{                                                                       \
 
496
        if (oband->format->levels == 1)                                 \
 
497
                return clearbitline;                                    \
 
498
        return fn_do_a;                                                 \
 
499
 
500
 
 
501
#define DO_HCfp(fn_prep,fn_do_a, fn_do_b,itype,otype)                   \
 
502
static void                                                             \
 
503
fn_do_a(INP,OUTP,pvt,bw)                                                \
 
504
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
505
{                                                                       \
 
506
        itype *inp = (itype *) INP;                                     \
 
507
        LogInt outval, M, *outp = (LogInt *) OUTP;                      \
 
508
        for ( ; bw >= LOGSIZE ; *outp++ = outval, bw -= LOGSIZE)        \
 
509
                for (M=LOGLEFT, outval = 0; M; LOGRIGHT(M))             \
 
510
                        if (*inp++ >= (itype) 1.0)                      \
 
511
                                outval |= M;                            \
 
512
        if (bw > 0) {                                                   \
 
513
                for (M=LOGLEFT, outval = 0; bw; bw--, LOGRIGHT(M))      \
 
514
                        if (*inp++ >= (itype) 1.0)                      \
 
515
                                outval |= M;                            \
 
516
                *outp = outval;                                         \
 
517
        }                                                               \
 
518
}                                                                       \
 
519
static void                                                             \
 
520
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
521
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
522
{                                                                       \
 
523
        if (oband->format->levels == 1)                                 \
 
524
                return clearbitline;                                    \
 
525
        return fn_do_a;                                                 \
 
526
 
527
 
 
528
#define DO_HClt(fn_prep,fn_do_a, fn_do_b,itype,otype)                   \
 
529
static void                                                             \
 
530
fn_do_b(INP,OUTP,pvt,bw)                                                \
 
531
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
532
{                                                                       \
 
533
        itype *inp = (itype *) INP;                                     \
 
534
        otype *outp = (otype *) OUTP;                                   \
 
535
        while (bw-- > 0 ) {                                             \
 
536
                *outp++ = (otype) *inp++;                               \
 
537
        }                                                               \
 
538
}                                                                       \
 
539
static void                                                             \
 
540
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
541
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
542
{                                                                       \
 
543
        return fn_do_b;                                                 \
 
544
 
545
 
 
546
#define DO_HCeq(fn_prep,fn_do_a, fn_do_b,itype,otype)                   \
 
547
static void                                                             \
 
548
fn_do_a(INP,OUTP,pvt,bw)                                                \
 
549
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
550
{                                                                       \
 
551
        itype *inp = (itype *) INP;                                     \
 
552
        otype *outp = (otype *) OUTP;                                   \
 
553
        itype inval, lm1 = LEVELSM1(itype);                             \
 
554
        while (bw-- > 0 ) {                                             \
 
555
                if ((inval = *inp++) > lm1) inval = lm1;                \
 
556
                *outp++ = (otype) inval;                                \
 
557
        }                                                               \
 
558
}                                                                       \
 
559
/* fn_do_b was memcpy, now done at higher level with PassStrip */       \
 
560
static void                                                             \
 
561
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
562
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
563
{                                                                       \
 
564
        itype ilm1 = (itype)( (iband->format->levels)                   \
 
565
                                ? iband->format->levels - 1 : ~0);      \
 
566
        itype olm1 = (itype)( (oband->format->levels)                   \
 
567
                                ? oband->format->levels - 1 : ~0);      \
 
568
        if (ilm1 < olm1) {                                              \
 
569
                /*special hint to PassStrip */                          \
 
570
                return  (void (*) ()) 0;                                \
 
571
        }                                                               \
 
572
        LEVELSM1(itype) = (itype) olm1;                                 \
 
573
        return fn_do_a;                                                 \
 
574
 
575
 
 
576
#define DO_HCgt(fn_prep,fn_do_a, fn_do_b,itype,otype)                   \
 
577
static void                                                             \
 
578
fn_do_a(INP,OUTP,pvt,bw)                                                \
 
579
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
580
{                                                                       \
 
581
        itype *inp = (itype *) INP;                                     \
 
582
        otype *outp = (otype *) OUTP;                                   \
 
583
        itype inval, lm1 = LEVELSM1(itype);                             \
 
584
        while (bw-- > 0 ) {                                             \
 
585
                if ((inval = *inp++) > lm1) inval = lm1;                \
 
586
                *outp++ = (otype) inval;                                \
 
587
        }                                                               \
 
588
}                                                                       \
 
589
static void                                                             \
 
590
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
591
        bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
592
{                                                                       \
 
593
        otype olm1 = (otype)( (oband->format->levels)                   \
 
594
                                ? oband->format->levels - 1 : ~0);      \
 
595
        LEVELSM1(itype) = (itype) olm1;                                 \
 
596
        return fn_do_a;                                                 \
 
597
 
598
 
 
599
 
 
600
#define DO_HCf(fn_prep,fn_do_a,fn_do_b,itype,otype)                     \
 
601
static void                                                             \
 
602
fn_do_a(INP,OUTP,pvt,bw)                                                \
 
603
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
604
{                                                                       \
 
605
        itype *inp = (itype *) INP;                                     \
 
606
        otype *outp = (otype *) OUTP;                                   \
 
607
        itype inval, olm1 = *((itype *) &(pvt->pad[0]));                \
 
608
        while (bw-- > 0 ) {                                             \
 
609
                if ((inval = *inp++) > olm1) inval = olm1;              \
 
610
                else if (inval < 0) inval = (itype) 0;                  \
 
611
                *outp++ = (otype) inval;                                \
 
612
        }                                                               \
 
613
}                                                                       \
 
614
static void                                                             \
 
615
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
616
    bandPtr iband, oband; mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band; \
 
617
{                                                                       \
 
618
        otype olm1 = (otype)( (oband->format->levels)                   \
 
619
                                ? oband->format->levels - 1 : ~0);      \
 
620
        *((itype *) &(pvt->pad[0])) = olm1;                             \
 
621
        return fn_do_a;                                                 \
 
622
}
 
623
 
 
624
DO_HCb  (HCp_bb, HCa_bb, HCb_bb, BitPixel,  BitPixel)
 
625
DO_HCp  (HCp_Bb, HCa_Bb, HCb_Bb, BytePixel, BitPixel)
 
626
DO_HCp  (HCp_Pb, HCa_Pb, HCb_Pb, PairPixel, BitPixel)
 
627
DO_HCp  (HCp_Qb, HCa_Qb, HCb_Qb, QuadPixel, BitPixel)
 
628
DO_HCfp (HCp_Rb, HCa_Rb, HCb_Rb, RealPixel, BitPixel)
 
629
 
 
630
DO_HCcx (HCp_bB, HCa_bB, HCb_bB, BitPixel,  BytePixel)
 
631
DO_HCeq (HCp_BB, HCa_BB, HCb_BB, BytePixel, BytePixel)
 
632
DO_HCgt (HCp_PB, HCa_PB, HCb_PB, PairPixel, BytePixel)
 
633
DO_HCgt (HCp_QB, HCa_QB, HCb_QB, QuadPixel, BytePixel)
 
634
DO_HCf  (HCp_RB, HCa_RB, HCb_RB, RealPixel, BytePixel)
 
635
 
 
636
DO_HCc  (HCp_bP, HCa_bP, HCb_bP, BitPixel,  PairPixel)
 
637
DO_HClt (HCp_BP, HCa_BP, HCb_BP, BytePixel, PairPixel)
 
638
DO_HCeq (HCp_PP, HCa_PP, HCb_PP, PairPixel, PairPixel)
 
639
DO_HCgt (HCp_QP, HCa_QP, HCb_QP, QuadPixel, PairPixel)
 
640
DO_HCf  (HCp_RP, HCa_RP, HCb_RP, RealPixel, PairPixel)
 
641
 
 
642
DO_HCc  (HCp_bQ, HCa_bQ, HCb_bQ, BitPixel,  QuadPixel)
 
643
DO_HClt (HCp_BQ, HCa_BQ, HCb_BQ, BytePixel, QuadPixel)
 
644
DO_HClt (HCp_PQ, HCa_PQ, HCb_PQ, PairPixel, QuadPixel)
 
645
DO_HCeq (HCp_QQ, HCa_QQ, HCb_QQ, QuadPixel, QuadPixel)
 
646
DO_HCf  (HCp_RQ, HCa_RQ, HCb_RQ, RealPixel, QuadPixel)
 
647
 
 
648
#undef  LEVELSM1
 
649
 
 
650
/*----------------------------- ClipScale --------------------------------*/
 
651
 
 
652
typedef float   ConstrainFloat;
 
653
#define HALF    ((ConstrainFloat) 0.5)
 
654
 
 
655
#define LBOUND(T)       *((T *) &(pvt->pad[0]))
 
656
#define UBOUND(T)       *((T *) &(pvt->pad[1]))
 
657
#define OLOW(T)         *((T *) &(pvt->pad[2]))
 
658
#define OHIGH(T)        *((T *) &(pvt->pad[3]))
 
659
#define FLT_SF          *((ConstrainFloat *) &(pvt->pad[4]))
 
660
#define FLT_OFF         *((ConstrainFloat *) &(pvt->pad[5]))
 
661
#define INT_SF          *((INT32 *) &(pvt->pad[4]))
 
662
#define INT_OFF         *((INT32 *) &(pvt->pad[5]))
 
663
 
 
664
static void
 
665
cs_scale_equation(pvt,techpvt,band)
 
666
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;
 
667
{
 
668
    QuadPixel olow = techpvt->output_low[band];
 
669
    ConstrainFloat ilow = techpvt->input_low[band];
 
670
    ConstrainFloat sf = (techpvt->output_high[band] - olow) /
 
671
                                (techpvt->input_high[band] - ilow);
 
672
    FLT_SF = sf;
 
673
    FLT_OFF = (ConstrainFloat) olow - sf * ilow;
 
674
}
 
675
 
 
676
static void
 
677
cs_fix_bits(pvt,techpvt,band)
 
678
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;
 
679
{
 
680
    ConstrainFloat  ilow = techpvt->input_low[band];
 
681
    ConstrainFloat ihigh = techpvt->input_high[band];
 
682
    QuadPixel       olow = techpvt->output_low[band];
 
683
    QuadPixel      ohigh = techpvt->output_high[band];
 
684
    /*  Prep guarantees ilow != ihigh, but what if ilow > ihigh */ 
 
685
    if (ilow == 0.0 && ihigh == 1.0) {
 
686
        OLOW(QuadPixel) = olow;
 
687
        OHIGH(QuadPixel) = ohigh;
 
688
        return;
 
689
    } else if (ilow == 1.0 && ihigh == 0.0) {
 
690
        OLOW(QuadPixel) = ohigh;
 
691
        OHIGH(QuadPixel) = olow;
 
692
        return;
 
693
    }
 
694
    cs_scale_equation(pvt,techpvt,band);
 
695
    if (ilow < ihigh) {
 
696
        if      (0.0 <= ilow)   OLOW(QuadPixel) = olow;
 
697
        else if (0.0 >= ihigh)  OLOW(QuadPixel) = ohigh;
 
698
        else                    OLOW(QuadPixel) = FLT_SF * 0. + FLT_OFF + HALF;
 
699
        if      (1.0 <= ilow)   OHIGH(QuadPixel) = olow;
 
700
        else if (1.0 >= ihigh)  OHIGH(QuadPixel) = ohigh;
 
701
        else                    OHIGH(QuadPixel) = FLT_SF * 1. + FLT_OFF + HALF;
 
702
    } else {
 
703
        if      (0.0 >= ilow)   OLOW(QuadPixel) = olow;
 
704
        else if (0.0 <= ihigh)  OLOW(QuadPixel) = ohigh;
 
705
        else                    OLOW(QuadPixel) = FLT_SF * 0. + FLT_OFF + HALF;
 
706
        if      (1.0 >= ilow)   OHIGH(QuadPixel) = olow;
 
707
        else if (1.0 <= ihigh)  OHIGH(QuadPixel) = ohigh;
 
708
        else                    OHIGH(QuadPixel) = FLT_SF * 1. + FLT_OFF + HALF;
 
709
    }
 
710
}
 
711
 
 
712
#define DO_CSb(fn_prep,fn_do,fn_do_b,itype,otype)                       \
 
713
static void                                                             \
 
714
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
715
    bandPtr iband, oband;                                               \
 
716
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
717
{                                                                       \
 
718
        if (iband->format->levels == 1 || oband->format->levels == 1)   \
 
719
                return clearbitline;                                    \
 
720
        cs_fix_bits(pvt,techpvt,band);                                  \
 
721
        return (OLOW(QuadPixel) == OHIGH(QuadPixel))                    \
 
722
               ? ((OLOW(QuadPixel) == 0) ? clearbitline: setbitline)    \
 
723
               : ((OLOW(QuadPixel) == 0) ? copybitline: invertbitline); \
 
724
 
725
 
 
726
 
 
727
#define DO_CSc(fn_prep,fn_do,fn_do_b,itype,otype)                       \
 
728
static void                                                             \
 
729
fn_do(INP,OUTP,pvt,bw)                                                  \
 
730
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
731
{                                                                       \
 
732
        LogInt inval, M, *inp = (LogInt *) INP;                         \
 
733
        otype *outp = (otype *) OUTP;                                   \
 
734
        otype olow = OLOW(otype), ohigh = OHIGH(otype);                 \
 
735
        for ( ; bw >= LOGSIZE ; bw -= LOGSIZE)                          \
 
736
                for (M=LOGLEFT, inval = *inp++; M; LOGRIGHT(M))         \
 
737
                        *outp++ =  (inval & M) ? ohigh : olow ;         \
 
738
        if (bw > 0)                                                     \
 
739
                for (M=LOGLEFT, inval = *inp++; bw; bw--, LOGRIGHT(M))  \
 
740
                        *outp++ =  (inval & M) ? ohigh : olow ;         \
 
741
}                                                                       \
 
742
static void                                                             \
 
743
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
744
    bandPtr iband, oband;                                               \
 
745
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
746
{                                                                       \
 
747
        cs_fix_bits(pvt,techpvt,band);                                  \
 
748
        OLOW(otype)  = OLOW(QuadPixel);                                 \
 
749
        OHIGH(otype) = OHIGH(QuadPixel);                                \
 
750
        return fn_do;                                                   \
 
751
 
752
 
 
753
#define DO_CScx(fn_prep,fn_do,fn_do_b,itype,otype)                      \
 
754
static void                                                             \
 
755
fn_do(INP,OUTP,pvt,bw)                                                  \
 
756
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
757
{                                                                       \
 
758
        otype olow = OLOW(otype), ohigh = OHIGH(otype);                 \
 
759
        bitexpand(INP, OUTP, bw, olow, ohigh);                          \
 
760
}                                                                       \
 
761
static void                                                             \
 
762
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
763
    bandPtr iband, oband;                                               \
 
764
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
765
{                                                                       \
 
766
        cs_fix_bits(pvt,techpvt,band);                                  \
 
767
        OLOW(otype)  = OLOW(QuadPixel);                                 \
 
768
        OHIGH(otype) = OHIGH(QuadPixel);                                \
 
769
        return fn_do;                                                   \
 
770
 
771
 
 
772
#define DO_CSp(fn_prep,fn_do,fn_do_b,itype,otype)                       \
 
773
static void                                                             \
 
774
fn_do(INP,OUTP,pvt,bw)                                                  \
 
775
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
776
{                                                                       \
 
777
        itype *inp = (itype *) INP;                                     \
 
778
        LogInt outval, M, *outp = (LogInt *) OUTP;                      \
 
779
        itype imedian = UBOUND(itype);                                  \
 
780
        for ( ; bw >= LOGSIZE ; *outp++ = outval, bw -= LOGSIZE)        \
 
781
                for (M=LOGLEFT, outval = 0; M; LOGRIGHT(M))             \
 
782
                        if (*inp++ > imedian)                           \
 
783
                                outval |= M;                            \
 
784
        if (bw > 0) {                                                   \
 
785
                for (M=LOGLEFT, outval = 0; bw; bw--, LOGRIGHT(M))      \
 
786
                        if (*inp++ > imedian)                           \
 
787
                                outval |= M;                            \
 
788
                *outp = outval;                                         \
 
789
        }                                                               \
 
790
}                                                                       \
 
791
static void                                                             \
 
792
fn_do_b(INP,OUTP,pvt,bw)                                                \
 
793
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
794
{                                                                       \
 
795
        itype *inp = (itype *) INP;                                     \
 
796
        LogInt outval, M, *outp = (LogInt *) OUTP;                      \
 
797
        itype imedian = UBOUND(itype);                                  \
 
798
        for ( ; bw >= LOGSIZE ; *outp++ = outval, bw -= LOGSIZE)        \
 
799
                for (M=LOGLEFT, outval = 0; M; LOGRIGHT(M))             \
 
800
                        if (*inp++ <= imedian)                          \
 
801
                                outval |= M;                            \
 
802
        if (bw > 0) {                                                   \
 
803
                for (M=LOGLEFT, outval = 0; bw; bw--, LOGRIGHT(M))      \
 
804
                        if (*inp++ <= imedian)                          \
 
805
                                outval |= M;                            \
 
806
                *outp = outval;                                         \
 
807
        }                                                               \
 
808
}                                                                       \
 
809
static void                                                             \
 
810
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
811
    bandPtr iband, oband;                                               \
 
812
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
813
{                                                                       \
 
814
        otype olow = techpvt->output_low[band];                         \
 
815
        otype ohigh = techpvt->output_high[band];                       \
 
816
        if (olow == ohigh)                                              \
 
817
                return (olow == 0) ? clearbitline : setbitline;         \
 
818
        UBOUND(itype) = HALF *                                          \
 
819
                (techpvt->input_low[band] + techpvt->input_high[band]); \
 
820
        return  (techpvt->input_low[band] < techpvt->input_high[band])  \
 
821
                        ? fn_do : fn_do_b;                              \
 
822
 
823
 
 
824
#define DO_CS(fn_prep,fn_do,fn_do_b,itype,otype)                        \
 
825
static void                                                             \
 
826
fn_do(INP,OUTP,pvt,bw)                                                  \
 
827
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
828
{                                                                       \
 
829
        itype *inp = (itype *) INP; otype *outp = (otype *) OUTP;       \
 
830
        itype inv, lbound = LBOUND(itype), ubound = UBOUND(itype);      \
 
831
        otype out, olow = OLOW(otype), ohigh = OHIGH(otype);            \
 
832
        ConstrainFloat sf = FLT_SF, offset = FLT_OFF;                   \
 
833
        while (bw-- > 0) {                                              \
 
834
                inv = *inp++;                                           \
 
835
                out = olow;                                             \
 
836
                if (inv >= ubound)                                      \
 
837
                        out = ohigh;                                    \
 
838
                else if (inv > lbound)                                  \
 
839
                        out = (otype)(sf * inv + offset);               \
 
840
                *outp++ = out;                                          \
 
841
        }                                                               \
 
842
}                                                                       \
 
843
static void                                                             \
 
844
fn_do_b(INP,OUTP,pvt,bw)                                                \
 
845
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
846
{                                                                       \
 
847
        itype *inp = (itype *) INP; otype *outp = (otype *) OUTP;       \
 
848
        itype inv, lbound = LBOUND(itype), ubound = UBOUND(itype);      \
 
849
        otype out, olow = OLOW(otype), ohigh = OHIGH(otype);            \
 
850
        ConstrainFloat sf = FLT_SF, offset = FLT_OFF;                   \
 
851
        while (bw-- > 0) {                                              \
 
852
                inv = *inp++;                                           \
 
853
                out = ohigh;                                            \
 
854
                if (inv >= lbound)                                      \
 
855
                        out = olow;                                     \
 
856
                else if (inv > ubound)                                  \
 
857
                        out = (otype)(sf * inv + offset);               \
 
858
                *outp++ = out;                                          \
 
859
        }                                                               \
 
860
}                                                                       \
 
861
static void                                                             \
 
862
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
863
    bandPtr iband, oband;                                               \
 
864
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
865
{                                                                       \
 
866
        OLOW(otype) = techpvt->output_low[band];                        \
 
867
        OHIGH(otype) = techpvt->output_high[band];                      \
 
868
        LBOUND(itype) = (itype) (techpvt->input_low[band] + HALF);      \
 
869
        UBOUND(itype) = (itype) (techpvt->input_high[band] + HALF);     \
 
870
        cs_scale_equation(pvt,techpvt,band);                            \
 
871
        FLT_OFF += HALF;                                                \
 
872
        return (FLT_SF >= 0.0) ? fn_do : fn_do_b;                       \
 
873
}
 
874
 
 
875
#if defined(USE_FLOATS)
 
876
#define DO_CSi(fn_prep,fn_do,fn_do_b,itype,otype,shift)                 \
 
877
        DO_CS(fn_prep,fn_do,fn_do_b,itype,otype) 
 
878
#else
 
879
/* XXX need LUT based approach for small sizes */
 
880
#define DO_CSi_part1(fna,itype,otype,shift)                             \
 
881
static void                                                             \
 
882
fna(INP,OUTP,pvt,bw)                                                    \
 
883
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
884
{                                                                       \
 
885
        itype *inp = (itype *) INP; otype *outp = (otype *) OUTP;       \
 
886
        otype out, olow = OLOW(otype), ohigh = OHIGH(otype);            \
 
887
        INT32 lbound = (INT32) LBOUND(itype);                           \
 
888
        INT32 ubound = (INT32) UBOUND(itype);                           \
 
889
        INT32 int_sf = INT_SF, int_off = INT_OFF;                       \
 
890
        CARD32 inv;                                                     \
 
891
        while (bw > 0) {                                                \
 
892
            inv = *inp++;                                               \
 
893
            out = ohigh;                                                \
 
894
            bw--;                                                       \
 
895
            if (inv < ubound) {                                         \
 
896
                out = (otype)((int_sf * inv + int_off)>>shift);         \
 
897
                if (inv <= lbound)                                      \
 
898
                        out = olow;                                     \
 
899
            }                                                           \
 
900
            *outp++ = out;                                              \
 
901
        }                                                               \
 
902
}
 
903
#define DO_CSi_part2(fnb,itype,otype,shift)                             \
 
904
static void                                                             \
 
905
fnb(INP,OUTP,pvt,bw)                                                    \
 
906
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
907
{                                                                       \
 
908
        itype *inp = (itype *) INP; otype *outp = (otype *) OUTP;       \
 
909
        otype out, olow = OLOW(otype), ohigh = OHIGH(otype);            \
 
910
        INT32 lbound = (INT32) LBOUND(itype);                           \
 
911
        INT32 ubound = (INT32) UBOUND(itype);                           \
 
912
        INT32 int_sf = INT_SF, int_off = INT_OFF;                       \
 
913
        CARD32 inv;                                                     \
 
914
        while (bw > 0) {                                                \
 
915
            inv = *inp++;                                               \
 
916
            out = olow;                                                 \
 
917
            bw--;                                                       \
 
918
            if (inv < lbound) {                                         \
 
919
                out = (otype)((int_sf * inv + int_off)>>shift);         \
 
920
                if (inv <= ubound)                                      \
 
921
                        out = ohigh;                                    \
 
922
            }                                                           \
 
923
            *outp++ = out;                                              \
 
924
        }                                                               \
 
925
}
 
926
/* some compilers gag on long macros. somehow this helps */
 
927
#define DO_CSi(fn_prep,fn_do,fn_do_b,itype,otype,shift)                 \
 
928
DO_CSi_part1(fn_do,itype,otype,shift)                                   \
 
929
DO_CSi_part2(fn_do_b,itype,otype,shift)                                 \
 
930
static void                                                             \
 
931
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
932
    bandPtr iband, oband;                                               \
 
933
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
934
{                                                                       \
 
935
        CARD32 olow, ohigh; INT32 int_sf, int_off;                      \
 
936
        olow = techpvt->output_low[band];                               \
 
937
        ohigh = techpvt->output_high[band];                             \
 
938
        LBOUND(itype) = (itype) (techpvt->input_low[band] + HALF);      \
 
939
        UBOUND(itype) = (itype) (techpvt->input_high[band] + HALF);     \
 
940
        OLOW(otype) = olow = techpvt->output_low[band];                 \
 
941
        OHIGH(otype) = ohigh = techpvt->output_high[band];              \
 
942
        olow <<= shift;                                                 \
 
943
        ohigh <<= shift;                                                \
 
944
        INT_SF = int_sf = (ohigh - olow) /                              \
 
945
                (techpvt->input_high[band] - techpvt->input_low[band]); \
 
946
        INT_OFF = int_off = (1<<(shift-1)) + olow -                     \
 
947
                        int_sf * (INT32) techpvt->input_low[band];      \
 
948
        INT_SF = int_sf;                                                \
 
949
        INT_OFF = int_off;                                              \
 
950
        return (int_sf >= 0) ? fn_do : fn_do_b;                         \
 
951
}
 
952
#endif
 
953
 
 
954
#define DO_CSf(fn_prep,fn_do,fn_do_b,itype,otype)                       \
 
955
static void                                                             \
 
956
fn_do(INP,OUTP,pvt,bw)                                                  \
 
957
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
958
{                                                                       \
 
959
        itype *inp = (itype *) INP; otype *outp = (otype *) OUTP;       \
 
960
        itype inv, lbound = LBOUND(itype), ubound = UBOUND(itype);      \
 
961
        otype out, olow = OLOW(otype), ohigh = OHIGH(otype);            \
 
962
        ConstrainFloat sf = FLT_SF, offset = FLT_OFF;                   \
 
963
        while (bw-- > 0) {                                              \
 
964
                inv = *inp++;                                           \
 
965
                out = olow;                                             \
 
966
                if (inv >= ubound)                                      \
 
967
                        out = ohigh;                                    \
 
968
                else if (inv > lbound)                                  \
 
969
                        out = (otype)(sf * inv + offset);               \
 
970
                *outp++ = out;                                          \
 
971
        }                                                               \
 
972
}                                                                       \
 
973
static void                                                             \
 
974
fn_do_b(INP,OUTP,pvt,bw)                                                \
 
975
        pointer INP; pointer OUTP; mpCnstPvtPtr pvt; int bw;            \
 
976
{                                                                       \
 
977
        itype *inp = (itype *) INP; otype *outp = (otype *) OUTP;       \
 
978
        itype inv, lbound = LBOUND(itype), ubound = UBOUND(itype);      \
 
979
        otype out, olow = OLOW(otype), ohigh = OHIGH(otype);            \
 
980
        ConstrainFloat sf = FLT_SF, offset = FLT_OFF;                   \
 
981
        while (bw-- > 0) {                                              \
 
982
                inv = *inp++;                                           \
 
983
                out = ohigh;                                            \
 
984
                if (inv >= lbound)                                      \
 
985
                        out = olow;                                     \
 
986
                else if (inv > ubound)                                  \
 
987
                        out = (otype)(sf * inv + offset);               \
 
988
                *outp++ = out;                                          \
 
989
        }                                                               \
 
990
}                                                                       \
 
991
static void                                                             \
 
992
(*fn_prep (iband,oband,pvt,techpvt,band))()                             \
 
993
    bandPtr iband, oband;                                               \
 
994
    mpCnstPvtPtr pvt; pCnstDefPtr techpvt; int band;                    \
 
995
{                                                                       \
 
996
        OLOW(otype) = techpvt->output_low[band];                        \
 
997
        OHIGH(otype) = techpvt->output_high[band];                      \
 
998
        LBOUND(itype) = (itype) techpvt->input_low[band];               \
 
999
        UBOUND(itype) = (itype) techpvt->input_high[band];              \
 
1000
        cs_scale_equation(pvt,techpvt,band);                            \
 
1001
        return (FLT_SF >= 0.0) ? fn_do : fn_do_b;                       \
 
1002
}
 
1003
 
 
1004
DO_CSb  (CSp_bb, CSa_bb, CSb_bb, BitPixel,  BitPixel)
 
1005
DO_CSp  (CSp_Bb, CSa_Bb, CSb_Bb, BytePixel, BitPixel)
 
1006
DO_CSp  (CSp_Pb, CSa_Pb, CSb_Pb, PairPixel, BitPixel)
 
1007
DO_CSp  (CSp_Qb, CSa_Qb, CSb_Qb, QuadPixel, BitPixel)
 
1008
DO_CSp  (CSp_Rb, CSa_Rb, CSb_Rb, RealPixel, BitPixel)
 
1009
 
 
1010
DO_CScx (CSp_bB, CSa_bB, CSb_bB, BitPixel,  BytePixel)
 
1011
DO_CSi  (CSp_BB, CSa_BB, CSb_BB, BytePixel, BytePixel, 22)
 
1012
DO_CSi  (CSp_PB, CSa_PB, CSb_PB, PairPixel, BytePixel, 22)
 
1013
DO_CSi  (CSp_QB, CSa_QB, CSb_QB, QuadPixel, BytePixel, 22)
 
1014
DO_CSf  (CSp_RB, CSa_RB, CSb_RB, RealPixel, BytePixel)
 
1015
 
 
1016
DO_CSc  (CSp_bP, CSa_bP, CSb_bP, BitPixel,  PairPixel)
 
1017
DO_CSi  (CSp_BP, CSa_BP, CSb_BP, BytePixel, PairPixel, 14)
 
1018
DO_CSi  (CSp_PP, CSa_PP, CSb_PP, PairPixel, PairPixel, 14)
 
1019
DO_CSi  (CSp_QP, CSa_QP, CSb_QP, QuadPixel, PairPixel, 14)
 
1020
DO_CSf  (CSp_RP, CSa_RP, CSb_RP, RealPixel, PairPixel)
 
1021
 
 
1022
DO_CSc  (CSp_bQ, CSa_bQ, CSb_bQ, BitPixel,  QuadPixel)
 
1023
DO_CSi  (CSp_BQ, CSa_BQ, CSb_BQ, BytePixel, QuadPixel, 6)
 
1024
DO_CSi  (CSp_PQ, CSa_PQ, CSb_PQ, PairPixel, QuadPixel, 6)
 
1025
DO_CSi  (CSp_QQ, CSa_QQ, CSb_QQ, QuadPixel, QuadPixel, 6)
 
1026
DO_CSf  (CSp_RQ, CSa_RQ, CSb_RQ, RealPixel, QuadPixel)
 
1027
 
 
1028
#undef LBOUND
 
1029
#undef HBOUND
 
1030
#undef OLOW
 
1031
#undef OHIGH
 
1032
#undef FLT_SF
 
1033
#undef FLT_OFF
 
1034
#undef INT_SF
 
1035
#undef INT_OFF
 
1036
 
 
1037
/* end module mpcnst.c */