Max 5 API Reference
00001 00002 float _c2ftab[256]; 00003 double _c2dtab[256]; 00004 00005 // conversion/casting macros 00006 #define FM_CONVFN_NONE(x) (x) 00007 #define FM_CONVFN_CHAR(x) ((uchar)(x)) 00008 #define FM_CONVFN_LONG(x) ((long)(x)) 00009 #define FM_CONVFN_FLOAT(x) ((float)(x)) 00010 #define FM_CONVFN_DOUBLE(x) ((double)(x)) 00011 #define FM_CONVFN_CHARFIXTOCHAR(x) ((uchar)FixedToInt(x)) 00012 #define FM_CONVFN_CHARFIXTOLONG(x) ((long)FixedToInt(x)) 00013 #define FM_CONVFN_CHARFIXTOFLOAT(x) (FixedToFloat(x)*(1.f/255.f)) 00014 #define FM_CONVFN_CHARFIXTODOUBLE(x) (FixedToDouble(x)*(1./255.)) 00015 #define FM_CONVFN_CHARTOFLOAT(x) (_c2ftab[(long)(x)]) 00016 #define FM_CONVFN_CHARTODOUBLE(x) (_c2dtab[(long)(x)]) 00017 #define FM_CONVFN_LONGTOCHAR(x) ((uchar)(x)) //clamp? 00018 #define FM_CONVFN_FLOATTOCHAR(x) ((uchar)((((x)>1.f)?1.f:(((x)<0.f)?0.f:(x)))*255.f)) 00019 #define FM_CONVFN_DOUBLETOCHAR(x) ((uchar)((((x)>1.)?1.:(((x)<0.)?0.:(x)))*255.)) 00020 00021 // int/fraction/mult macros 00022 #define FM_INTFN_DOUBLE(v) ((long)(v)) 00023 #define FM_INTFN_FIXED(v) (FixedToInt(v)) 00024 00025 #define FM_FRAKFN_DOUBLE(v,w) ((v)-(double)(w)) 00026 #define FM_FRAKFN_FIXED(v,w) (FixedFraction(v)) 00027 00028 #define FM_NEGFRAKFN_DOUBLE(v) (-(v)) 00029 #define FM_NEGFRAKFN_FIXED(v) (fixed1-(v)) 00030 00031 #define FM_INVFRAKFN_DOUBLE(v) (1.-(v)) 00032 #define FM_INVFRAKFN_FIXED(v) (fixed1-(v)) 00033 00034 #define FM_MULFN_DOUBLE(v,w) ((double)(v)*(double)(w)) 00035 #define FM_MULFN_FIXED(v,w) (FixMul((v),(w))) 00036 #define FM_MULFN_LONG(v,w) ((long)(v)*(long)(w)) 00037 00038 // common setup code 00039 #define FM_PREAMBLE() \ 00040 long i,j,k; \ 00041 long planemap[JIT_MATRIX_MAX_PLANECOUNT]; \ 00042 long planecount,dst_height,dst_width,src_height,src_width; \ 00043 long dst_dimsize,src_dimsize,dst_rowstride,src_rowstride,dst_cellstride,src_cellstride; \ 00044 long dst_typesize,src_typesize,poff; \ 00045 long xmin,xmax,ymin,ymax,xdir,ydir; \ 00046 double dxinc=0,dyinc=0; \ 00047 long bigmatrix = FALSE; \ 00048 long interp = FALSE; \ 00049 long unity = FALSE; \ 00050 \ 00051 planecount = dst_minfo->planecount; \ 00052 dst_width = dst_minfo->dim[0]; \ 00053 dst_height = dst_minfo->dim[1]; \ 00054 src_width = src_minfo->dim[0]; \ 00055 src_height = src_minfo->dim[1]; \ 00056 dst_rowstride = dst_minfo->dimstride[1]; \ 00057 src_rowstride = src_minfo->dimstride[1]; \ 00058 dst_typesize = jit_matrix_info_typesize(dst_minfo); \ 00059 src_typesize = jit_matrix_info_typesize(src_minfo); \ 00060 dst_cellstride = dst_minfo->dimstride[0] / dst_typesize; \ 00061 src_cellstride = src_minfo->dimstride[0] / src_typesize; \ 00062 \ 00063 if (mcinfo) { \ 00064 if (mcinfo->flags&JIT_MATRIX_CONVERT_DSTDIM) { \ 00065 dst_width = ABS(mcinfo->dstdimend[0] - mcinfo->dstdimstart[0]) + 1; \ 00066 dst_height = ABS(mcinfo->dstdimend[1] - mcinfo->dstdimstart[1]) + 1; \ 00067 dst_bp += (dst_minfo->dimstride[0]*MIN(mcinfo->dstdimstart[0],mcinfo->dstdimend[0])); \ 00068 dst_bp += (dst_minfo->dimstride[1]*MIN(mcinfo->dstdimstart[1],mcinfo->dstdimend[1])); \ 00069 } \ 00070 if (mcinfo->flags&JIT_MATRIX_CONVERT_SRCDIM) { \ 00071 src_width = (mcinfo->srcdimend[0] - mcinfo->srcdimstart[0]); \ 00072 if (src_width>=0) src_width++; else src_width--; \ 00073 src_height = (mcinfo->srcdimend[1] - mcinfo->srcdimstart[1]); \ 00074 if (src_height>=0) src_height++; else src_height--; \ 00075 src_bp += (src_minfo->dimstride[0]*mcinfo->srcdimstart[0]); \ 00076 src_bp += (src_minfo->dimstride[1]*mcinfo->srcdimstart[1]); \ 00077 } \ 00078 for (i=0;i<planecount;i++) { \ 00079 if (mcinfo->planemap[i]>=0) \ 00080 planemap[i] = mcinfo->planemap[i] % src_minfo->planecount; \ 00081 else \ 00082 planemap[i] = -1; \ 00083 } \ 00084 } else { \ 00085 for (i=0;i<planecount;i++) { \ 00086 planemap[i] = i % src_minfo->planecount; \ 00087 } \ 00088 } \ 00089 \ 00090 if ((src_width>JIT_MATRIX_BIGMATRIX) || \ 00091 (src_height>JIT_MATRIX_BIGMATRIX) || \ 00092 (dst_width>JIT_MATRIX_BIGMATRIX) || \ 00093 (dst_height>JIT_MATRIX_BIGMATRIX)) \ 00094 { \ 00095 bigmatrix = TRUE; \ 00096 } \ 00097 \ 00098 if (mcinfo&&(mcinfo->flags&JIT_MATRIX_CONVERT_INTERP)) \ 00099 interp = TRUE; \ 00100 \ 00101 if (interp) { \ 00102 if ((ABS(src_width)>1)&&(ABS(dst_width)>1)) \ 00103 dxinc = ((double)src_width-DIRECTION(src_width))/((double)dst_width-1); \ 00104 if ((ABS(src_height)>1)&&(ABS(dst_height)>1)) \ 00105 dyinc = ((double)src_height-DIRECTION(src_height))/((double)dst_height-1); \ 00106 } else { \ 00107 if ((ABS(src_width)>1)&&(ABS(dst_width)>1)) \ 00108 dxinc = ((double)src_width)/((double)dst_width); \ 00109 if ((ABS(src_height)>1)&&(ABS(dst_height)>1)) \ 00110 dyinc = ((double)src_height)/((double)dst_height); \ 00111 } \ 00112 \ 00113 if (ABS(dxinc)<JIT_MATRIX_INC_THRESH) dxinc = 0; \ 00114 if (ABS(dyinc)<JIT_MATRIX_INC_THRESH) dyinc = 0; \ 00115 \ 00116 if (dxinc==1&&dyinc==1) unity = TRUE; \ 00117 xdir = DIRECTION(dxinc); \ 00118 ydir = DIRECTION(dyinc); \ 00119 \ 00120 switch (xdir) \ 00121 { \ 00122 case 1: xmax = src_width-1; xmin = 0; break; \ 00123 case -1: xmin = src_width+1; xmax = 0; break; \ 00124 default: xmin = xmax = 0; break; \ 00125 } \ 00126 switch (ydir) \ 00127 { \ 00128 case 1: ymax = src_height-1; ymin = 0; break; \ 00129 case -1: ymin = src_height+1; ymax = 0; break; \ 00130 default: ymin = ymax = 0; break; \ 00131 } 00132 00133 00134 // FM_COPY has no interpolation, but uses fractional increment 00135 #define FM_COPY_SETUP_DOUBLE(inputtype,outputtype) \ 00136 outputtype *dst; \ 00137 inputtype *src,*src0; \ 00138 long xidx_int,yidx_int; \ 00139 double xidx=0,xinc=dxinc,yidx=0,yinc=dyinc; \ 00140 double xfudge=0,yfudge=0; 00141 00142 00143 #define FM_COPY_SETUP_FIXED(inputtype,outputtype) \ 00144 outputtype *dst; \ 00145 inputtype *src,*src0; \ 00146 long xidx_int,yidx_int; \ 00147 Fixed xidx=0,xinc=0,yidx=0,yinc=0; \ 00148 Fixed xfudge,yfudge; \ 00149 \ 00150 xfudge = DoubleToFixed((xdir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); \ 00151 yfudge = DoubleToFixed((ydir>=0)?JIT_MATRIX_FUDGE:1.-JIT_MATRIX_FUDGE); \ 00152 xinc = DoubleToFixed(dxinc); \ 00153 yinc = DoubleToFixed(dyinc); 00154 00155 00156 #define FM_COPY_ROW_LOOP(inputtype,outputtype,intfn,columnloop) \ 00157 yidx = yfudge; \ 00158 for(i=0;i<dst_height;i++) { \ 00159 yidx_int = intfn(yidx); \ 00160 CLIP(yidx_int,ymin,ymax); \ 00161 src0 = (inputtype *)(src_bp + (yidx_int*src_rowstride)); \ 00162 dst = (outputtype *)(dst_bp + (i*dst_rowstride)); \ 00163 xidx = xfudge; \ 00164 columnloop \ 00165 yidx+=yinc; \ 00166 } 00167 00168 00169 #define FM_COPY_COLUMN_LOOP(intfn,planeloop) \ 00170 for(j=0;j<dst_width;j++) { \ 00171 xidx_int = intfn(xidx); \ 00172 CLIP(xidx_int,xmin,xmax); \ 00173 src = src0 + (xidx_int*src_cellstride); \ 00174 planeloop \ 00175 dst+=dst_cellstride; \ 00176 xidx+=xinc; \ 00177 } 00178 00179 00180 #define FM_COPY_PLANE_LOOP(convfn) \ 00181 for (k=0;k<planecount;k++) { \ 00182 if (planemap[k]>=0) \ 00183 dst[k]=convfn(*(src+planemap[k])); \ 00184 } 00185 00186 #define FM_COPY_ROW_LOOP_DOUBLE(inputtype,outputtype,columnloop) \ 00187 FM_COPY_ROW_LOOP(inputtype,outputtype,FM_INTFN_DOUBLE,columnloop) 00188 00189 #define FM_COPY_ROW_LOOP_FIXED(inputtype,outputtype,columnloop) \ 00190 FM_COPY_ROW_LOOP(inputtype,outputtype,FM_INTFN_FIXED,columnloop) 00191 00192 #define FM_COPY_COLUMN_LOOP_DOUBLE(planeloop) \ 00193 FM_COPY_COLUMN_LOOP(FM_INTFN_DOUBLE,planeloop) 00194 00195 #define FM_COPY_COLUMN_LOOP_FIXED(planeloop) \ 00196 FM_COPY_COLUMN_LOOP(FM_INTFN_FIXED,planeloop) 00197 00198 #define FM_COPY_ALL_DOUBLE(inputtype,outputtype,convfn) \ 00199 FM_COPY_SETUP_DOUBLE(inputtype,outputtype); \ 00200 FM_COPY_ROW_LOOP_DOUBLE(inputtype,outputtype,FM_COPY_COLUMN_LOOP_DOUBLE(FM_COPY_PLANE_LOOP(convfn))); 00201 00202 #define FM_COPY_ALL_FIXED(inputtype,outputtype,convfn) \ 00203 FM_COPY_SETUP_FIXED(inputtype,outputtype); \ 00204 FM_COPY_ROW_LOOP_FIXED(inputtype,outputtype,FM_COPY_COLUMN_LOOP_FIXED(FM_COPY_PLANE_LOOP(convfn))); 00205 00206 00207 00208 // FM_COPY_INTERP uses interpolation and fractional increment 00209 #define FM_COPY_INTERP_SETUP(inputtype,outputtype,tmptype,tmpconv) \ 00210 outputtype *dst; \ 00211 inputtype *src,*src2,*x0,*x1,*x2,*x3; \ 00212 long xidx_int,xidx_int2,yidx_int,yidx_int2; \ 00213 tmptype c0,c1,c2,c3; \ 00214 tmptype xfrak,yfrak,xfrak_inv,yfrak_inv; \ 00215 tmptype xidx=0,xinc=tmpconv(dxinc),yidx=0,yinc=tmpconv(dyinc); 00216 00217 00218 #define FM_COPY_INTERP_SETUP_DOUBLE(inputtype,outputtype) \ 00219 FM_COPY_INTERP_SETUP(inputtype,outputtype,double,FM_CONVFN_NONE) 00220 00221 00222 #define FM_COPY_INTERP_SETUP_FIXED(inputtype,outputtype) \ 00223 FM_COPY_INTERP_SETUP(inputtype,outputtype,Fixed,DoubleToFixed) 00224 00225 00226 #define FM_COPY_INTERP_ROW_LOOP(inputtype,outputtype,intfn,frakfn,negfrakfn,invfrakfn,columnloop) \ 00227 for(i=0;i<dst_height;i++) { \ 00228 yidx_int = intfn(yidx); \ 00229 yidx_int2 = yidx_int+ydir; \ 00230 CLIP(yidx_int2,ymin,ymax); \ 00231 src = (inputtype *)(src_bp + (yidx_int * src_rowstride)); \ 00232 src2 = (inputtype *)(src_bp + (yidx_int2 * src_rowstride)); \ 00233 dst = (outputtype *)(dst_bp + (i * dst_rowstride)); \ 00234 xidx = 0; \ 00235 yfrak = frakfn(yidx,yidx_int); \ 00236 if (ydir<0&&yfrak!=0) yfrak = negfrakfn(yfrak); \ 00237 yfrak_inv = invfrakfn(yfrak); \ 00238 columnloop \ 00239 yidx+=yinc; \ 00240 } 00241 00242 00243 #define FM_COPY_INTERP_COLUMN_LOOP(intfn,frakfn,negfrakfn,invfrakfn,mulfn,planeloop) \ 00244 for(j=0;j<dst_width;j++) { \ 00245 xidx_int = intfn(xidx); \ 00246 xidx_int2 = xidx_int+xdir; \ 00247 CLIP(xidx_int2,xmin,xmax); \ 00248 xfrak = frakfn(xidx,xidx_int); \ 00249 if (xdir<0&&xfrak!=0) xfrak = negfrakfn(xfrak); \ 00250 xfrak_inv = invfrakfn(xfrak); \ 00251 xidx_int *= src_cellstride; \ 00252 xidx_int2 *= src_cellstride; \ 00253 x0 = src + xidx_int; \ 00254 x1 = src + xidx_int2; \ 00255 x2 = src2 + xidx_int; \ 00256 x3 = src2 + xidx_int2; \ 00257 c0 = mulfn(xfrak_inv,yfrak_inv); \ 00258 c1 = mulfn(xfrak,yfrak_inv); \ 00259 c2 = mulfn(xfrak_inv,yfrak); \ 00260 c3 = mulfn(xfrak,yfrak); \ 00261 planeloop \ 00262 dst+=dst_cellstride; \ 00263 xidx+=xinc; \ 00264 } 00265 00266 00267 #define FM_COPY_INTERP_PLANE_LOOP(mulfn,convfn) \ 00268 for (k=0;k<planecount;k++) { \ 00269 poff=planemap[k]; \ 00270 if (poff>=0) \ 00271 dst[k]=convfn(mulfn(*(x0+poff),c0) + mulfn(*(x1+poff),c1) + mulfn(*(x2+poff),c2) + mulfn(*(x3+poff),c3)); \ 00272 } 00273 00274 00275 #define FM_COPY_INTERP_ROW_LOOP_DOUBLE(inputtype,outputtype,columnloop) \ 00276 FM_COPY_INTERP_ROW_LOOP(inputtype,outputtype,FM_INTFN_DOUBLE,FM_FRAKFN_DOUBLE,FM_NEGFRAKFN_DOUBLE,FM_INVFRAKFN_DOUBLE,columnloop) 00277 00278 #define FM_COPY_INTERP_ROW_LOOP_FIXED(inputtype,outputtype,columnloop) \ 00279 FM_COPY_INTERP_ROW_LOOP(inputtype,outputtype,FM_INTFN_FIXED,FM_FRAKFN_FIXED,FM_NEGFRAKFN_FIXED,FM_INVFRAKFN_FIXED,columnloop) 00280 00281 #define FM_COPY_INTERP_COLUMN_LOOP_DOUBLE(planeloop) \ 00282 FM_COPY_INTERP_COLUMN_LOOP(FM_INTFN_DOUBLE,FM_FRAKFN_DOUBLE,FM_NEGFRAKFN_DOUBLE,FM_INVFRAKFN_DOUBLE,FM_MULFN_DOUBLE,planeloop) 00283 00284 #define FM_COPY_INTERP_COLUMN_LOOP_FIXED(planeloop) \ 00285 FM_COPY_INTERP_COLUMN_LOOP(FM_INTFN_FIXED,FM_FRAKFN_FIXED,FM_NEGFRAKFN_FIXED,FM_INVFRAKFN_FIXED,FM_MULFN_FIXED,planeloop) 00286 00287 #define FM_COPY_INTERP_ALL_DOUBLE(inputtype,outputtype,mulfn,convfn) \ 00288 FM_COPY_INTERP_SETUP_DOUBLE(inputtype,outputtype); \ 00289 FM_COPY_INTERP_ROW_LOOP_DOUBLE(inputtype,outputtype,FM_COPY_INTERP_COLUMN_LOOP_DOUBLE(FM_COPY_INTERP_PLANE_LOOP(mulfn,convfn))); 00290 00291 #define FM_COPY_INTERP_ALL_FIXED(inputtype,outputtype,mulfn,convfn) \ 00292 FM_COPY_INTERP_SETUP_FIXED(inputtype,outputtype); \ 00293 FM_COPY_INTERP_ROW_LOOP_FIXED(inputtype,outputtype,FM_COPY_INTERP_COLUMN_LOOP_FIXED(FM_COPY_INTERP_PLANE_LOOP(mulfn,convfn))); 00294 00295 00296 // FM_COPY_UNITY uses no interpolation and integer increment 00297 #define FM_COPY_UNITY_SETUP(inputtype,outputtype) \ 00298 outputtype *dst; \ 00299 inputtype *src; \ 00300 00301 #define FM_COPY_UNITY_ROW_LOOP(inputtype,outputtype,columnloop) \ 00302 for(i=0;i<dst_height;i++) { \ 00303 src = (inputtype *)(src_bp + (i*src_rowstride)); \ 00304 dst = (outputtype *)(dst_bp + (i*dst_rowstride)); \ 00305 columnloop \ 00306 } 00307 00308 00309 #define FM_COPY_UNITY_COLUMN_LOOP(planeloop) \ 00310 for(j=0;j<dst_width;j++) { \ 00311 planeloop \ 00312 dst+=dst_cellstride; \ 00313 src+=src_cellstride; \ 00314 } 00315 00316 00317 // if xinc and yinc == 1, and in and out planecount == 1 00318 00319 #define FM_COPY_UNITY_COLUMN_LOOP_1(convfn) \ 00320 for(j=0;j<dst_width;j++) { \ 00321 dst[j] = convfn(src[j]); \ 00322 } 00323 00324 // if xinc and yinc == 1, and in and planecount == 4 00325 00326 #define FM_COPY_UNITY_COLUMN_LOOP_4(convfn) \ 00327 for(j=0;j<(dst_width*4);j+=4) { \ 00328 dst[j] = convfn(src[j]); \ 00329 dst[j+1] = convfn(src[j+1]); \ 00330 dst[j+2] = convfn(src[j+2]); \ 00331 dst[j+3] = convfn(src[j+3]); \ 00332 } 00333 00334 00335 #define FM_COPY_UNITY_ALL(inputtype,outputtype,convfn) \ 00336 FM_COPY_UNITY_SETUP(inputtype,outputtype); \ 00337 if ((src_minfo->planecount==1)&&(dst_minfo->planecount==1)&& \ 00338 (dst_cellstride==dst_typesize)&& \ 00339 (src_cellstride==dst_cellstride)) \ 00340 { \ 00341 if (planemap[0]>=0) { \ 00342 FM_COPY_UNITY_ROW_LOOP(inputtype,outputtype,FM_COPY_UNITY_COLUMN_LOOP_1(convfn)); \ 00343 } \ 00344 } else if ((src_minfo->planecount==4)&&(dst_minfo->planecount==4)&& \ 00345 (planemap[0]==0)&&(planemap[1]==1)&&(planemap[2]==2)&&(planemap[3]==3)&& \ 00346 (dst_cellstride==dst_typesize)&& \ 00347 (src_cellstride==dst_cellstride)) \ 00348 { \ 00349 FM_COPY_UNITY_ROW_LOOP(inputtype,outputtype,FM_COPY_UNITY_COLUMN_LOOP_4(convfn)); \ 00350 } else { \ 00351 FM_COPY_UNITY_ROW_LOOP(inputtype,outputtype,FM_COPY_UNITY_COLUMN_LOOP(FM_COPY_PLANE_LOOP(convfn))); \ 00352 } 00353
Copyright © 2008, Cycling '74