Ignore:
Timestamp:
06/05/12 03:11:34 (12 months ago)
Author:
anthony
Message:

Rename of 'bicubic' interpolation to more precise 'catrom'.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ImageMagick/branches/ImageMagick-6/magick/resize.c

    r8127 r8157  
    308308  /* 
    309309    Kaiser Windowing Function (bessel windowing) 
    310     Alpha (coeff[0]) is a free value from 5 to 8 (defaults to 6.5). 
    311     A scaling factor (coeff[1]) is not actually needed as filter will 
    312     automatically be normalized. 
     310 
     311       I0( beta * sqrt( 1-x^2) ) / IO(0) 
     312 
     313    Beta (coeff[0]) is a free value from 5 to 8 (defaults to 6.5). 
     314    However it is typically defined in terms of Alpha*PI 
     315 
     316    The normalization factor (coeff[1]) is not actually needed, 
     317    but without it the filters has a large value at x=0 making it 
     318    difficult to compare the function with other windowing functions. 
    313319  */ 
    314320  return(resize_filter->coefficient[1]* 
    315             I0(resize_filter->coefficient[0]*sqrt((double) (1.0-x*x)))); 
     321           I0(resize_filter->coefficient[0]*sqrt((double) (1.0-x*x)))); 
    316322} 
    317323 
     
    970976  if ((resize_filter->filter == Kaiser) || 
    971977      (resize_filter->window == Kaiser) ) { 
    972     value=6.5; /* default alpha value for Kaiser bessel windowing function */ 
    973     artifact=GetImageArtifact(image,"filter:alpha"); 
     978    value=6.5; /* default beta value for Kaiser bessel windowing function */ 
     979    artifact=GetImageArtifact(image,"filter:alpha");  /* FUTURE: depreciate */ 
    974980    if (artifact != (const char *) NULL) 
    975981      value=StringToDouble(artifact,(char **) NULL); 
     
    11671173%  AdaptiveResizeImage() adaptively resize image with pixel resampling. 
    11681174% 
     1175%  This is shortcut function for a fast interpolative resize using mesh 
     1176%  interpolation.  It works well for small resizes of less than +/- 50% 
     1177%  of the original image size.  For larger resizing on images a full 
     1178%  filtered and slower resize function should be used instead. 
     1179% 
    11691180%  The format of the AdaptiveResizeImage method is: 
    11701181% 
     
    11861197  const size_t columns,const size_t rows,ExceptionInfo *exception) 
    11871198{ 
    1188 #define AdaptiveResizeImageTag  "Resize/Image" 
     1199  return(InterpolativeResizeImage(image,columns,rows,MeshInterpolatePixel, 
     1200    exception)); 
     1201} 
     1202 
     1203/* 
     1204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1205%                                                                             % 
     1206%                                                                             % 
     1207%                                                                             % 
     1208+   B e s s e l O r d e r O n e                                               % 
     1209%                                                                             % 
     1210%                                                                             % 
     1211%                                                                             % 
     1212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1213% 
     1214%  BesselOrderOne() computes the Bessel function of x of the first kind of 
     1215%  order 0.  This is used to create the Jinc() filter function below. 
     1216% 
     1217%    Reduce x to |x| since j1(x)= -j1(-x), and for x in (0,8] 
     1218% 
     1219%       j1(x) = x*j1(x); 
     1220% 
     1221%    For x in (8,inf) 
     1222% 
     1223%       j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) 
     1224% 
     1225%    where x1 = x-3*pi/4. Compute sin(x1) and cos(x1) as follow: 
     1226% 
     1227%       cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4) 
     1228%               =  1/sqrt(2) * (sin(x) - cos(x)) 
     1229%       sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4) 
     1230%               = -1/sqrt(2) * (sin(x) + cos(x)) 
     1231% 
     1232%  The format of the BesselOrderOne method is: 
     1233% 
     1234%      MagickRealType BesselOrderOne(MagickRealType x) 
     1235% 
     1236%  A description of each parameter follows: 
     1237% 
     1238%    o x: MagickRealType value. 
     1239% 
     1240*/ 
     1241 
     1242#undef I0 
     1243static MagickRealType I0(MagickRealType x) 
     1244{ 
     1245  MagickRealType 
     1246    sum, 
     1247    t, 
     1248    y; 
     1249 
     1250  register ssize_t 
     1251    i; 
     1252 
     1253  /* 
     1254    Zeroth order Bessel function of the first kind. 
     1255  */ 
     1256  sum=1.0; 
     1257  y=x*x/4.0; 
     1258  t=y; 
     1259  for (i=2; t > MagickEpsilon; i++) 
     1260  { 
     1261    sum+=t; 
     1262    t*=y/((MagickRealType) i*i); 
     1263  } 
     1264  return(sum); 
     1265} 
     1266 
     1267#undef J1 
     1268static MagickRealType J1(MagickRealType x) 
     1269{ 
     1270  MagickRealType 
     1271    p, 
     1272    q; 
     1273 
     1274  register ssize_t 
     1275    i; 
     1276 
     1277  static const double 
     1278    Pone[] = 
     1279    { 
     1280       0.581199354001606143928050809e+21, 
     1281      -0.6672106568924916298020941484e+20, 
     1282       0.2316433580634002297931815435e+19, 
     1283      -0.3588817569910106050743641413e+17, 
     1284       0.2908795263834775409737601689e+15, 
     1285      -0.1322983480332126453125473247e+13, 
     1286       0.3413234182301700539091292655e+10, 
     1287      -0.4695753530642995859767162166e+7, 
     1288       0.270112271089232341485679099e+4 
     1289    }, 
     1290    Qone[] = 
     1291    { 
     1292      0.11623987080032122878585294e+22, 
     1293      0.1185770712190320999837113348e+20, 
     1294      0.6092061398917521746105196863e+17, 
     1295      0.2081661221307607351240184229e+15, 
     1296      0.5243710262167649715406728642e+12, 
     1297      0.1013863514358673989967045588e+10, 
     1298      0.1501793594998585505921097578e+7, 
     1299      0.1606931573481487801970916749e+4, 
     1300      0.1e+1 
     1301    }; 
     1302 
     1303  p=Pone[8]; 
     1304  q=Qone[8]; 
     1305  for (i=7; i >= 0; i--) 
     1306  { 
     1307    p=p*x*x+Pone[i]; 
     1308    q=q*x*x+Qone[i]; 
     1309  } 
     1310  return(p/q); 
     1311} 
     1312 
     1313#undef P1 
     1314static MagickRealType P1(MagickRealType x) 
     1315{ 
     1316  MagickRealType 
     1317    p, 
     1318    q; 
     1319 
     1320  register ssize_t 
     1321    i; 
     1322 
     1323  static const double 
     1324    Pone[] = 
     1325    { 
     1326      0.352246649133679798341724373e+5, 
     1327      0.62758845247161281269005675e+5, 
     1328      0.313539631109159574238669888e+5, 
     1329      0.49854832060594338434500455e+4, 
     1330      0.2111529182853962382105718e+3, 
     1331      0.12571716929145341558495e+1 
     1332    }, 
     1333    Qone[] = 
     1334    { 
     1335      0.352246649133679798068390431e+5, 
     1336      0.626943469593560511888833731e+5, 
     1337      0.312404063819041039923015703e+5, 
     1338      0.4930396490181088979386097e+4, 
     1339      0.2030775189134759322293574e+3, 
     1340      0.1e+1 
     1341    }; 
     1342 
     1343  p=Pone[5]; 
     1344  q=Qone[5]; 
     1345  for (i=4; i >= 0; i--) 
     1346  { 
     1347    p=p*(8.0/x)*(8.0/x)+Pone[i]; 
     1348    q=q*(8.0/x)*(8.0/x)+Qone[i]; 
     1349  } 
     1350  return(p/q); 
     1351} 
     1352 
     1353#undef Q1 
     1354static MagickRealType Q1(MagickRealType x) 
     1355{ 
     1356  MagickRealType 
     1357    p, 
     1358    q; 
     1359 
     1360  register ssize_t 
     1361    i; 
     1362 
     1363  static const double 
     1364    Pone[] = 
     1365    { 
     1366      0.3511751914303552822533318e+3, 
     1367      0.7210391804904475039280863e+3, 
     1368      0.4259873011654442389886993e+3, 
     1369      0.831898957673850827325226e+2, 
     1370      0.45681716295512267064405e+1, 
     1371      0.3532840052740123642735e-1 
     1372    }, 
     1373    Qone[] = 
     1374    { 
     1375      0.74917374171809127714519505e+4, 
     1376      0.154141773392650970499848051e+5, 
     1377      0.91522317015169922705904727e+4, 
     1378      0.18111867005523513506724158e+4, 
     1379      0.1038187585462133728776636e+3, 
     1380      0.1e+1 
     1381    }; 
     1382 
     1383  p=Pone[5]; 
     1384  q=Qone[5]; 
     1385  for (i=4; i >= 0; i--) 
     1386  { 
     1387    p=p*(8.0/x)*(8.0/x)+Pone[i]; 
     1388    q=q*(8.0/x)*(8.0/x)+Qone[i]; 
     1389  } 
     1390  return(p/q); 
     1391} 
     1392 
     1393static MagickRealType BesselOrderOne(MagickRealType x) 
     1394{ 
     1395  MagickRealType 
     1396    p, 
     1397    q; 
     1398 
     1399  if (x == 0.0) 
     1400    return(0.0); 
     1401  p=x; 
     1402  if (x < 0.0) 
     1403    x=(-x); 
     1404  if (x < 8.0) 
     1405    return(p*J1(x)); 
     1406  q=sqrt((double) (2.0/(MagickPI*x)))*(P1(x)*(1.0/sqrt(2.0)*(sin((double) x)- 
     1407    cos((double) x)))-8.0/x*Q1(x)*(-1.0/sqrt(2.0)*(sin((double) x)+ 
     1408    cos((double) x)))); 
     1409  if (p < 0.0) 
     1410    q=(-q); 
     1411  return(q); 
     1412} 
     1413 
     1414/* 
     1415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1416%                                                                             % 
     1417%                                                                             % 
     1418%                                                                             % 
     1419+   D e s t r o y R e s i z e F i l t e r                                     % 
     1420%                                                                             % 
     1421%                                                                             % 
     1422%                                                                             % 
     1423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1424% 
     1425%  DestroyResizeFilter() destroy the resize filter. 
     1426% 
     1427%  The format of the DestroyResizeFilter method is: 
     1428% 
     1429%      ResizeFilter *DestroyResizeFilter(ResizeFilter *resize_filter) 
     1430% 
     1431%  A description of each parameter follows: 
     1432% 
     1433%    o resize_filter: the resize filter. 
     1434% 
     1435*/ 
     1436MagickExport ResizeFilter *DestroyResizeFilter(ResizeFilter *resize_filter) 
     1437{ 
     1438  assert(resize_filter != (ResizeFilter *) NULL); 
     1439  assert(resize_filter->signature == MagickSignature); 
     1440  resize_filter->signature=(~MagickSignature); 
     1441  resize_filter=(ResizeFilter *) RelinquishMagickMemory(resize_filter); 
     1442  return(resize_filter); 
     1443} 
     1444 
     1445/* 
     1446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1447%                                                                             % 
     1448%                                                                             % 
     1449%                                                                             % 
     1450+   G e t R e s i z e F i l t e r S u p p o r t                               % 
     1451%                                                                             % 
     1452%                                                                             % 
     1453%                                                                             % 
     1454%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1455% 
     1456%  GetResizeFilterSupport() return the current support window size for this 
     1457%  filter.  Note that this may have been enlarged by filter:blur factor. 
     1458% 
     1459%  The format of the GetResizeFilterSupport method is: 
     1460% 
     1461%      MagickRealType GetResizeFilterSupport(const ResizeFilter *resize_filter) 
     1462% 
     1463%  A description of each parameter follows: 
     1464% 
     1465%    o filter: Image filter to use. 
     1466% 
     1467*/ 
     1468MagickExport MagickRealType GetResizeFilterSupport( 
     1469  const ResizeFilter *resize_filter) 
     1470{ 
     1471  assert(resize_filter != (ResizeFilter *) NULL); 
     1472  assert(resize_filter->signature == MagickSignature); 
     1473  return(resize_filter->support*resize_filter->blur); 
     1474} 
     1475 
     1476/* 
     1477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1478%                                                                             % 
     1479%                                                                             % 
     1480%                                                                             % 
     1481+   G e t R e s i z e F i l t e r W e i g h t                                 % 
     1482%                                                                             % 
     1483%                                                                             % 
     1484%                                                                             % 
     1485%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1486% 
     1487%  GetResizeFilterWeight evaluates the specified resize filter at the point x 
     1488%  which usally lies between zero and the filters current 'support' and 
     1489%  returns the weight of the filter function at that point. 
     1490% 
     1491%  The format of the GetResizeFilterWeight method is: 
     1492% 
     1493%      MagickRealType GetResizeFilterWeight(const ResizeFilter *resize_filter, 
     1494%        const MagickRealType x) 
     1495% 
     1496%  A description of each parameter follows: 
     1497% 
     1498%    o filter: the filter type. 
     1499% 
     1500%    o x: the point. 
     1501% 
     1502*/ 
     1503MagickExport MagickRealType GetResizeFilterWeight( 
     1504  const ResizeFilter *resize_filter,const MagickRealType x) 
     1505{ 
     1506  MagickRealType 
     1507    scale, 
     1508    weight, 
     1509    x_blur; 
     1510 
     1511  /* 
     1512    Windowing function - scale the weighting filter by this amount. 
     1513  */ 
     1514  assert(resize_filter != (ResizeFilter *) NULL); 
     1515  assert(resize_filter->signature == MagickSignature); 
     1516  x_blur=fabs((double) x)/resize_filter->blur;  /* X offset with blur scaling */ 
     1517  if ((resize_filter->window_support < MagickEpsilon) || 
     1518      (resize_filter->window == Box)) 
     1519    scale=1.0;  /* Point or Box Filter -- avoid division by zero */ 
     1520  else 
     1521    { 
     1522      scale=resize_filter->scale; 
     1523      scale=resize_filter->window(x_blur*scale,resize_filter); 
     1524    } 
     1525  weight=scale*resize_filter->filter(x_blur,resize_filter); 
     1526  return(weight); 
     1527} 
     1528 
     1529/* 
     1530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1531%                                                                             % 
     1532%                                                                             % 
     1533%                                                                             % 
     1534%   I n t e r p o l a t i v e R e s i z e I m a g e                           % 
     1535%                                                                             % 
     1536%                                                                             % 
     1537%                                                                             % 
     1538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1539% 
     1540%  InterpolativeResizeImage() resizes an image using the specified 
     1541%  interpolation method. 
     1542% 
     1543%  The format of the InterpolativeResizeImage method is: 
     1544% 
     1545%      Image *InterpolativeResizeImage(const Image *image,const size_t columns, 
     1546%        const size_t rows,const InterpolatePixelMethod method, 
     1547%        ExceptionInfo *exception) 
     1548% 
     1549%  A description of each parameter follows: 
     1550% 
     1551%    o image: the image. 
     1552% 
     1553%    o columns: the number of columns in the resized image. 
     1554% 
     1555%    o rows: the number of rows in the resized image. 
     1556% 
     1557%    o method: the pixel interpolation method. 
     1558% 
     1559%    o exception: return any errors or warnings in this structure. 
     1560% 
     1561*/ 
     1562MagickExport Image *InterpolativeResizeImage(const Image *image, 
     1563  const size_t columns,const size_t rows,const InterpolatePixelMethod method, 
     1564  ExceptionInfo *exception) 
     1565{ 
     1566#define InterpolativeResizeImageTag  "Resize/Image" 
    11891567 
    11901568  CacheView 
     
    12011579    progress; 
    12021580 
     1581  PointInfo 
     1582    scale; 
     1583 
    12031584  ssize_t 
    12041585    y; 
    12051586 
    12061587  /* 
    1207     Adaptively resize image. 
     1588    Interpolatively resize image. 
    12081589  */ 
    12091590  assert(image != (const Image *) NULL); 
     
    12301611  image_view=AcquireVirtualCacheView(image,exception); 
    12311612  resize_view=AcquireAuthenticCacheView(resize_image,exception); 
     1613  scale.x=(double) image->columns/resize_image->columns; 
     1614  scale.y=(double) image->rows/resize_image->rows; 
    12321615#if defined(MAGICKCORE_OPENMP_SUPPORT) 
    12331616  #pragma omp parallel for schedule(static) shared(progress,status) \ 
     
    12581641      continue; 
    12591642    resize_indexes=GetCacheViewAuthenticIndexQueue(resize_view); 
    1260     offset.y=((MagickRealType) (y+0.5)*image->rows/resize_image->rows); 
    12611643    GetMagickPixelPacket(image,&pixel); 
     1644    offset.y=((MagickRealType) y+0.5)*scale.y-0.5; 
    12621645    for (x=0; x < (ssize_t) resize_image->columns; x++) 
    12631646    { 
    1264       offset.x=((MagickRealType) (x+0.5)*image->columns/resize_image->columns); 
    1265       (void) InterpolateMagickPixelPacket(image,image_view, 
    1266         MeshInterpolatePixel,offset.x-0.5,offset.y-0.5,&pixel,exception); 
     1647      offset.x=((MagickRealType) x+0.5)*scale.x-0.5; 
     1648      (void) InterpolateMagickPixelPacket(image,image_view,method, 
     1649           offset.x,offset.y,&pixel,exception); 
    12671650      SetPixelPacket(resize_image,&pixel,q,resize_indexes+x); 
    12681651      q++; 
     
    12761659 
    12771660#if defined(MAGICKCORE_OPENMP_SUPPORT)  
    1278         #pragma omp critical (MagickCore_AdaptiveResizeImage) 
     1661        #pragma omp critical (MagickCore_InterpolativeResizeImage) 
    12791662#endif 
    1280         proceed=SetImageProgress(image,AdaptiveResizeImageTag,progress++, 
     1663        proceed=SetImageProgress(image,InterpolativeResizeImageTag,progress++, 
    12811664          image->rows); 
    12821665        if (proceed == MagickFalse) 
     
    12891672    resize_image=DestroyImage(resize_image); 
    12901673  return(resize_image); 
    1291 } 
    1292  
    1293 /* 
    1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1295 %                                                                             % 
    1296 %                                                                             % 
    1297 %                                                                             % 
    1298 +   B e s s e l O r d e r O n e                                               % 
    1299 %                                                                             % 
    1300 %                                                                             % 
    1301 %                                                                             % 
    1302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1303 % 
    1304 %  BesselOrderOne() computes the Bessel function of x of the first kind of 
    1305 %  order 0.  This is used to create the Jinc() filter function below. 
    1306 % 
    1307 %    Reduce x to |x| since j1(x)= -j1(-x), and for x in (0,8] 
    1308 % 
    1309 %       j1(x) = x*j1(x); 
    1310 % 
    1311 %    For x in (8,inf) 
    1312 % 
    1313 %       j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) 
    1314 % 
    1315 %    where x1 = x-3*pi/4. Compute sin(x1) and cos(x1) as follow: 
    1316 % 
    1317 %       cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4) 
    1318 %               =  1/sqrt(2) * (sin(x) - cos(x)) 
    1319 %       sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4) 
    1320 %               = -1/sqrt(2) * (sin(x) + cos(x)) 
    1321 % 
    1322 %  The format of the BesselOrderOne method is: 
    1323 % 
    1324 %      MagickRealType BesselOrderOne(MagickRealType x) 
    1325 % 
    1326 %  A description of each parameter follows: 
    1327 % 
    1328 %    o x: MagickRealType value. 
    1329 % 
    1330 */ 
    1331  
    1332 #undef I0 
    1333 static MagickRealType I0(MagickRealType x) 
    1334 { 
    1335   MagickRealType 
    1336     sum, 
    1337     t, 
    1338     y; 
    1339  
    1340   register ssize_t 
    1341     i; 
    1342  
    1343   /* 
    1344     Zeroth order Bessel function of the first kind. 
    1345   */ 
    1346   sum=1.0; 
    1347   y=x*x/4.0; 
    1348   t=y; 
    1349   for (i=2; t > MagickEpsilon; i++) 
    1350   { 
    1351     sum+=t; 
    1352     t*=y/((MagickRealType) i*i); 
    1353   } 
    1354   return(sum); 
    1355 } 
    1356  
    1357 #undef J1 
    1358 static MagickRealType J1(MagickRealType x) 
    1359 { 
    1360   MagickRealType 
    1361     p, 
    1362     q; 
    1363  
    1364   register ssize_t 
    1365     i; 
    1366  
    1367   static const double 
    1368     Pone[] = 
    1369     { 
    1370        0.581199354001606143928050809e+21, 
    1371       -0.6672106568924916298020941484e+20, 
    1372        0.2316433580634002297931815435e+19, 
    1373       -0.3588817569910106050743641413e+17, 
    1374        0.2908795263834775409737601689e+15, 
    1375       -0.1322983480332126453125473247e+13, 
    1376        0.3413234182301700539091292655e+10, 
    1377       -0.4695753530642995859767162166e+7, 
    1378        0.270112271089232341485679099e+4 
    1379     }, 
    1380     Qone[] = 
    1381     { 
    1382       0.11623987080032122878585294e+22, 
    1383       0.1185770712190320999837113348e+20, 
    1384       0.6092061398917521746105196863e+17, 
    1385       0.2081661221307607351240184229e+15, 
    1386       0.5243710262167649715406728642e+12, 
    1387       0.1013863514358673989967045588e+10, 
    1388       0.1501793594998585505921097578e+7, 
    1389       0.1606931573481487801970916749e+4, 
    1390       0.1e+1 
    1391     }; 
    1392  
    1393   p=Pone[8]; 
    1394   q=Qone[8]; 
    1395   for (i=7; i >= 0; i--) 
    1396   { 
    1397     p=p*x*x+Pone[i]; 
    1398     q=q*x*x+Qone[i]; 
    1399   } 
    1400   return(p/q); 
    1401 } 
    1402  
    1403 #undef P1 
    1404 static MagickRealType P1(MagickRealType x) 
    1405 { 
    1406   MagickRealType 
    1407     p, 
    1408     q; 
    1409  
    1410   register ssize_t 
    1411     i; 
    1412  
    1413   static const double 
    1414     Pone[] = 
    1415     { 
    1416       0.352246649133679798341724373e+5, 
    1417       0.62758845247161281269005675e+5, 
    1418       0.313539631109159574238669888e+5, 
    1419       0.49854832060594338434500455e+4, 
    1420       0.2111529182853962382105718e+3, 
    1421       0.12571716929145341558495e+1 
    1422     }, 
    1423     Qone[] = 
    1424     { 
    1425       0.352246649133679798068390431e+5, 
    1426       0.626943469593560511888833731e+5, 
    1427       0.312404063819041039923015703e+5, 
    1428       0.4930396490181088979386097e+4, 
    1429       0.2030775189134759322293574e+3, 
    1430       0.1e+1 
    1431     }; 
    1432  
    1433   p=Pone[5]; 
    1434   q=Qone[5]; 
    1435   for (i=4; i >= 0; i--) 
    1436   { 
    1437     p=p*(8.0/x)*(8.0/x)+Pone[i]; 
    1438     q=q*(8.0/x)*(8.0/x)+Qone[i]; 
    1439   } 
    1440   return(p/q); 
    1441 } 
    1442  
    1443 #undef Q1 
    1444 static MagickRealType Q1(MagickRealType x) 
    1445 { 
    1446   MagickRealType 
    1447     p, 
    1448     q; 
    1449  
    1450   register ssize_t 
    1451     i; 
    1452  
    1453   static const double 
    1454     Pone[] = 
    1455     { 
    1456       0.3511751914303552822533318e+3, 
    1457       0.7210391804904475039280863e+3, 
    1458       0.4259873011654442389886993e+3, 
    1459       0.831898957673850827325226e+2, 
    1460       0.45681716295512267064405e+1, 
    1461       0.3532840052740123642735e-1 
    1462     }, 
    1463     Qone[] = 
    1464     { 
    1465       0.74917374171809127714519505e+4, 
    1466       0.154141773392650970499848051e+5, 
    1467       0.91522317015169922705904727e+4, 
    1468       0.18111867005523513506724158e+4, 
    1469       0.1038187585462133728776636e+3, 
    1470       0.1e+1 
    1471     }; 
    1472  
    1473   p=Pone[5]; 
    1474   q=Qone[5]; 
    1475   for (i=4; i >= 0; i--) 
    1476   { 
    1477     p=p*(8.0/x)*(8.0/x)+Pone[i]; 
    1478     q=q*(8.0/x)*(8.0/x)+Qone[i]; 
    1479   } 
    1480   return(p/q); 
    1481 } 
    1482  
    1483 static MagickRealType BesselOrderOne(MagickRealType x) 
    1484 { 
    1485   MagickRealType 
    1486     p, 
    1487     q; 
    1488  
    1489   if (x == 0.0) 
    1490     return(0.0); 
    1491   p=x; 
    1492   if (x < 0.0) 
    1493     x=(-x); 
    1494   if (x < 8.0) 
    1495     return(p*J1(x)); 
    1496   q=sqrt((double) (2.0/(MagickPI*x)))*(P1(x)*(1.0/sqrt(2.0)*(sin((double) x)- 
    1497     cos((double) x)))-8.0/x*Q1(x)*(-1.0/sqrt(2.0)*(sin((double) x)+ 
    1498     cos((double) x)))); 
    1499   if (p < 0.0) 
    1500     q=(-q); 
    1501   return(q); 
    1502 } 
    1503  
    1504 /* 
    1505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1506 %                                                                             % 
    1507 %                                                                             % 
    1508 %                                                                             % 
    1509 +   D e s t r o y R e s i z e F i l t e r                                     % 
    1510 %                                                                             % 
    1511 %                                                                             % 
    1512 %                                                                             % 
    1513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1514 % 
    1515 %  DestroyResizeFilter() destroy the resize filter. 
    1516 % 
    1517 %  The format of the DestroyResizeFilter method is: 
    1518 % 
    1519 %      ResizeFilter *DestroyResizeFilter(ResizeFilter *resize_filter) 
    1520 % 
    1521 %  A description of each parameter follows: 
    1522 % 
    1523 %    o resize_filter: the resize filter. 
    1524 % 
    1525 */ 
    1526 MagickExport ResizeFilter *DestroyResizeFilter(ResizeFilter *resize_filter) 
    1527 { 
    1528   assert(resize_filter != (ResizeFilter *) NULL); 
    1529   assert(resize_filter->signature == MagickSignature); 
    1530   resize_filter->signature=(~MagickSignature); 
    1531   resize_filter=(ResizeFilter *) RelinquishMagickMemory(resize_filter); 
    1532   return(resize_filter); 
    1533 } 
    1534  
    1535 /* 
    1536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1537 %                                                                             % 
    1538 %                                                                             % 
    1539 %                                                                             % 
    1540 +   G e t R e s i z e F i l t e r S u p p o r t                               % 
    1541 %                                                                             % 
    1542 %                                                                             % 
    1543 %                                                                             % 
    1544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1545 % 
    1546 %  GetResizeFilterSupport() return the current support window size for this 
    1547 %  filter.  Note that this may have been enlarged by filter:blur factor. 
    1548 % 
    1549 %  The format of the GetResizeFilterSupport method is: 
    1550 % 
    1551 %      MagickRealType GetResizeFilterSupport(const ResizeFilter *resize_filter) 
    1552 % 
    1553 %  A description of each parameter follows: 
    1554 % 
    1555 %    o filter: Image filter to use. 
    1556 % 
    1557 */ 
    1558 MagickExport MagickRealType GetResizeFilterSupport( 
    1559   const ResizeFilter *resize_filter) 
    1560 { 
    1561   assert(resize_filter != (ResizeFilter *) NULL); 
    1562   assert(resize_filter->signature == MagickSignature); 
    1563   return(resize_filter->support*resize_filter->blur); 
    1564 } 
    1565  
    1566 /* 
    1567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1568 %                                                                             % 
    1569 %                                                                             % 
    1570 %                                                                             % 
    1571 +   G e t R e s i z e F i l t e r W e i g h t                                 % 
    1572 %                                                                             % 
    1573 %                                                                             % 
    1574 %                                                                             % 
    1575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1576 % 
    1577 %  GetResizeFilterWeight evaluates the specified resize filter at the point x 
    1578 %  which usally lies between zero and the filters current 'support' and 
    1579 %  returns the weight of the filter function at that point. 
    1580 % 
    1581 %  The format of the GetResizeFilterWeight method is: 
    1582 % 
    1583 %      MagickRealType GetResizeFilterWeight(const ResizeFilter *resize_filter, 
    1584 %        const MagickRealType x) 
    1585 % 
    1586 %  A description of each parameter follows: 
    1587 % 
    1588 %    o filter: the filter type. 
    1589 % 
    1590 %    o x: the point. 
    1591 % 
    1592 */ 
    1593 MagickExport MagickRealType GetResizeFilterWeight( 
    1594   const ResizeFilter *resize_filter,const MagickRealType x) 
    1595 { 
    1596   MagickRealType 
    1597     scale, 
    1598     weight, 
    1599     x_blur; 
    1600  
    1601   /* 
    1602     Windowing function - scale the weighting filter by this amount. 
    1603   */ 
    1604   assert(resize_filter != (ResizeFilter *) NULL); 
    1605   assert(resize_filter->signature == MagickSignature); 
    1606   x_blur=fabs((double) x)/resize_filter->blur;  /* X offset with blur scaling */ 
    1607   if ((resize_filter->window_support < MagickEpsilon) || 
    1608       (resize_filter->window == Box)) 
    1609     scale=1.0;  /* Point or Box Filter -- avoid division by zero */ 
    1610   else 
    1611     { 
    1612       scale=resize_filter->scale; 
    1613       scale=resize_filter->window(x_blur*scale,resize_filter); 
    1614     } 
    1615   weight=scale*resize_filter->filter(x_blur,resize_filter); 
    1616   return(weight); 
    1617 } 
    1618  
    1619 /* 
    1620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1621 %                                                                             % 
    1622 %                                                                             % 
    1623 %                                                                             % 
    1624 %   M a g n i f y I m a g e                                                   % 
    1625 %                                                                             % 
    1626 %                                                                             % 
    1627 %                                                                             % 
    1628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1629 % 
    1630 %  MagnifyImage() is a convenience method that scales an image proportionally 
    1631 %  to twice its size. 
    1632 % 
    1633 %  The format of the MagnifyImage method is: 
    1634 % 
    1635 %      Image *MagnifyImage(const Image *image,ExceptionInfo *exception) 
    1636 % 
    1637 %  A description of each parameter follows: 
    1638 % 
    1639 %    o image: the image. 
    1640 % 
    1641 %    o exception: return any errors or warnings in this structure. 
    1642 % 
    1643 */ 
    1644 MagickExport Image *MagnifyImage(const Image *image,ExceptionInfo *exception) 
    1645 { 
    1646   Image 
    1647     *magnify_image; 
    1648  
    1649   assert(image != (Image *) NULL); 
    1650   assert(image->signature == MagickSignature); 
    1651   if (image->debug != MagickFalse) 
    1652     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 
    1653   assert(exception != (ExceptionInfo *) NULL); 
    1654   assert(exception->signature == MagickSignature); 
    1655   magnify_image=ResizeImage(image,2*image->columns,2*image->rows,CubicFilter, 
    1656     1.0,exception); 
    1657   return(magnify_image); 
    1658 } 
    1659  
    1660 /* 
    1661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1662 %                                                                             % 
    1663 %                                                                             % 
    1664 %                                                                             % 
    1665 %   M i n i f y I m a g e                                                     % 
    1666 %                                                                             % 
    1667 %                                                                             % 
    1668 %                                                                             % 
    1669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1670 % 
    1671 %  MinifyImage() is a convenience method that scales an image proportionally 
    1672 %  to half its size. 
    1673 % 
    1674 %  The format of the MinifyImage method is: 
    1675 % 
    1676 %      Image *MinifyImage(const Image *image,ExceptionInfo *exception) 
    1677 % 
    1678 %  A description of each parameter follows: 
    1679 % 
    1680 %    o image: the image. 
    1681 % 
    1682 %    o exception: return any errors or warnings in this structure. 
    1683 % 
    1684 */ 
    1685 MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception) 
    1686 { 
    1687   Image 
    1688     *minify_image; 
    1689  
    1690   assert(image != (Image *) NULL); 
    1691   assert(image->signature == MagickSignature); 
    1692   if (image->debug != MagickFalse) 
    1693     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 
    1694   assert(exception != (ExceptionInfo *) NULL); 
    1695   assert(exception->signature == MagickSignature); 
    1696   minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,1.0, 
    1697     exception); 
    1698   return(minify_image); 
    1699 } 
    1700  
    1701 /* 
    1702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1703 %                                                                             % 
    1704 %                                                                             % 
    1705 %                                                                             % 
    1706 %   R e s a m p l e I m a g e                                                 % 
    1707 %                                                                             % 
    1708 %                                                                             % 
    1709 %                                                                             % 
    1710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    1711 % 
    1712 %  ResampleImage() resize image in terms of its pixel size, so that when 
    1713 %  displayed at the given resolution it will be the same size in terms of 
    1714 %  real world units as the original image at the original resolution. 
    1715 % 
    1716 %  The format of the ResampleImage method is: 
    1717 % 
    1718 %      Image *ResampleImage(Image *image,const double x_resolution, 
    1719 %        const double y_resolution,const FilterTypes filter,const double blur, 
    1720 %        ExceptionInfo *exception) 
    1721 % 
    1722 %  A description of each parameter follows: 
    1723 % 
    1724 %    o image: the image to be resized to fit the given resolution. 
    1725 % 
    1726 %    o x_resolution: the new image x resolution. 
    1727 % 
    1728 %    o y_resolution: the new image y resolution. 
    1729 % 
    1730 %    o filter: Image filter to use. 
    1731 % 
    1732 %    o blur: the blur factor where > 1 is blurry, < 1 is sharp. 
    1733 % 
    1734 */ 
    1735 MagickExport Image *ResampleImage(const Image *image,const double x_resolution, 
    1736   const double y_resolution,const FilterTypes filter,const double blur, 
    1737   ExceptionInfo *exception) 
    1738 { 
    1739 #define ResampleImageTag  "Resample/Image" 
    1740  
    1741   Image 
    1742     *resample_image; 
    1743  
    1744   size_t 
    1745     height, 
    1746     width; 
    1747  
    1748   /* 
    1749     Initialize sampled image attributes. 
    1750   */ 
    1751   assert(image != (const Image *) NULL); 
    1752   assert(image->signature == MagickSignature); 
    1753   if (image->debug != MagickFalse) 
    1754     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 
    1755   assert(exception != (ExceptionInfo *) NULL); 
    1756   assert(exception->signature == MagickSignature); 
    1757   width=(size_t) (x_resolution*image->columns/(image->x_resolution == 0.0 ? 
    1758     72.0 : image->x_resolution)+0.5); 
    1759   height=(size_t) (y_resolution*image->rows/(image->y_resolution == 0.0 ? 
    1760     72.0 : image->y_resolution)+0.5); 
    1761   resample_image=ResizeImage(image,width,height,filter,blur,exception); 
    1762   if (resample_image != (Image *) NULL) 
    1763     { 
    1764       resample_image->x_resolution=x_resolution; 
    1765       resample_image->y_resolution=y_resolution; 
    1766     } 
    1767   return(resample_image); 
    17681674} 
    17691675#if defined(MAGICKCORE_LQR_DELEGATE) 
     
    19771883} 
    19781884#endif 
     1885 
     1886/* 
     1887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1888%                                                                             % 
     1889%                                                                             % 
     1890%                                                                             % 
     1891%   M a g n i f y I m a g e                                                   % 
     1892%                                                                             % 
     1893%                                                                             % 
     1894%                                                                             % 
     1895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1896% 
     1897%  MagnifyImage() is a convenience method that scales an image proportionally 
     1898%  to twice its size. 
     1899% 
     1900%  The format of the MagnifyImage method is: 
     1901% 
     1902%      Image *MagnifyImage(const Image *image,ExceptionInfo *exception) 
     1903% 
     1904%  A description of each parameter follows: 
     1905% 
     1906%    o image: the image. 
     1907% 
     1908%    o exception: return any errors or warnings in this structure. 
     1909% 
     1910*/ 
     1911MagickExport Image *MagnifyImage(const Image *image,ExceptionInfo *exception) 
     1912{ 
     1913  Image 
     1914    *magnify_image; 
     1915 
     1916  assert(image != (Image *) NULL); 
     1917  assert(image->signature == MagickSignature); 
     1918  if (image->debug != MagickFalse) 
     1919    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 
     1920  assert(exception != (ExceptionInfo *) NULL); 
     1921  assert(exception->signature == MagickSignature); 
     1922  magnify_image=ResizeImage(image,2*image->columns,2*image->rows,CubicFilter, 
     1923    1.0,exception); 
     1924  return(magnify_image); 
     1925} 
     1926 
     1927/* 
     1928%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1929%                                                                             % 
     1930%                                                                             % 
     1931%                                                                             % 
     1932%   M i n i f y I m a g e                                                     % 
     1933%                                                                             % 
     1934%                                                                             % 
     1935%                                                                             % 
     1936%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1937% 
     1938%  MinifyImage() is a convenience method that scales an image proportionally to 
     1939%  half its size. 
     1940% 
     1941%  The format of the MinifyImage method is: 
     1942% 
     1943%      Image *MinifyImage(const Image *image,ExceptionInfo *exception) 
     1944% 
     1945%  A description of each parameter follows: 
     1946% 
     1947%    o image: the image. 
     1948% 
     1949%    o exception: return any errors or warnings in this structure. 
     1950% 
     1951*/ 
     1952MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception) 
     1953{ 
     1954  Image 
     1955    *minify_image; 
     1956 
     1957  assert(image != (Image *) NULL); 
     1958  assert(image->signature == MagickSignature); 
     1959  if (image->debug != MagickFalse) 
     1960    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 
     1961  assert(exception != (ExceptionInfo *) NULL); 
     1962  assert(exception->signature == MagickSignature); 
     1963  minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,1.0, 
     1964    exception); 
     1965  return(minify_image); 
     1966} 
     1967 
     1968/* 
     1969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1970%                                                                             % 
     1971%                                                                             % 
     1972%                                                                             % 
     1973%   R e s a m p l e I m a g e                                                 % 
     1974%                                                                             % 
     1975%                                                                             % 
     1976%                                                                             % 
     1977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     1978% 
     1979%  ResampleImage() resize image in terms of its pixel size, so that when 
     1980%  displayed at the given resolution it will be the same size in terms of 
     1981%  real world units as the original image at the original resolution. 
     1982% 
     1983%  The format of the ResampleImage method is: 
     1984% 
     1985%      Image *ResampleImage(Image *image,const double x_resolution, 
     1986%        const double y_resolution,const FilterTypes filter,const double blur, 
     1987%        ExceptionInfo *exception) 
     1988% 
     1989%  A description of each parameter follows: 
     1990% 
     1991%    o image: the image to be resized to fit the given resolution. 
     1992% 
     1993%    o x_resolution: the new image x resolution. 
     1994% 
     1995%    o y_resolution: the new image y resolution. 
     1996% 
     1997%    o filter: Image filter to use. 
     1998% 
     1999%    o blur: the blur factor where > 1 is blurry, < 1 is sharp. 
     2000% 
     2001*/ 
     2002MagickExport Image *ResampleImage(const Image *image,const double x_resolution, 
     2003  const double y_resolution,const FilterTypes filter,const double blur, 
     2004  ExceptionInfo *exception) 
     2005{ 
     2006#define ResampleImageTag  "Resample/Image" 
     2007 
     2008  Image 
     2009    *resample_image; 
     2010 
     2011  size_t 
     2012    height, 
     2013    width; 
     2014 
     2015  /* 
     2016    Initialize sampled image attributes. 
     2017  */ 
     2018  assert(image != (const Image *) NULL); 
     2019  assert(image->signature == MagickSignature); 
     2020  if (image->debug != MagickFalse) 
     2021    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 
     2022  assert(exception != (ExceptionInfo *) NULL); 
     2023  assert(exception->signature == MagickSignature); 
     2024  width=(size_t) (x_resolution*image->columns/(image->x_resolution == 0.0 ? 
     2025    72.0 : image->x_resolution)+0.5); 
     2026  height=(size_t) (y_resolution*image->rows/(image->y_resolution == 0.0 ? 
     2027    72.0 : image->y_resolution)+0.5); 
     2028  resample_image=ResizeImage(image,width,height,filter,blur,exception); 
     2029  if (resample_image != (Image *) NULL) 
     2030    { 
     2031      resample_image->x_resolution=x_resolution; 
     2032      resample_image->y_resolution=y_resolution; 
     2033    } 
     2034  return(resample_image); 
     2035} 
    19792036 
    19802037/* 
Note: See TracChangeset for help on using the changeset viewer.