e:/XFree86 for RH 8.0/XFree86-4.2.0/xc/programs/Xserver/XIE/mixie/process/mparith.c

Go to the documentation of this file.
00001 /* $Xorg: mparith.c,v 1.6 2001/02/09 02:04:29 xorgcvs Exp $ */ 00002 /* AGE Logic - Oct 15 1995 - Larry Hare */ 00003 /**** module mparith.c ****/ 00004 /****************************************************************************** 00005 00006 Copyright 1993, 1994, 1998 The Open Group 00007 00008 Permission to use, copy, modify, distribute, and sell this software and its 00009 documentation for any purpose is hereby granted without fee, provided that 00010 the above copyright notice appear in all copies and that both that 00011 copyright notice and this permission notice appear in supporting 00012 documentation. 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00020 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 00024 Except as contained in this notice, the name of The Open Group shall not be 00025 used in advertising or otherwise to promote the sale, use or other dealings 00026 in this Software without prior written authorization from The Open Group. 00027 00028 00029 NOTICE 00030 00031 This software is being provided by AGE Logic, Inc. under the 00032 following license. By obtaining, using and/or copying this software, 00033 you agree that you have read, understood, and will comply with these 00034 terms and conditions: 00035 00036 Permission to use, copy, modify, distribute and sell this 00037 software and its documentation for any purpose and without 00038 fee or royalty and to grant others any or all rights granted 00039 herein is hereby granted, provided that you agree to comply 00040 with the following copyright notice and statements, including 00041 the disclaimer, and that the same appears on all copies and 00042 derivative works of the software and documentation you make. 00043 00044 "Copyright 1993, 1994 by AGE Logic, Inc." 00045 00046 THIS SOFTWARE IS PROVIDED "AS IS". AGE LOGIC MAKES NO 00047 REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of 00048 example, but not limitation, AGE LOGIC MAKE NO 00049 REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS 00050 FOR ANY PARTICULAR PURPOSE OR THAT THE SOFTWARE DOES NOT 00051 INFRINGE THIRD-PARTY PROPRIETARY RIGHTS. AGE LOGIC 00052 SHALL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE. IN NO 00053 EVENT SHALL EITHER PARTY BE LIABLE FOR ANY INDIRECT, 00054 INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS 00055 OF PROFITS, REVENUE, DATA OR USE, INCURRED BY EITHER PARTY OR 00056 ANY THIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT OR 00057 BASED ON A WARRANTY, EVEN IF AGE LOGIC LICENSEES 00058 HEREUNDER HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH 00059 DAMAGES. 00060 00061 The name of AGE Logic, Inc. may not be used in 00062 advertising or publicity pertaining to this software without 00063 specific, written prior permission from AGE Logic. 00064 00065 Title to this software shall at all times remain with AGE 00066 Logic, Inc. 00067 ***************************************************************************** 00068 00069 mparith.c -- DDXIE arithmetic and math element 00070 00071 Larry Hare -- AGE Logic, Inc. August, 1993 00072 00073 *****************************************************************************/ 00074 /* $XFree86: xc/programs/Xserver/XIE/mixie/process/mparith.c,v 3.4 2001/01/17 22:13:10 dawes Exp $ */ 00075 00076 00077 #define _XIEC_MPARITH 00078 #define _XIEC_PARITH 00079 00080 /* 00081 * Include files 00082 */ 00083 00084 /* 00085 * Core X Includes 00086 */ 00087 #include <X.h> 00088 #include <Xproto.h> 00089 /* 00090 * XIE Includes 00091 */ 00092 #include <XIE.h> 00093 #include <XIEproto.h> 00094 /* 00095 * more X server includes. 00096 */ 00097 #include <misc.h> 00098 #include <dixstruct.h> 00099 /* 00100 * Server XIE Includes 00101 */ 00102 #include <error.h> 00103 #include <macro.h> 00104 #include <element.h> 00105 #include <texstr.h> 00106 #include <xiemd.h> 00107 #include <memory.h> 00108 00109 /* 00110 ** Most machines will work fine using the double precision versions 00111 ** of the math functions. If they give you problems, or if you 00112 ** want a bit more speed, then pick one of the following sets of 00113 ** defines. Enjoy. While you are thinking about this you might 00114 ** want to consider changing the cube root function in mprgb.c 00115 ** with fpow(x,1./3.) or powf(x,1./3.). Another similar area is 00116 ** in mpgeomaa.c for the gaussian technique. 00117 */ 00118 00119 #if defined(USE_EXPF) 00120 /* 00121 ** The very newest ANSI-C libraries promote this style of floating 00122 ** functions. Even if you have these available, you may need to 00123 ** use special compiler options, and prototypes from math.h 00124 */ 00125 # define exp expf 00126 # define log logf 00127 # define pow powf 00128 # define sqrt sqrtf 00129 #endif 00130 00131 #if defined(USE_FEXP) 00132 /* 00133 ** This is the more antique way to get floating math functions. But 00134 ** you may have to use compiler options or otherwise stand on your 00135 ** head to do this safely. Otherwise the argument may get promoted. 00136 */ 00137 # define exp fexp 00138 # define log flog 00139 # define pow fpow 00140 # define sqrt fsqrt 00141 #endif 00142 00143 /* 00144 * routines referenced by other DDXIE modules 00145 */ 00146 int miAnalyzeArith(); 00147 int miAnalyzeMath(); 00148 00149 /* 00150 * routines used internal to this module 00151 */ 00152 static int CreateArith(); 00153 static int InitializeArith(); 00154 static int ResetArith(); 00155 static int DestroyArith(); 00156 00157 static int ActivateArithMROI(); 00158 static int ActivateArithDROI(); 00159 static int SetupArith(); 00160 static void ClearArith(); /* and Math */ 00161 00162 static int CreateMath(); 00163 static int InitializeMath(); 00164 static int SetupMath(); 00165 00166 /* 00167 * DDXIE Arithmetic and Math entry points 00168 */ 00169 static ddElemVecRec ArithVec = { 00170 CreateArith, 00171 InitializeArith, 00172 (xieIntProc) NULL, 00173 (xieIntProc) NULL, 00174 ResetArith, 00175 DestroyArith 00176 }; 00177 00178 static ddElemVecRec MathVec = { 00179 CreateMath, 00180 InitializeMath, 00181 ActivateArithMROI, /* yes, arith */ 00182 (xieIntProc) NULL, 00183 ResetArith, /* yes, arith */ 00184 DestroyArith /* yes, arith */ 00185 }; 00186 00187 /* 00188 * Local Declarations. 00189 */ 00190 00191 typedef struct _mparithdef { 00192 void (*action) (); /* to do arithmetic */ 00193 void (*passive) (); /* to copy src1 in passive areas */ 00194 CARD32 *lutptr; /* in case we do a lookup */ 00195 CARD32 nlev; /* integer clipping */ 00196 CARD32 nclip; /* integer clipping */ 00197 CARD32 iconstant; 00198 RealPixel fconstant; 00199 } mpArithPvtRec, *mpArithPvtPtr; /* also used for Math */ 00200 00201 /* 00202 ** NOTE: What happens if element is run over and over with same 00203 ** parameters. If we are using a LUT, should we try to keep it? 00204 ** If KEEP_LUTS is enabled, then we build any required luts in 00205 ** the Create routine and free them in Destroy. Otherwise we do 00206 ** so in Initialize and Reset. This is more important on 00207 ** operations like divide on non-fpu machines. 00208 */ 00209 00210 #define KEEP_LUTS 00211 00212 00213 /*------------------------------------------------------------------------ 00214 ------------------------ fill in the vector --------------------------- 00215 ------------------------------------------------------------------------*/ 00216 int miAnalyzeArith(flo,ped) 00217 floDefPtr flo; 00218 peDefPtr ped; 00219 { 00220 ped->ddVec = ArithVec; 00221 return TRUE; 00222 } 00223 00224 int miAnalyzeMath(flo,ped) 00225 floDefPtr flo; 00226 peDefPtr ped; 00227 { 00228 ped->ddVec = MathVec; 00229 return TRUE; 00230 } 00231 00232 /*------------------------------------------------------------------------ 00233 ---------------------------- create peTex . . . -------------------------- 00234 ------------------------------------------------------------------------*/ 00235 static int CreateArith(flo,ped) 00236 floDefPtr flo; 00237 peDefPtr ped; 00238 { 00239 /* always force syncing between inputs (is nop if only one input) */ 00240 if (!MakePETex(flo,ped, 00241 xieValMaxBands * sizeof(mpArithPvtRec), 00242 SYNC, /* InSync: */ 00243 NO_SYNC /* bandSync: */)) 00244 return FALSE; 00245 00246 #if defined(KEEP_LUTS) 00247 if (!SetupArith(flo, ped, 0 /* modify ?? */)) 00248 return FALSE; 00249 #endif 00250 00251 return TRUE; 00252 00253 } 00254 00255 static int CreateMath(flo,ped) 00256 floDefPtr flo; 00257 peDefPtr ped; 00258 { 00259 /* always force syncing between inputs (is nop if only one input) */ 00260 if (!MakePETex(flo,ped, 00261 xieValMaxBands * sizeof(mpArithPvtRec), 00262 SYNC, /* InSync: */ 00263 NO_SYNC /* bandSync: */)) 00264 return FALSE; 00265 00266 #if defined(KEEP_LUTS) 00267 if (!SetupMath(flo, ped, 0 /* modify ?? */)) 00268 return FALSE; 00269 #endif 00270 00271 return TRUE; 00272 00273 } 00274 00275 /*------------------------------------------------------------------------ 00276 ---------------------------- initialize peTex . . . ---------------------- 00277 ------------------------------------------------------------------------*/ 00278 00279 static int InitializeArith(flo,ped) 00280 floDefPtr flo; 00281 peDefPtr ped; 00282 { 00283 xieFloArithmetic *raw = (xieFloArithmetic *) ped->elemRaw; 00284 peTexPtr pet = ped->peTex; 00285 receptorPtr rcp = pet->receptor; 00286 CARD8 msk = raw->bandMask; 00287 00288 #if !defined(KEEP_LUTS) 00289 if (!SetupArith(flo, ped, 0 /* modify ?? */)) 00290 return FALSE; 00291 #endif 00292 00293 ped->ddVec.activate = raw->src2 ? ActivateArithDROI : ActivateArithMROI; 00294 00295 /* If processing domain, allow replication */ 00296 if (raw->domainPhototag) 00297 rcp[ped->inCnt-1].band[0].replicate = msk; 00298 00299 InitReceptor(flo, ped, &rcp[SRCt1], NO_DATAMAP, 1, msk, ~msk); 00300 00301 if (raw->src2) 00302 InitReceptor(flo, ped, &rcp[SRCt2], NO_DATAMAP, 1, msk, NO_BANDS); 00303 00304 InitProcDomain(flo, ped, raw->domainPhototag, raw->domainOffsetX, 00305 raw->domainOffsetY); 00306 InitEmitter(flo, ped, NO_DATAMAP, SRCt1); 00307 00308 return !ferrCode(flo); 00309 } 00310 00311 static int InitializeMath(flo,ped) 00312 floDefPtr flo; 00313 peDefPtr ped; 00314 { 00315 xieFloMath *raw = (xieFloMath *) ped->elemRaw; 00316 peTexPtr pet = ped->peTex; 00317 receptorPtr rcp = pet->receptor; 00318 CARD8 msk = raw->bandMask; 00319 00320 #if !defined(KEEP_LUTS) 00321 if (!SetupMath(flo, ped, 0 /* modify ?? */)) 00322 return FALSE; 00323 #endif 00324 if (raw->domainPhototag) 00325 rcp[ped->inCnt-1].band[0].replicate = msk; 00326 InitReceptor(flo, ped, &rcp[SRCt1], NO_DATAMAP, 1, msk, ~msk); 00327 InitProcDomain(flo, ped, raw->domainPhototag, raw->domainOffsetX, 00328 raw->domainOffsetY); 00329 InitEmitter(flo, ped, NO_DATAMAP, SRCt1); 00330 00331 return !ferrCode(flo); 00332 } 00333 00334 /*------------------------------------------------------------------------ 00335 ----------------------------- crank some data ---------------------------- 00336 ------------------------------------------------------------------------*/ 00337 00338 static int ActivateArithMROI(flo,ped,pet) 00339 floDefPtr flo; 00340 peDefPtr ped; 00341 peTexPtr pet; 00342 { 00343 mpArithPvtPtr pvt = (mpArithPvtPtr) pet->private; 00344 int band, nbands = pet->receptor[SRCt1].inFlo->bands; 00345 bandPtr sband = &(pet->receptor[SRCt1].band[0]); 00346 bandPtr dband = &(pet->emitter[0]); 00347 00348 for(band = 0; band < nbands; band++, pvt++, sband++, dband++) { 00349 pointer svoid, dvoid; 00350 00351 if (!(pet->scheduled & 1<<band)) continue; 00352 00353 if (!(svoid = GetCurrentSrc(flo,pet,sband)) || 00354 !(dvoid = GetCurrentDst(flo,pet,dband))) continue; 00355 00356 while (!ferrCode(flo) && svoid && dvoid && 00357 SyncDomain(flo,ped,dband,FLUSH)) { 00358 INT32 run, ix = 0; 00359 00360 while (run = GetRun(flo,pet,dband)) { 00361 if (run > 0) { 00362 (*(pvt->action)) (dvoid, svoid, run, ix, pvt); 00363 ix += run; 00364 } else { 00365 if (dvoid != svoid) 00366 (*(pvt->passive)) (dvoid, svoid, -run, ix); 00367 ix -= run; 00368 } 00369 } 00370 svoid = GetNextSrc(flo,pet,sband,FLUSH); 00371 dvoid = GetNextDst(flo,pet,dband,FLUSH); 00372 } 00373 00374 FreeData(flo, pet, sband, sband->current); 00375 } 00376 return TRUE; 00377 } 00378 00379 static int ActivateArithDROI(flo,ped,pet) 00380 floDefPtr flo; 00381 peDefPtr ped; 00382 peTexPtr pet; 00383 { 00384 mpArithPvtPtr pvt = (mpArithPvtPtr) pet->private; 00385 int band, nbands = pet->receptor[SRCt1].inFlo->bands; 00386 bandPtr sband = &(pet->receptor[SRCt1].band[0]); 00387 bandPtr tband = &(pet->receptor[SRCt2].band[0]); 00388 bandPtr dband = &(pet->emitter[0]); 00389 00390 for(band = 0; band < nbands; band++, pvt++, sband++, tband++, dband++) { 00391 pointer svoid, tvoid, dvoid; 00392 CARD32 w; 00393 00394 if (!(pet->scheduled & 1<<band)) continue; 00395 00396 w = sband->format->width; 00397 if (w > tband->format->width) w = tband->format->width; 00398 00399 if (!(svoid = GetCurrentSrc(flo,pet,sband)) || 00400 !(tvoid = GetCurrentSrc(flo,pet,tband)) || 00401 !(dvoid = GetCurrentDst(flo,pet,dband))) continue; 00402 00403 while (!ferrCode(flo) && svoid && tvoid && dvoid && 00404 SyncDomain(flo,ped,dband,FLUSH)) { 00405 INT32 run, ix = 0; 00406 00407 while (run = GetRun(flo,pet,dband)) { 00408 if (run > 0) { 00409 /* needs to clip to second source, yuck */ 00410 if ((ix + run) > w) { 00411 if (ix < w) 00412 (*(pvt->action)) (dvoid,svoid,tvoid, w-ix, ix, pvt); 00413 if (dvoid != svoid) { 00414 run = sband->format->width - w; 00415 if (run > 0) 00416 (*(pvt->passive)) (dvoid, svoid, run, w); 00417 } 00418 break; 00419 } 00420 (*(pvt->action)) (dvoid, svoid, tvoid, run, ix, pvt); 00421 ix += run; 00422 } else { 00423 if (dvoid != svoid) 00424 (*(pvt->passive)) (dvoid, svoid, -run, ix); 00425 ix -= run; 00426 } 00427 } 00428 svoid = GetNextSrc(flo,pet,sband,FLUSH); 00429 tvoid = GetNextSrc(flo,pet,tband,FLUSH); 00430 dvoid = GetNextDst(flo,pet,dband,FLUSH); 00431 } 00432 00433 if(!svoid && sband->final) { 00434 DisableSrc(flo,pet,tband,FLUSH); 00435 } else if(!tvoid && tband->final) { 00436 BypassSrc(flo,pet,sband); 00437 } else { 00438 /* both inputs still active, keep the scheduler up to date */ 00439 FreeData(flo,pet,sband,sband->current); 00440 FreeData(flo,pet,tband,tband->current); 00441 } 00442 } 00443 return TRUE; 00444 } 00445 00446 /*------------------------------------------------------------------------ 00447 ------------------------ get rid of run-time stuff ----------------------- 00448 ------------------------------------------------------------------------*/ 00449 static int ResetArith(flo,ped) 00450 floDefPtr flo; 00451 peDefPtr ped; 00452 { 00453 00454 #if !defined(KEEP_LUTS) 00455 ClearArith(flo,ped); 00456 #endif 00457 00458 ResetReceptors(ped); 00459 ResetProcDomain(ped); 00460 ResetEmitter(ped); 00461 return TRUE; 00462 } 00463 00464 /*------------------------------------------------------------------------ 00465 -------------------------- get rid of this element ----------------------- 00466 ------------------------------------------------------------------------*/ 00467 static int DestroyArith(flo,ped) 00468 floDefPtr flo; 00469 peDefPtr ped; 00470 { 00471 00472 #if defined(KEEP_LUTS) 00473 ClearArith(flo,ped); 00474 #endif 00475 00476 /* get rid of the peTex structure and private structures */ 00477 ped->peTex = (peTexPtr) XieFree(ped->peTex); 00478 00479 /* zap this element's entry point vector */ 00480 ped->ddVec.create = (xieIntProc)NULL; 00481 ped->ddVec.initialize = (xieIntProc)NULL; 00482 ped->ddVec.activate = (xieIntProc)NULL; 00483 ped->ddVec.reset = (xieIntProc)NULL; 00484 ped->ddVec.destroy = (xieIntProc)NULL; 00485 00486 return TRUE; 00487 } 00488 00489 /*------------------------------------------------------------------------ 00490 --------------------- Lotsa Little Action Routines --------------------- 00491 ------------------------------------------------------------------------*/ 00492 00493 /* xieTypArithmeticOp 00494 ** 00495 ** #define xieValAdd 1 00496 ** #define xieValSub 2 00497 ** #define xieValSubRev 3 00498 ** #define xieValMul 4 00499 ** #define xieValDiv 5 00500 ** #define xieValDivRev 6 00501 ** #define xieValMin 7 00502 ** #define xieValMax 8 00503 ** #define xieValGamma 9 00504 ** 00505 ** xieTypMathOp 00506 ** 00507 ** #define xieValExp 1 00508 ** #define xieValLn 2 00509 ** #define xieValLog2 3 00510 ** #define xieValLog10 4 00511 ** #define xieValSquare 5 00512 ** #define xieValSqrt 6 00513 */ 00514 00515 #define NADA 0 00516 00517 #define AADD D = S1 + S2; if (D >= nlev) D = nlev - 1; 00518 #define ASUB D = (S1 > S2) ? S1 - S2 : 0; 00519 #define ASUBREV D = (S2 > S1) ? S2 - S1 : 0; 00520 #define AMIN D = S1 < S2 ? S1 : S2; 00521 #define AMAX D = S1 > S2 ? S1 : S2; 00522 00523 00524 #define FADD D = S1 + S2; 00525 #define FSUB D = S1 - S2; 00526 #define FSUBREV D = S2 - S1; 00527 #define FMUL D = S1 * S2; 00528 #define FDIV D = S1 / S2; 00529 #define FDIVREV D = S1 ? S2 / S1 : S2; 00530 #define FMIN D = S1 < S2 ? S1 : S2; 00531 #define FMAX D = S1 > S2 ? S1 : S2; 00532 /* beware float vs double */ 00533 /* consider using fpow() if available */ 00534 #define FGAM D = pow(S1,S2); 00535 #define IFGAM D = (nlev - 1) * pow(S1/(nlev-1),S2); 00536 00537 #define BADD D = S1 | S2; 00538 #define BSUB D = S1 & ~S2; 00539 #define BSUBREV D = S2 & ~S1; 00540 #define BMUL D = S1 & S2; 00541 #define BDIV D = S1; 00542 #define BDIVREV D = S2; 00543 #define BMIN D = S1 & S2; /* same as BMUL */ 00544 #define BMAX D = S1 | S2; /* same as BADD */ 00545 #define BGAM D = S1; 00546 00547 00548 /*------------------------------------------------------------------------ 00549 --------------------- ROI operations work on subranges ------------------ 00550 ------------------------------------------------------------------------*/ 00551 00552 /* MROI: (*(pvt->action)) (dvoid, src1, run, ix, pvt); */ 00553 /* DROI: (*(pvt->action)) (dvoid, src1, src2, run, ix, pvt); */ 00554 00555 #define MakeLutI(name1, expr) \ 00556 static void name1(pvt) \ 00557 mpArithPvtPtr pvt; \ 00558 { \ 00559 CARD32 *lut = pvt->lutptr; \ 00560 CARD32 nlev = pvt->nlev; \ 00561 CARD32 nclip = pvt->nclip; \ 00562 CARD32 i; \ 00563 CARD32 D, S1, S2 = pvt->iconstant; \ 00564 for ( i = 0; i < nlev ; i++) { \ 00565 S1 = i; \ 00566 expr; \ 00567 lut[i] = D; \ 00568 } \ 00569 for ( ; i < nclip ; i++) { \ 00570 lut[i] = 0; \ 00571 } \ 00572 } 00573 00574 #define MakeLutF2(name1, expr) \ 00575 static void name1(pvt) \ 00576 mpArithPvtPtr pvt; \ 00577 { \ 00578 CARD32 *lut = pvt->lutptr; \ 00579 CARD32 nlev = pvt->nlev; \ 00580 CARD32 nclip = pvt->nclip; \ 00581 RealPixel Half = (RealPixel) .5; \ 00582 RealPixel dlev = (RealPixel) nlev - Half; \ 00583 RealPixel D, S1, S2 = pvt->fconstant; \ 00584 CARD32 i; \ 00585 for ( i = 0; i < nlev ; i++) { \ 00586 S1 = i; \ 00587 expr; \ 00588 D += .5; \ 00589 if (D < 0.) D = 0; \ 00590 else if (D > dlev) D = dlev; \ 00591 lut[i] = D; \ 00592 } \ 00593 for ( ; i < nclip ; i++) { \ 00594 lut[i] = 0; \ 00595 } \ 00596 } 00597 00598 #define MakeLutF1(name1, expr) \ 00599 static void name1(pvt) \ 00600 mpArithPvtPtr pvt; \ 00601 { \ 00602 CARD32 *lut = pvt->lutptr; \ 00603 CARD32 nlev = pvt->nlev; \ 00604 CARD32 nclip = pvt->nclip; \ 00605 RealPixel Half = (RealPixel) .5; \ 00606 RealPixel dlev = (RealPixel) nlev - Half; \ 00607 RealPixel D, S1; \ 00608 CARD32 i; \ 00609 for ( i = 0; i < nlev ; i++) { \ 00610 S1 = i; \ 00611 expr; \ 00612 D += .5; \ 00613 if (D < 0.) D = 0; \ 00614 else if (D > dlev) D = dlev; \ 00615 lut[i] = D; \ 00616 } \ 00617 for ( ; i < nclip ; i++) { \ 00618 lut[i] = 0; \ 00619 } \ 00620 } 00621 00622 #define MakeLook(name1, itype) \ 00623 static void name1(dst1,src1,nx,x,pvt) \ 00624 pointer dst1, src1; \ 00625 CARD32 nx, x; \ 00626 mpArithPvtPtr pvt; \ 00627 { \ 00628 itype *dst = ((itype *) dst1) + x; \ 00629 itype *src = ((itype *) src1) + x; \ 00630 CARD32 *lut = pvt->lutptr; \ 00631 CARD32 nmask = pvt->nclip - 1; \ 00632 for ( ; nx > 0 ; nx--) { \ 00633 *dst++ = lut[*src++ & nmask]; \ 00634 } \ 00635 } 00636 00637 MakeLutI(pr_a, AADD ) 00638 MakeLutI(pr_s, ASUB ) 00639 MakeLutI(pr_sr, ASUBREV ) 00640 MakeLutI(pr_mn, AMIN ) 00641 MakeLutI(pr_mx, AMAX ) 00642 00643 MakeLutF2(pr_m, FMUL ) 00644 MakeLutF2(pr_d, FDIV ) 00645 MakeLutF2(pr_dr, FDIVREV ) 00646 MakeLutF2(pr_gm, IFGAM ) 00647 00648 static void (*prep_mono[xieValGamma])() = { 00649 pr_a, pr_s, pr_sr, pr_m, pr_d, pr_dr, pr_mn, pr_mx, pr_gm 00650 }; 00651 00652 MakeLook(lr_B, BytePixel) 00653 MakeLook(lr_P, PairPixel) 00654 MakeLook(lr_Q, QuadPixel) 00655 00656 static void (*action_lut[5])() = { 00657 NADA, 00658 NADA, 00659 lr_B, 00660 lr_P, 00661 lr_Q 00662 }; 00663 00664 00665 00666 /* 00667 ** NOTE: 00668 ** The MakePixI and MakePixF? macros may be used to synthesize monadic 00669 ** action routines which can be used in place of look up table based 00670 ** routines. They were actually tested at one point in time. The 00671 ** invocations still remain below, and the routines can be plugged 00672 ** into the action_monoROI[itype][operator] table below. As noted 00673 ** elsewhere, these routines might be more appropriate for bigger 00674 ** pixels to avoid lookup table explosion; or for machines without 00675 ** a data cache, or a very small data cache. IN summary, which 00676 ** of these routines should be used depends on: 00677 ** a) existence of data cache? 00678 ** b) size, organization, and fill method of data cache? 00679 ** c) speed of floating operations 00680 */ 00681 00682 #define MakePixI(name1, itype, expr) \ 00683 static void name1(dst1,src1,nx,x,pvt) \ 00684 pointer dst1, src1; \ 00685 CARD32 nx, x; \ 00686 mpArithPvtPtr pvt; \ 00687 { \ 00688 itype *dst = (itype *) dst1; \ 00689 itype *src = (itype *) src1; \ 00690 CARD32 nlev = pvt->nlev; \ 00691 CARD32 D, S1, S2 = (itype) pvt->iconstant; \ 00692 for ( ; nx > 0 ; nx--, x++) { \ 00693 S1 = src[x]; \ 00694 expr \ 00695 dst[x] = D; \ 00696 } \ 00697 } 00698 00699 #define MakePixF2(name1, itype, expr) \ 00700 static void name1(dst1,src1,nx,x,pvt) \ 00701 pointer dst1, src1; \ 00702 CARD32 nx, x; \ 00703 mpArithPvtPtr pvt; \ 00704 { \ 00705 itype *dst = (itype *) dst1; \ 00706 itype *src = (itype *) src1; \ 00707 RealPixel Half = (RealPixel) .5; \ 00708 RealPixel dlev = (RealPixel) pvt->nlev - Half; \ 00709 RealPixel D, S1, S2 = (itype) pvt->fconstant; \ 00710 for ( ; nx > 0 ; nx--, x++) { \ 00711 S1 = (RealPixel) src[x]; \ 00712 expr \ 00713 D += Half; \ 00714 if (D < 0.) D = 0; \ 00715 else if (D > dlev) D = dlev; \ 00716 dst[x] = (itype) D; \ 00717 } \ 00718 } 00719 00720 #define MakePixF1(name1, itype, expr) \ 00721 static void name1(dst1,src1,nx,x,pvt) \ 00722 pointer dst1, src1; \ 00723 CARD32 nx, x; \ 00724 mpArithPvtPtr pvt; \ 00725 { \ 00726 itype *dst = (itype *) dst1; \ 00727 itype *src = (itype *) src1; \ 00728 RealPixel Half = (RealPixel) .5; \ 00729 RealPixel dlev = (RealPixel) pvt->nlev - Half; \ 00730 RealPixel D, S1; \ 00731 for ( ; nx > 0 ; nx--, x++) { \ 00732 S1 = (RealPixel) src[x]; \ 00733 expr \ 00734 D += Half; \ 00735 if (D < 0.) D = 0; \ 00736 else if (D > dlev) D = dlev; \ 00737 dst[x] = (itype) D; \ 00738 } \ 00739 } 00740 00741 #define DakePix(name2, itype, expr) \ 00742 static void name2(dst1,src1,src2,nx,x,pvt) \ 00743 pointer dst1, src1, src2; \ 00744 CARD32 nx, x; \ 00745 mpArithPvtPtr pvt; \ 00746 { \ 00747 itype *dst = ((itype *) dst1) + x; \ 00748 itype *src = ((itype *) src1) + x; \ 00749 itype *trc = ((itype *) src2) + x; \ 00750 CARD32 nlev = pvt->nlev; \ 00751 CARD32 D, S1, S2; \ 00752 for ( ; nx > 0 ; nx--) { \ 00753 S1 = *src++; \ 00754 S2 = *trc++; \ 00755 expr \ 00756 *dst++ = D; \ 00757 } \ 00758 } 00759 00760 #define MakeFlt2(name1, expr) \ 00761 static void name1(dst1,src1,nx,x,pvt) \ 00762 pointer dst1, src1; \ 00763 CARD32 nx, x; \ 00764 mpArithPvtPtr pvt; \ 00765 { \ 00766 RealPixel *dst = ((RealPixel *) dst1) + x; \ 00767 RealPixel *src = ((RealPixel *) src1) + x; \ 00768 RealPixel D, S1, S2 = pvt->fconstant; \ 00769 for ( ; nx > 0 ; nx--) { \ 00770 S1 = *src++; \ 00771 expr \ 00772 *dst++ = D; \ 00773 } \ 00774 } 00775 00776 #define MakeFlt1(name1, expr) \ 00777 static void name1(dst1,src1,nx,x,pvt) \ 00778 pointer dst1, src1; \ 00779 CARD32 nx, x; \ 00780 mpArithPvtPtr pvt; \ 00781 { \ 00782 RealPixel *dst = ((RealPixel *) dst1) + x; \ 00783 RealPixel *src = ((RealPixel *) src1) + x; \ 00784 RealPixel D, S1; \ 00785 for ( ; nx > 0 ; nx--) { \ 00786 S1 = *src++; \ 00787 expr \ 00788 *dst++ = D; \ 00789 } \ 00790 } 00791 00792 #define DakeFlt(name2, expr) \ 00793 static void name2(dst1,src1,src2,nx,x,pvt) \ 00794 pointer dst1, src1, src2; \ 00795 CARD32 nx, x; \ 00796 mpArithPvtPtr pvt; \ 00797 { \ 00798 RealPixel *dst = ((RealPixel *) dst1) + x; \ 00799 RealPixel *src = ((RealPixel *) src1) + x; \ 00800 RealPixel *trc = ((RealPixel *) src2) + x; \ 00801 RealPixel D, S1, S2; \ 00802 for ( ; nx > 0 ; nx--) { \ 00803 S1 = *src++; \ 00804 S2 = *trc++; \ 00805 expr \ 00806 *dst++ = D; \ 00807 } \ 00808 } 00809 00810 /* Bits no longer required by protocol */ 00811 #define mr_b_a NADA 00812 #define mr_b_s NADA 00813 #define mr_b_sr NADA 00814 #define mr_b_m NADA 00815 #define mr_b_d NADA 00816 #define mr_b_dr NADA 00817 #define mr_b_mn NADA 00818 #define mr_b_mx NADA 00819 #define mr_b_gm NADA 00820 00821 #define dr_b_a NADA 00822 #define dr_b_s NADA 00823 #define dr_b_sr NADA 00824 #define dr_b_mn NADA 00825 #define dr_b_mx NADA 00826 00827 /* MakePixI (mr_B_a, BytePixel, AADD ) */ 00828 /* MakePixI (mr_B_s, BytePixel, ASUB ) */ 00829 /* MakePixI (mr_B_sr, BytePixel, ASUBREV ) */ 00830 /* MakePixI (mr_B_mn, BytePixel, AMIN ) */ 00831 /* MakePixI (mr_B_mx, BytePixel, AMAX ) */ 00832 00833 /* MakePixF2 (mr_B_m, BytePixel, FMUL ) */ 00834 /* MakePixF2 (mr_B_d, BytePixel, FDIV ) */ 00835 /* MakePixF2 (mr_B_dr, BytePixel, FDIVREV ) */ 00836 /* MakePixF2 (mr_B_gm, BytePixel, IFGAM ) */ 00837 00838 DakePix (dr_B_a, BytePixel, AADD ) 00839 DakePix (dr_B_s, BytePixel, ASUB ) 00840 DakePix (dr_B_sr, BytePixel, ASUBREV ) 00841 DakePix (dr_B_mn, BytePixel, AMIN ) 00842 DakePix (dr_B_mx, BytePixel, AMAX ) 00843 00844 /* MakePixI (mr_P_a, PairPixel, AADD ) */ 00845 /* MakePixI (mr_P_s, PairPixel, ASUB ) */ 00846 /* MakePixI (mr_P_sr, PairPixel, ASUBREV ) */ 00847 /* MakePixI (mr_P_mn, PairPixel, AMIN ) */ 00848 /* MakePixI (mr_P_mx, PairPixel, AMAX ) */ 00849 00850 /* MakePixF2 (mr_P_m, PairPixel, FMUL ) */ 00851 /* MakePixF2 (mr_P_d, PairPixel, FDIV ) */ 00852 /* MakePixF2 (mr_P_dr, PairPixel, FDIVREV ) */ 00853 /* MakePixF2 (mr_P_gm, PairPixel, IFGAM ) */ 00854 00855 DakePix (dr_P_a, PairPixel, AADD ) 00856 DakePix (dr_P_s, PairPixel, ASUB ) 00857 DakePix (dr_P_sr, PairPixel, ASUBREV ) 00858 DakePix (dr_P_mn, PairPixel, AMIN ) 00859 DakePix (dr_P_mx, PairPixel, AMAX ) 00860 00861 /* MakePixI (mr_Q_a, QuadPixel, AADD ) */ 00862 /* MakePixI (mr_Q_s, QuadPixel, ASUB ) */ 00863 /* MakePixI (mr_Q_sr, QuadPixel, ASUBREV ) */ 00864 /* MakePixI (mr_Q_mn, QuadPixel, AMIN ) */ 00865 /* MakePixI (mr_Q_mx, QuadPixel, AMAX ) */ 00866 00867 /* MakePixF2 (mr_Q_m, QuadPixel, FMUL ) */ 00868 /* MakePixF2 (mr_Q_d, QuadPixel, FDIV ) */ 00869 /* MakePixF2 (mr_Q_dr, QuadPixel, FDIVREV ) */ 00870 /* MakePixF2 (mr_Q_gm, QuadPixel, IFGAM ) */ 00871 00872 DakePix (dr_Q_a, QuadPixel, AADD ) 00873 DakePix (dr_Q_s, QuadPixel, ASUB ) 00874 DakePix (dr_Q_sr, QuadPixel, ASUBREV ) 00875 DakePix (dr_Q_mn, QuadPixel, AMIN ) 00876 DakePix (dr_Q_mx, QuadPixel, AMAX ) 00877 00878 MakeFlt2 (mr_R_a, FADD ) 00879 MakeFlt2 (mr_R_s, FSUB ) 00880 MakeFlt2 (mr_R_sr, FSUBREV ) 00881 MakeFlt2 (mr_R_m, FMUL ) 00882 MakeFlt2 (mr_R_d, FDIV ) 00883 MakeFlt2 (mr_R_dr, FDIVREV ) 00884 MakeFlt2 (mr_R_mn, FMIN ) 00885 MakeFlt2 (mr_R_mx, FMAX ) 00886 MakeFlt2 (mr_R_gm, FGAM ) 00887 00888 DakeFlt (dr_R_a, FADD ) 00889 DakeFlt (dr_R_s, FSUB ) 00890 DakeFlt (dr_R_sr, FSUBREV ) 00891 DakeFlt (dr_R_mn, FMIN ) 00892 DakeFlt (dr_R_mx, FMAX ) 00893 00894 /* 00895 ADD, SUB, SUBREV, MUL, DIV, DIVREV, MIN, MAX, GAMMA 00896 */ 00897 00898 static void (*action_monoROI[5][xieValGamma])() = { 00899 mr_R_a, mr_R_s, mr_R_sr, mr_R_m, mr_R_d, mr_R_dr, mr_R_mn, mr_R_mx, mr_R_gm, 00900 mr_b_a, mr_b_s, mr_b_sr, mr_b_m, mr_b_d, mr_b_dr, mr_b_mn, mr_b_mx, mr_b_gm, 00901 NADA, NADA, NADA, NADA, NADA, NADA, NADA, NADA, NADA, 00902 NADA, NADA, NADA, NADA, NADA, NADA, NADA, NADA, NADA, 00903 NADA, NADA, NADA, NADA, NADA, NADA, NADA, NADA, NADA 00904 }; 00905 00906 static void (*action_dyadROI[5][xieValGamma])() = { 00907 dr_R_a, dr_R_s, dr_R_sr, NADA, NADA, NADA, dr_R_mn, dr_R_mx, NADA, 00908 dr_b_a, dr_b_s, dr_b_sr, NADA, NADA, NADA, dr_b_mn, dr_b_mx, NADA, 00909 dr_B_a, dr_B_s, dr_B_sr, NADA, NADA, NADA, dr_B_mn, dr_B_mx, NADA, 00910 dr_P_a, dr_P_s, dr_P_sr, NADA, NADA, NADA, dr_P_mn, dr_P_mx, NADA, 00911 dr_Q_a, dr_Q_s, dr_Q_sr, NADA, NADA, NADA, dr_Q_mn, dr_Q_mx, NADA 00912 }; 00913 00914 00915 extern void (*passive_copy[5])(); 00916 00917 /*------------------------------------------------------------------------ 00918 -------------------------- . . . Math Sandbox . . . ---------------------- 00919 ------------------------------------------------------------------------*/ 00920 00921 /* 00922 ** Math NOTES: 00923 ** #define xieValExp 1 00924 ** #define xieValLn 2 00925 ** #define xieValLog2 3 00926 ** #define xieValLog10 4 00927 ** #define xieValSquare 5 00928 ** #define xieValSqrt 6 00929 ** 00930 ** log(==0) is -infinity with divide by zero exception. sigh. 00931 ** log( <0) is quiet NaN with invalid operation exception, sigh. 00932 ** sqrt(<0) might be error, 0., or -sqrt(-x) ??? 00933 ** 00934 ** for log2(), it may be quicker to count bits for integer arguments :-) 00935 ** 00936 ** also, not all machines have a log2 and log10 in their math library 00937 ** so we multiply log() by the magic values M_LOG2E and M_LOG10E. 00938 ** 00939 ** one can argue that taking logs and exponents and such of small 00940 ** integers is a somewhat frenetic exercise. while it might make 00941 ** sense to use square or squareroot as an image contrast enhancer, 00942 ** it doesn't make sense when applied to small integers either. 00943 ** 00944 ** just for the heck of it, here are some values for small inputs: 00945 ** i log2 logN log10 exp sqrt square 00946 ** 0 -Inf -Inf -Inf 1 0 0 00947 ** 1 0 0 0 2.718 1 1 00948 ** 2 1 0.6931 0.301 7.389 1.414 4 00949 ** 3 1.585 1.099 0.4771 20.09 1.732 9 00950 ** 4 2 1.386 0.6021 54.6 2 16 00951 ** 5 2.322 1.609 0.699 148.4 2.236 25 00952 ** 00953 ** also note that LN_MAXFLOAT (or LN_MAXDOUBLE) and MAXFLOAT are 00954 ** typically defined in values.h, but including it conflicts with 00955 ** misc.h on many machines. values.h isn't a very modern .h file 00956 ** as standards go these days. help..... 00957 */ 00958 00959 #ifndef M_LOG2E 00960 #define M_LOG2E 1.4426950408889634074 00961 #endif 00962 00963 #ifndef M_LOG10E 00964 #define M_LOG10E 0.43429448190325182765 00965 #endif 00966 00967 #ifndef LN_MAXFLOAT 00968 #define LN_MAXFLOAT 88.7228394 00969 #endif 00970 00971 #ifndef MAXFLOAT 00972 #define MAXFLOAT ((float)3.40282346638528860e+38) 00973 #endif 00974 00975 #define BANY D = S1; 00976 #define FEXP D = (S1 <= (LN_MAXFLOAT-2.) ? exp(S1) : MAXFLOAT); 00977 #define FLGN D = (S1 > 0. ? log(S1) : 0. ); 00978 #define FLG2 D = (S1 > 0. ? log(S1) * M_LOG2E : 0. ); 00979 #define FLG10 D = (S1 > 0. ? log(S1) * M_LOG10E : 0. ); 00980 #define FSQR D = S1 * S1; 00981 #define FSQRT D = (S1 >= 0. ? sqrt(S1) : 0. ); 00982 00983 MakeLutF1(mpr_exp, FEXP ) 00984 MakeLutF1(mpr_lgN, FLGN ) 00985 MakeLutF1(mpr_lg2, FLG2 ) 00986 MakeLutF1(mpr_lg10, FLG10) 00987 MakeLutF1(mpr_sqr, FSQR ) 00988 MakeLutF1(mpr_sqrt, FSQRT) 00989 00990 00991 /* Bits no longer required by protocol */ 00992 #define m_b_exp NADA 00993 #define m_b_lgN NADA 00994 #define m_b_lg2 NADA 00995 #define m_b_lg10 NADA 00996 #define m_b_sqr NADA 00997 #define m_b_sqrt NADA 00998 00999 MakePixF1 (m_P_sqr, PairPixel, FSQR) /* ??? or use LUT */ 01000 MakePixF1 (m_Q_sqr, QuadPixel, FSQR) 01001 01002 MakeFlt1 (m_R_exp, FEXP ) 01003 MakeFlt1 (m_R_lgN, FLGN ) 01004 MakeFlt1 (m_R_lg2, FLG2 ) 01005 MakeFlt1 (m_R_lg10, FLG10 ) 01006 MakeFlt1 (m_R_sqr, FSQR ) 01007 MakeFlt1 (m_R_sqrt, FSQRT ) 01008 01009 static void (*action_mathROI[5][xieValSqrt])() = { 01010 /* EXP, LOG, LOG2, LOG10, SQUARE, SQRT */ 01011 m_R_exp, m_R_lgN, m_R_lg2, m_R_lg10, m_R_sqr, m_R_sqrt, /* floats */ 01012 m_b_exp, m_b_lgN, m_b_lg2, m_b_lg10, m_b_sqr, m_b_sqrt, /* bits */ 01013 NADA, NADA, NADA, NADA, NADA, NADA, /* bytes */ 01014 NADA, NADA, NADA, NADA, m_P_sqr, NADA, /* pairs */ 01015 NADA, NADA, NADA, NADA, m_Q_sqr, NADA /* quads */ 01016 /* EXP, LOG, LOG2, LOG10, SQUARE, SQRT */ 01017 }; 01018 01019 static void (*prep_math[xieValSqrt])() = { 01020 mpr_exp, mpr_lgN, mpr_lg2, mpr_lg10, mpr_sqr, mpr_sqrt 01021 }; 01022 01023 /*------------------------------------------------------------------------ 01024 -------------------------- initialize element . . . ---------------------- 01025 ------------------------------------------------------------------------*/ 01026 01027 static int SetupArith(flo,ped,modify) 01028 floDefPtr flo; 01029 peDefPtr ped; 01030 int modify; 01031 { 01032 xieFloArithmetic *raw = (xieFloArithmetic *) ped->elemRaw; 01033 peTexPtr pet = ped->peTex; 01034 pArithDefPtr epvt = (pArithDefPtr) ped->elemPvt; 01035 mpArithPvtPtr pvt = (mpArithPvtPtr) pet->private; 01036 receptorPtr rcp = pet->receptor; 01037 CARD32 nbands = rcp[SRCt1].inFlo->bands; 01038 bandPtr sband = &(rcp[SRCt1].band[0]); 01039 bandPtr tband = &(rcp[SRCt2].band[0]); 01040 bandPtr dband = &(pet->emitter[0]); 01041 CARD32 band; 01042 01043 for (band=0; band<nbands; band++, pvt++, sband++, tband++, dband++) { 01044 CARD32 iclass = IndexClass(sband->format->class); 01045 void (*act)() = 0; 01046 01047 if ((raw->bandMask & (1<<band)) == 0) 01048 continue; 01049 01050 if (!raw->src2) /* only used for mul, div, divrev, gamma */ 01051 pvt->fconstant = (RealPixel) epvt->constant[band]; 01052 01053 switch(raw->operator) { 01054 case xieValDiv: if (pvt->fconstant == 0.0) /* epsilon ?? */ 01055 pvt->fconstant = 1.0; 01056 break; 01057 } 01058 01059 if (IsConstrained(sband->format->class)) { 01060 pvt->nlev = sband->format->levels; 01061 if (!raw->src2) { 01062 CARD32 deep; 01063 SetDepthFromLevels(pvt->nlev,deep); pvt->nclip = 1 << deep; 01064 /* only used for add, sub, subrev, min, max */ 01065 pvt->iconstant = ConstrainConst(epvt->constant[band],pvt->nlev); 01066 } 01067 } 01068 01069 /* Try to find a dyadic operator */ 01070 if (!act && raw->src2) 01071 act = action_dyadROI[iclass][raw->operator-1]; 01072 01073 /* 01074 ** NOTE: 01075 ** For larger pixels a look up table begins to be less 01076 ** attractive since the malloc is larger, it takes longer 01077 ** to compute, and the cache hit rate may go down. So 01078 ** we may want to add more actual monodaic arithmetic 01079 ** elements to the table (see MakePixel, it worked once 01080 ** upon a time) and choose between an arithmetic and lookup 01081 ** version based on number of levels. 01082 */ 01083 01084 /* Try to find a monadic operator */ 01085 if (!act && !raw->src2) 01086 act = action_monoROI[iclass][raw->operator-1]; 01087 01088 /* Or maybe a monadic look up table op */ 01089 if (!act && !raw->src2) { 01090 act = action_lut[iclass]; 01091 if (act) { 01092 /* Allocate Lut and Fill it in */ 01093 if (!(pvt->lutptr = (CARD32 *) 01094 XieMalloc(pvt->nclip * sizeof(CARD32)))) 01095 AllocError(flo,ped,return(FALSE)); 01096 (*prep_mono[raw->operator-1]) (pvt); 01097 } 01098 } 01099 01100 if (!act) 01101 ImplementationError(flo,ped,return(FALSE)); 01102 pvt->action = act; 01103 pvt->passive = passive_copy[iclass]; 01104 } 01105 return TRUE; 01106 } 01107 01108 static int SetupMath(flo,ped,modify) 01109 floDefPtr flo; 01110 peDefPtr ped; 01111 int modify; 01112 { 01113 xieFloMath *raw = (xieFloMath *) ped->elemRaw; 01114 peTexPtr pet = ped->peTex; 01115 mpArithPvtPtr pvt = (mpArithPvtPtr) pet->private; 01116 receptorPtr rcp = pet->receptor; 01117 CARD32 nbands = rcp[SRCt1].inFlo->bands; 01118 bandPtr sband = &(rcp[SRCt1].band[0]); 01119 bandPtr dband = &(pet->emitter[0]); 01120 CARD32 band; 01121 01122 for (band=0; band<nbands; band++, pvt++, sband++, dband++) { 01123 CARD32 iclass = IndexClass(sband->format->class); 01124 void (*act)() = 0; 01125 01126 if ((raw->bandMask & (1<<band)) == 0) 01127 continue; 01128 01129 if (IsConstrained(sband->format->class)) { 01130 CARD32 deep; 01131 pvt->nlev = sband->format->levels; 01132 SetDepthFromLevels(pvt->nlev,deep); pvt->nclip = 1 << deep; 01133 } 01134 01135 /* 01136 ** NOTE: 01137 ** For larger sized pixels, a lookup table my be counter 01138 ** productive. In addition to the malloc space (eg 64k 01139 ** words), and the low cache hit rate, the time to fill the 01140 ** lookup table can become significant. Even for medium 01141 ** sized pixels, some sort of hashed cache might be a 01142 ** better solution. But I seriously doubt anyone will 01143 ** use these operations on integer pixels very much ... 01144 */ 01145 01146 /* Try to find a monadic operator */ 01147 if (!act) 01148 act = action_mathROI[iclass][raw->operator-1]; 01149 01150 /* Or maybe a monadic look up table operator */ 01151 if (!act) { 01152 act = action_lut[iclass]; 01153 if (act) { 01154 /* Allocate Lut and Fill it in */ 01155 if (!(pvt->lutptr = (CARD32 *) 01156 XieMalloc(pvt->nclip * sizeof(CARD32)))) 01157 AllocError(flo,ped,return(FALSE)); 01158 (*prep_math[raw->operator-1]) (pvt); 01159 } 01160 } 01161 if (!act) 01162 ImplementationError(flo,ped,return(FALSE)); 01163 01164 pvt->action = act; 01165 pvt->passive = passive_copy[iclass]; 01166 } 01167 return TRUE; 01168 } 01169 01170 static void ClearArith(flo,ped) 01171 floDefPtr flo; 01172 peDefPtr ped; 01173 { 01174 mpArithPvtPtr pvt = (mpArithPvtPtr) (ped->peTex->private); 01175 int band; 01176 01177 /* free any dynamic private data */ 01178 if (pvt) 01179 for (band = 0 ; band < xieValMaxBands ; band++, pvt++) 01180 if (pvt->lutptr) 01181 pvt->lutptr = (CARD32 *) XieFree(pvt->lutptr); 01182 01183 } 01184 01185 /* end module mparith.c */

Generated on Mon May 10 23:29:24 2004 for XFree86 by doxygen 1.3.7