~ubuntu-branches/ubuntu/oneiric/imagemagick/oneiric-updates

« back to all changes in this revision

Viewing changes to magick/distort.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-06-15 11:05:28 UTC
  • mfrom: (6.2.11 sid)
  • Revision ID: james.westby@ubuntu.com-20110615110528-08jgo07a4846xh8d
Tags: 8:6.6.0.4-3ubuntu1
* Resynchronise with Debian (LP: #797595).  Remaining changes:
  - Make ufraw-batch (universe) a suggestion instead of a recommendation.
  - Make debian/rules install target depend on check; they cannot reliably
    be run in parallel.
  - Don't set MAKEFLAGS in debian/rules; just pass it to the build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
#include "magick/matrix.h"
57
57
#include "magick/memory_.h"
58
58
#include "magick/monitor-private.h"
59
 
#include "magick/option.h"
60
59
#include "magick/pixel.h"
61
60
#include "magick/pixel-private.h"
62
61
#include "magick/resample.h"
128
127
 
129
128
static inline double MagickRound(double x)
130
129
{
131
 
  /*
132
 
    Round the fraction to nearest integer.
133
 
  */
 
130
  /* round the fraction to nearest integer */
134
131
  if (x >= 0.0)
135
 
    return((double) ((ssize_t) (x+0.5)));
136
 
  return((double) ((ssize_t) (x-0.5)));
 
132
    return((double) ((long) (x+0.5)));
 
133
  return((double) ((long) (x-0.5)));
137
134
}
138
135
 
139
136
/*
155
152
 * which is to allow the use of a bi-linear (order=1.5) polynomial.
156
153
 * All the later polynomials are ordered simply from x^N to y^N
157
154
 */
158
 
static size_t poly_number_terms(double order)
 
155
static unsigned long poly_number_terms(double order)
159
156
{
160
157
 /* Return the number of terms for a 2d polynomial */
161
158
  if ( order < 1 || order > 5 ||
162
159
       ( order != floor(order) && (order-1.5) > MagickEpsilon) )
163
160
    return 0; /* invalid polynomial order */
164
 
  return((size_t) floor((order+1)*(order+2)/2));
 
161
  return((unsigned long) floor((order+1)*(order+2)/2));
165
162
}
166
163
 
167
 
static double poly_basis_fn(ssize_t n, double x, double y)
 
164
static double poly_basis_fn(long n, double x, double y)
168
165
{
169
166
  /* Return the result for this polynomial term */
170
167
  switch(n) {
192
189
  }
193
190
  return( 0 ); /* should never happen */
194
191
}
195
 
static const char *poly_basis_str(ssize_t n)
 
192
static const char *poly_basis_str(long n)
196
193
{
197
194
  /* return the result for this polynomial term */
198
195
  switch(n) {
220
217
  }
221
218
  return( "UNKNOWN" ); /* should never happen */
222
219
}
223
 
static double poly_basis_dx(ssize_t n, double x, double y)
 
220
static double poly_basis_dx(long n, double x, double y)
224
221
{
225
222
  /* polynomial term for x derivative */
226
223
  switch(n) {
248
245
  }
249
246
  return( 0.0 ); /* should never happen */
250
247
}
251
 
static double poly_basis_dy(ssize_t n, double x, double y)
 
248
static double poly_basis_dy(long n, double x, double y)
252
249
{
253
250
  /* polynomial term for y derivative */
254
251
  switch(n) {
284
281
%  The format of the GenerateCoefficients() method is:
285
282
%
286
283
%    Image *GenerateCoefficients(const Image *image,DistortImageMethod method,
287
 
%        const size_t number_arguments,const double *arguments,
288
 
%        size_t number_values, ExceptionInfo *exception)
 
284
%        const unsigned long number_arguments,const double *arguments,
 
285
%        unsigned long number_values, ExceptionInfo *exception)
289
286
%
290
287
%  A description of each parameter follows:
291
288
%
316
313
*/
317
314
 
318
315
static double *GenerateCoefficients(const Image *image,
319
 
  DistortImageMethod *method,const size_t number_arguments,
320
 
  const double *arguments,size_t number_values,ExceptionInfo *exception)
 
316
  DistortImageMethod *method,const unsigned long number_arguments,
 
317
  const double *arguments,unsigned long number_values,ExceptionInfo *exception)
321
318
{
322
319
  double
323
320
    *coeff;
324
321
 
325
 
  register size_t
 
322
  register unsigned long
326
323
    i;
327
324
 
328
 
  size_t
 
325
  unsigned long
329
326
    number_coeff, /* number of coefficients to return (array size) */
330
327
    cp_size,      /* number floating point numbers per control point */
331
328
    cp_x,cp_y,    /* the x,y indexes for control point */
353
350
  /* If not enough control point pairs are found for specific distortions
354
351
    fall back to Affine distortion (allowing 0 to 3 point pairs)
355
352
  */
356
 
  if ( number_arguments < 4*cp_size &&
 
353
  if ( number_arguments < 4*cp_size && 
357
354
       (  *method == BilinearForwardDistortion
358
355
       || *method == BilinearReverseDistortion
359
356
       || *method == PerspectiveDistortion
385
382
      }
386
383
      if ( number_arguments < 1+i*cp_size ) {
387
384
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
388
 
               "InvalidArgument", "%s : 'require at least %.20g CPs'",
389
 
               "Polynomial", (double) i);
 
385
               "InvalidArgument", "%s : 'require at least %ld CPs'",
 
386
               "Polynomial", i);
390
387
        return((double *) NULL);
391
388
      }
392
389
      break;
463
460
      if ( number_arguments%cp_size != 0 ||
464
461
           number_arguments < cp_size ) {
465
462
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
466
 
               "InvalidArgument", "%s : 'require at least %.20g CPs'",
467
 
               "Affine", 1.0);
 
463
               "InvalidArgument", "%s : 'require at least %ld CPs'",
 
464
               "Affine", 1L);
468
465
        coeff=(double *) RelinquishMagickMemory(coeff);
469
466
        return((double *) NULL);
470
467
      }
551
548
        if ( status == MagickFalse ) {
552
549
          coeff = (double *) RelinquishMagickMemory(coeff);
553
550
          (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
554
 
              "InvalidArgument","%s : 'Unsolvable Matrix'",
555
 
              MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
551
                      "InvalidArgument","%s : '%s'","Affine",
 
552
                      "Unsolvable Matrix");
556
553
          return((double *) NULL);
557
554
        }
558
555
      }
577
574
      if (number_arguments != 6) {
578
575
        coeff = (double *) RelinquishMagickMemory(coeff);
579
576
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
580
 
              "InvalidArgument","%s : 'Needs 6 coeff values'",
581
 
              MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
577
                     "InvalidArgument","%s : '%s'","AffineProjection",
 
578
                     "Needs 6 coeff values");
582
579
        return((double *) NULL);
583
580
      }
584
581
      /* FUTURE: trap test for sx*sy-rx*ry == 0 (determinate = 0, no inverse) */
626
623
      case 0:
627
624
        coeff = (double *) RelinquishMagickMemory(coeff);
628
625
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
629
 
              "InvalidArgument","%s : 'Needs at least 1 argument'",
630
 
              MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
626
                     "InvalidArgument","%s : '%s'", "ScaleTranslateRotate",
 
627
                     "Needs at least 1 argument");
631
628
        return((double *) NULL);
632
629
      case 1:
633
630
        a = arguments[0];
668
665
        default:
669
666
          coeff = (double *) RelinquishMagickMemory(coeff);
670
667
          (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
671
 
              "InvalidArgument","%s : 'Too Many Arguments (7 or less)'",
672
 
              MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
668
                     "InvalidArgument","%s : '%s'", "ScaleTranslateRotate",
 
669
                     "Too Many Arguments (7 or less)");
673
670
          return((double *) NULL);
674
671
        }
675
672
        break;
678
675
      if ( fabs(sx) < MagickEpsilon || fabs(sy) < MagickEpsilon ) {
679
676
        coeff = (double *) RelinquishMagickMemory(coeff);
680
677
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
681
 
              "InvalidArgument","%s : 'Zero Scale Given'",
682
 
              MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
678
                     "InvalidArgument","%s : '%s'", "ScaleTranslateRotate",
 
679
                     "Zero Scale Given");
683
680
        return((double *) NULL);
684
681
      }
685
682
      /* Save the given arguments as an affine distortion */
730
727
        *vectors[1],
731
728
        terms[8];
732
729
 
733
 
      size_t
 
730
      unsigned long
734
731
        cp_u = cp_values,
735
732
        cp_v = cp_values+1;
736
733
 
740
737
      if ( number_arguments%cp_size != 0 ||
741
738
           number_arguments < cp_size*4 ) {
742
739
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
743
 
              "InvalidArgument", "%s : 'require at least %.20g CPs'",
744
 
              MagickOptionToMnemonic(MagickDistortOptions, *method), 4.0);
 
740
               "InvalidArgument", "%s : 'require at least %ld CPs'",
 
741
               "Perspective", 4L);
745
742
        coeff=(double *) RelinquishMagickMemory(coeff);
746
743
        return((double *) NULL);
747
744
      }
785
782
      if ( status == MagickFalse ) {
786
783
        coeff = (double *) RelinquishMagickMemory(coeff);
787
784
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
788
 
            "InvalidArgument","%s : 'Unsolvable Matrix'",
789
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
785
                    "InvalidArgument","%s : '%s'","Perspective",
 
786
                    "Unsolvable Matrix");
790
787
        return((double *) NULL);
791
788
      }
792
789
      /*
808
805
      */
809
806
      if (number_arguments != 8) {
810
807
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
811
 
              "InvalidArgument", "%s : 'Needs 8 coefficient values'",
812
 
              MagickOptionToMnemonic(MagickDistortOptions, *method));
 
808
                     "InvalidArgument","%s : '%s'","PerspectiveProjection",
 
809
                     "Needs 8 coefficient values");
813
810
        return((double *) NULL);
814
811
      }
815
812
      /* FUTURE: trap test  c0*c4-c3*c1 == 0  (determinate = 0, no inverse) */
856
853
      if ( number_arguments%cp_size != 0 ||
857
854
           number_arguments < cp_size*4 ) {
858
855
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
859
 
              "InvalidArgument", "%s : 'require at least %.20g CPs'",
860
 
              MagickOptionToMnemonic(MagickDistortOptions, *method), 4.0);
 
856
               "InvalidArgument", "%s : 'require at least %ld CPs'",
 
857
               *method == BilinearForwardDistortion ? "BilinearForward" :
 
858
               "BilinearReverse", 4L);
861
859
        coeff=(double *) RelinquishMagickMemory(coeff);
862
860
        return((double *) NULL);
863
861
      }
893
891
      if ( status == MagickFalse ) {
894
892
        coeff = (double *) RelinquishMagickMemory(coeff);
895
893
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
896
 
            "InvalidArgument","%s : 'Unsolvable Matrix'",
897
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
894
                     "InvalidArgument","%s : '%s'",
 
895
                     *method == BilinearForwardDistortion ?
 
896
                                "BilinearForward" : "BilinearReverse",
 
897
                     "Unsolvable Matrix");
898
898
        return((double *) NULL);
899
899
      }
900
900
      if ( *method == BilinearForwardDistortion ) {
906
906
            i = c0*x + c1*y + c2*x*y + c3;
907
907
            j = c4*x + c5*y + c6*x*y + c7;
908
908
 
909
 
         where i,j are in the destination image, NOT the source.
 
909
         where u,v are in the destination image, NOT the source.
910
910
 
911
911
         Reverse Pixel mapping however needs to use reverse of these
912
912
         functions.  It required a full page of algbra to work out the
987
987
        **vectors,
988
988
        *terms;
989
989
 
990
 
      size_t
 
990
      unsigned long
991
991
        nterms;   /* number of polynomial terms per number_values */
992
992
 
993
 
      register ssize_t
 
993
      register long
994
994
        j;
995
995
 
996
996
      MagickBooleanType
999
999
      /* first two coefficients hold polynomial order information */
1000
1000
      coeff[0] = arguments[0];
1001
1001
      coeff[1] = (double) poly_number_terms(arguments[0]);
1002
 
      nterms = (size_t) coeff[1];
 
1002
      nterms = (unsigned long) coeff[1];
1003
1003
 
1004
1004
      /* create matrix, a fake vectors matrix, and least sqs terms */
1005
1005
      matrix = AcquireMagickMatrix(nterms,nterms);
1023
1023
        vectors[i] = &(coeff[2+i*nterms]);
1024
1024
      /* Add given control point pairs for least squares solving */
1025
1025
      for (i=1; i < number_arguments; i+=cp_size) { /* NB: start = 1 not 0 */
1026
 
        for (j=0; j < (ssize_t) nterms; j++)
 
1026
        for (j=0; j < (long) nterms; j++)
1027
1027
          terms[j] = poly_basis_fn(j,arguments[i+cp_x],arguments[i+cp_y]);
1028
1028
        LeastSquaresAddTerms(matrix,vectors,terms,
1029
1029
             &(arguments[i+cp_values]),nterms,number_values);
1036
1036
      if ( status == MagickFalse ) {
1037
1037
        coeff = (double *) RelinquishMagickMemory(coeff);
1038
1038
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1039
 
            "InvalidArgument","%s : 'Unsolvable Matrix'",
1040
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
1039
                     "InvalidArgument","%s : '%s'","Polynomial",
 
1040
                     "Unsolvable Matrix");
1041
1041
        return((double *) NULL);
1042
1042
      }
1043
1043
      return(coeff);
1081
1081
      if ( number_arguments >= 1 && arguments[0] < MagickEpsilon ) {
1082
1082
        coeff = (double *) RelinquishMagickMemory(coeff);
1083
1083
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1084
 
            "InvalidArgument","%s : 'Arc Angle Too Small'",
1085
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
1084
                     "InvalidArgument","%s : '%s'", "Arc",
 
1085
                     "Arc Angle Too Small");
1086
1086
        return((double *) NULL);
1087
1087
      }
1088
1088
      if ( number_arguments >= 3 && arguments[2] < MagickEpsilon ) {
1089
1089
        coeff = (double *) RelinquishMagickMemory(coeff);
1090
1090
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1091
 
            "InvalidArgument","%s : 'Outer Radius Too Small'",
1092
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
1091
                     "InvalidArgument","%s : '%s'", "Arc",
 
1092
                     "Outer Radius Too Small");
1093
1093
        return((double *) NULL);
1094
1094
      }
1095
1095
      coeff[0] = -MagickPI2;   /* -90, place at top! */
1131
1131
      if ( number_arguments == 3
1132
1132
          || ( number_arguments > 6 && *method == PolarDistortion )
1133
1133
          || number_arguments > 8 ) {
1134
 
          (void) ThrowMagickException(exception,GetMagickModule(),
1135
 
            OptionError,"InvalidArgument", "%s : number of arguments",
1136
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
1134
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
 
1135
               "InvalidArgument", "%s : number of arguments",
 
1136
               *method == PolarDistortion ? "Polar" : "DePolar");
1137
1137
        coeff=(double *) RelinquishMagickMemory(coeff);
1138
1138
        return((double *) NULL);
1139
1139
      }
1192
1192
      if ( coeff[0] < MagickEpsilon || coeff[1] < -MagickEpsilon
1193
1193
           || (coeff[0]-coeff[1]) < MagickEpsilon ) {
1194
1194
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1195
 
            "InvalidArgument", "%s : Invalid Radius",
1196
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
 
1195
               "InvalidArgument", "%s : Invalid Radius",
 
1196
               *method == PolarDistortion ? "Polar" : "DePolar");
1197
1197
        coeff=(double *) RelinquishMagickMemory(coeff);
1198
1198
        return((double *) NULL);
1199
1199
      }
1217
1217
           Rs=Rd/(A*Rd^3 + B*Rd^2 + C*Rd + D)
1218
1218
 
1219
1219
        Where Rd is the normalized radius from corner to middle of image
1220
 
        Input Arguments are one of the following forms (number of arguments)...
1221
 
            3:  A,B,C
1222
 
            4:  A,B,C,D
1223
 
            5:  A,B,C    X,Y
1224
 
            6:  A,B,C,D  X,Y
1225
 
            8:  Ax,Bx,Cx,Dx  Ay,By,Cy,Dy
1226
 
           10:  Ax,Bx,Cx,Dx  Ay,By,Cy,Dy   X,Y
 
1220
        Input Arguments are one of the following forms...
 
1221
             A,B,C
 
1222
             A,B,C,D
 
1223
             A,B,C    X,Y
 
1224
             A,B,C,D  X,Y
 
1225
             Ax,Bx,Cx,Dx  Ay,By,Cy,Dy
 
1226
             Ax,Bx,Cx,Dx  Ay,By,Cy,Dy   X,Y
1227
1227
 
1228
1228
        Returns 10 coefficent values, which are de-normalized (pixel scale)
1229
1229
          Ax, Bx, Cx, Dx,   Ay, By, Cy, Dy,    Xc, Yc
1232
1232
      double
1233
1233
        rscale = 2.0/MagickMin((double) image->columns,(double) image->rows);
1234
1234
 
1235
 
      /* sanity check  number of args must = 3,4,5,6,8,10 or error */
1236
 
      if ( (number_arguments  < 3) || (number_arguments == 7) ||
1237
 
           (number_arguments == 9) || (number_arguments > 10) )
1238
 
        {
1239
 
          coeff=(double *) RelinquishMagickMemory(coeff);
1240
 
          (void) ThrowMagickException(exception,GetMagickModule(),
1241
 
            OptionError,"InvalidArgument", "%s : number of arguments",
1242
 
            MagickOptionToMnemonic(MagickDistortOptions, *method) );
1243
 
          return((double *) NULL);
1244
 
        }
 
1235
      if ( number_arguments != 4 && number_arguments != 6 &&
 
1236
           number_arguments != 8 && number_arguments != 10 ) {
 
1237
        coeff=(double *) RelinquishMagickMemory(coeff);
 
1238
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
 
1239
               "InvalidArgument", "%s : '%s'", "Barrel(Inv)",
 
1240
               "number of arguments" );
 
1241
        return((double *) NULL);
 
1242
      }
1245
1243
      /* A,B,C,D coefficients */
1246
1244
      coeff[0] = arguments[0];
1247
1245
      coeff[1] = arguments[1];
1248
1246
      coeff[2] = arguments[2];
1249
 
      if ((number_arguments == 3) || (number_arguments == 5) )
1250
 
        coeff[3] = 1.0 - coeff[0] - coeff[1] - coeff[2];
 
1247
      if ( number_arguments == 3 || number_arguments == 5 )
 
1248
        coeff[3] = 1 - arguments[0] - arguments[1] - arguments[2];
1251
1249
      else
1252
 
        coeff[3] = arguments[3];
1253
 
      /* de-normalize the coefficients */
 
1250
         coeff[3] = arguments[3];
 
1251
      /* de-normalize the X coefficients */
1254
1252
      coeff[0] *= pow(rscale,3.0);
1255
1253
      coeff[1] *= rscale*rscale;
1256
1254
      coeff[2] *= rscale;
1257
 
      /* Y coefficients: as given OR same as X coefficients */
 
1255
      /* Y coefficients: as given OR as X coefficients */
1258
1256
      if ( number_arguments >= 8 ) {
1259
1257
        coeff[4] = arguments[4] * pow(rscale,3.0);
1260
1258
        coeff[5] = arguments[5] * rscale*rscale;
1267
1265
        coeff[6] = coeff[2];
1268
1266
        coeff[7] = coeff[3];
1269
1267
      }
1270
 
      /* X,Y Center of Distortion (image coodinates) */
 
1268
      /* X,Y Center of Distortion */
 
1269
      coeff[8] = ((double)image->columns-1)/2.0 + image->page.x;
 
1270
      coeff[9] = ((double)image->rows-1)/2.0    + image->page.y;
1271
1271
      if ( number_arguments == 5 )  {
1272
1272
        coeff[8] = arguments[3];
1273
1273
        coeff[9] = arguments[4];
1274
1274
      }
1275
 
      else if ( number_arguments == 6 ) {
 
1275
      if ( number_arguments == 6 ) {
1276
1276
        coeff[8] = arguments[4];
1277
1277
        coeff[9] = arguments[5];
1278
1278
      }
1279
 
      else if ( number_arguments == 10 ) {
 
1279
      if ( number_arguments == 10 ) {
1280
1280
        coeff[8] = arguments[8];
1281
1281
        coeff[9] = arguments[9];
1282
1282
      }
1283
 
      else {
1284
 
        /* center of the image provided (image coodinates) */
1285
 
        coeff[8] = (double)image->columns/2.0 + image->page.x;
1286
 
        coeff[9] = (double)image->rows/2.0    + image->page.y;
1287
 
      }
1288
1283
      return(coeff);
1289
1284
    }
1290
1285
    case ShepardsDistortion:
1298
1293
      if ( number_arguments%cp_size != 0 ||
1299
1294
           number_arguments < cp_size ) {
1300
1295
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1301
 
              "InvalidArgument", "%s : 'require at least %.20g CPs'",
1302
 
              MagickOptionToMnemonic(MagickDistortOptions, *method), 1.0);
 
1296
               "InvalidArgument", "%s : 'require at least %ld CPs'",
 
1297
               "Shepards", 1UL);
1303
1298
        coeff=(double *) RelinquishMagickMemory(coeff);
1304
1299
        return((double *) NULL);
1305
1300
      }
1341
1336
%  The format of the DistortImage() method is:
1342
1337
%
1343
1338
%      Image *DistortImage(const Image *image,const DistortImageMethod method,
1344
 
%        const size_t number_arguments,const double *arguments,
 
1339
%        const unsigned long number_arguments,const double *arguments,
1345
1340
%        MagickBooleanType bestfit, ExceptionInfo *exception)
1346
1341
%
1347
1342
%  A description of each parameter follows:
1402
1397
%
1403
1398
*/
1404
1399
MagickExport Image *DistortImage(const Image *image,DistortImageMethod method,
1405
 
  const size_t number_arguments,const double *arguments,
 
1400
  const unsigned long number_arguments,const double *arguments,
1406
1401
  MagickBooleanType bestfit,ExceptionInfo *exception)
1407
1402
{
1408
1403
#define DistortImageTag  "Distort/Image"
1589
1584
        /* direct calculation as it needs to tile correctly
1590
1585
         * for reversibility in a DePolar-Polar cycle */
1591
1586
        geometry.x = geometry.y = 0;
1592
 
        geometry.height = (size_t) ceil(coeff[0]-coeff[1]);
1593
 
        geometry.width = (size_t)
 
1587
        geometry.height = (unsigned long) ceil(coeff[0]-coeff[1]);
 
1588
        geometry.width = (unsigned long)
1594
1589
                  ceil((coeff[0]-coeff[1])*(coeff[5]-coeff[4])*0.5);
1595
1590
        break;
1596
1591
      }
1608
1603
        bestfit = MagickFalse;
1609
1604
        break;
1610
1605
    }
1611
 
 
1612
 
    /* Set the output image geometry to calculated 'bestfit'.
1613
 
       Yes this tends to 'over do' the file image size, ON PURPOSE!
1614
 
       Do not do this for DePolar which needs to be exact for virtual tiling.
 
1606
    /* Set the output image geometry to calculated 'bestfit'
 
1607
       Do not do this for DePolar which needs to be exact for tiling
1615
1608
    */
1616
1609
    if ( bestfit && method != DePolarDistortion ) {
1617
 
      geometry.x = (ssize_t) floor(min.x-0.5);
1618
 
      geometry.y = (ssize_t) floor(min.y-0.5);
1619
 
      geometry.width=(size_t) ceil(max.x-geometry.x+0.5);
1620
 
      geometry.height=(size_t) ceil(max.y-geometry.y+0.5);
 
1610
      geometry.x = (long) floor(min.x-0.5);
 
1611
      geometry.y = (long) floor(min.y-0.5);
 
1612
      geometry.width=(unsigned long) ceil(max.x-geometry.x+0.5);
 
1613
      geometry.height=(unsigned long) ceil(max.y-geometry.y+0.5);
1621
1614
    }
1622
 
 
1623
 
    /* Now that we have a new size lets some distortions to it exactly
1624
 
       This is for correct handling of Depolar and its virtual tile handling
1625
 
     */
 
1615
    /* now that we have a new size lets fit distortion to it exactly */
1626
1616
    if ( method == DePolarDistortion ) {
1627
1617
      coeff[6]=(coeff[5]-coeff[4])/geometry.width; /* changed width */
1628
1618
      coeff[7]=(coeff[0]-coeff[1])/geometry.height; /* should be about 1.0 */
1643
1633
 
1644
1634
  /* Verbose output */
1645
1635
  if ( GetImageArtifact(image,"verbose") != (const char *) NULL ) {
1646
 
    register ssize_t
 
1636
    register long
1647
1637
       i;
1648
1638
    char image_gen[MaxTextExtent];
1649
1639
    const char *lookup;
1650
1640
 
1651
1641
    /* Set destination image size and virtual offset */
1652
1642
    if ( bestfit || viewport_given ) {
1653
 
      (void) FormatMagickString(image_gen, MaxTextExtent,"  -size %.20gx%.20g "
1654
 
        "-page %+.20gx%+.20g xc: +insert \\\n",(double) geometry.width,
1655
 
        (double) geometry.height,(double) geometry.x,(double) geometry.y);
 
1643
      (void) FormatMagickString(image_gen, MaxTextExtent,"  -size %lux%lu "
 
1644
        "-page %+ld%+ld xc: +insert \\\n",geometry.width,geometry.height,
 
1645
        geometry.x,geometry.y);
1656
1646
      lookup="v.p{ xx-v.page.x-.5, yy-v.page.x-.5 }";
1657
1647
    }
1658
1648
    else {
1787
1777
 
1788
1778
      case PolynomialDistortion:
1789
1779
      {
1790
 
        size_t nterms = (size_t) coeff[1];
 
1780
        unsigned long nterms = (unsigned long) coeff[1];
1791
1781
        fprintf(stderr, "Polynomial (order %lg, terms %lu), FX Equivelent\n",
1792
 
          coeff[0],(unsigned long) nterms);
 
1782
                       coeff[0], nterms);
1793
1783
        fprintf(stderr, "%s", image_gen);
1794
1784
        fprintf(stderr, "  -fx 'ii=i+page.x+0.5; jj=j+page.y+0.5;\n");
1795
1785
        fprintf(stderr, "       xx =");
1796
 
        for (i=0; i<(ssize_t) nterms; i++) {
 
1786
        for (i=0; i<(long) nterms; i++) {
1797
1787
          if ( i != 0 && i%4 == 0 ) fprintf(stderr, "\n         ");
1798
1788
          fprintf(stderr, " %+lf%s", coeff[2+i],
1799
1789
               poly_basis_str(i));
1800
1790
        }
1801
1791
        fprintf(stderr, ";\n       yy =");
1802
 
        for (i=0; i<(ssize_t) nterms; i++) {
 
1792
        for (i=0; i<(long) nterms; i++) {
1803
1793
          if ( i != 0 && i%4 == 0 ) fprintf(stderr, "\n         ");
1804
1794
          fprintf(stderr, " %+lf%s", coeff[2+i+nterms],
1805
1795
               poly_basis_str(i));
1811
1801
      {
1812
1802
        fprintf(stderr, "Arc Distort, Internal Coefficients:\n");
1813
1803
        for ( i=0; i<5; i++ )
1814
 
          fprintf(stderr, "  c%.20g = %+lf\n", (double) i, coeff[i]);
 
1804
          fprintf(stderr, "  c%ld = %+lf\n", i, coeff[i]);
1815
1805
        fprintf(stderr, "Arc Distort, FX Equivelent:\n");
1816
1806
        fprintf(stderr, "%s", image_gen);
1817
1807
        fprintf(stderr, "  -fx 'ii=i+page.x; jj=j+page.y;\n");
1829
1819
      {
1830
1820
        fprintf(stderr, "Polar Distort, Internal Coefficents\n");
1831
1821
        for ( i=0; i<8; i++ )
1832
 
          fprintf(stderr, "  c%.20g = %+lf\n", (double) i, coeff[i]);
 
1822
          fprintf(stderr, "  c%ld = %+lf\n", i, coeff[i]);
1833
1823
        fprintf(stderr, "Polar Distort, FX Equivelent:\n");
1834
1824
        fprintf(stderr, "%s", image_gen);
1835
1825
        fprintf(stderr, "  -fx 'ii=i+page.x%+lf; jj=j+page.y%+lf;\n",
1848
1838
      {
1849
1839
        fprintf(stderr, "DePolar Distort, Internal Coefficents\n");
1850
1840
        for ( i=0; i<8; i++ )
1851
 
          fprintf(stderr, "  c%.20g = %+lf\n", (double) i, coeff[i]);
 
1841
          fprintf(stderr, "  c%ld = %+lf\n", i, coeff[i]);
1852
1842
        fprintf(stderr, "DePolar Distort, FX Equivelent:\n");
1853
1843
        fprintf(stderr, "%s", image_gen);
1854
1844
        fprintf(stderr, "  -fx 'aa=(i+.5)*%lf %+lf;\n", coeff[6], -coeff[4] );
1861
1851
      case BarrelDistortion:
1862
1852
      case BarrelInverseDistortion:
1863
1853
      { double xc,yc;
1864
 
        /* NOTE: This does the barrel roll in pixel coords not image coords
1865
 
        ** The internal distortion must do it in image coordinates,
1866
 
        ** so that is what the center coeff (8,9) is given in.
1867
 
        */
1868
1854
        xc = ((double)image->columns-1.0)/2.0 + image->page.x;
1869
1855
        yc = ((double)image->rows-1.0)/2.0    + image->page.y;
1870
1856
        fprintf(stderr, "Barrel%s Distort, FX Equivelent:\n",
1871
1857
             method == BarrelDistortion ? "" : "Inv");
1872
1858
        fprintf(stderr, "%s", image_gen);
1873
 
        if ( fabs(coeff[8]-xc-0.5) < 0.1 && fabs(coeff[9]-yc-0.5) < 0.1 )
 
1859
        if ( fabs(coeff[8]-xc) < 0.1 && fabs(coeff[9]-yc) < 0.1 )
1874
1860
          fprintf(stderr, "  -fx 'xc=(w-1)/2;  yc=(h-1)/2;\n");
1875
1861
        else
1876
1862
          fprintf(stderr, "  -fx 'xc=%lf;  yc=%lf;\n",
1877
 
               coeff[8]-0.5, coeff[9]-0.5);
 
1863
               coeff[8], coeff[9]);
1878
1864
        fprintf(stderr,
1879
1865
             "       ii=i-xc;  jj=j-yc;  rr=hypot(ii,jj);\n");
1880
1866
        fprintf(stderr, "       ii=ii%s(%lf*rr*rr*rr %+lf*rr*rr %+lf*rr %+lf);\n",
1939
1925
  { /* ----- MAIN CODE -----
1940
1926
       Sample the source image to each pixel in the distort image.
1941
1927
     */
1942
 
    CacheView
1943
 
      *distort_view;
1944
 
 
1945
 
    MagickBooleanType
 
1928
    long
 
1929
      j,
 
1930
      progress,
1946
1931
      status;
1947
1932
 
1948
 
    MagickOffsetType
1949
 
      progress;
1950
 
 
1951
1933
    MagickPixelPacket
1952
1934
      zero;
1953
1935
 
1954
1936
    ResampleFilter
1955
1937
      **restrict resample_filter;
1956
1938
 
1957
 
    ssize_t
1958
 
      j;
 
1939
    CacheView
 
1940
      *distort_view;
1959
1941
 
1960
1942
    status=MagickTrue;
1961
1943
    progress=0;
1966
1948
#if defined(MAGICKCORE_OPENMP_SUPPORT)
1967
1949
  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
1968
1950
#endif
1969
 
    for (j=0; j < (ssize_t) distort_image->rows; j++)
 
1951
    for (j=0; j < (long) distort_image->rows; j++)
1970
1952
    {
1971
1953
      double
1972
1954
        validity;  /* how mathematically valid is this the mapping */
1985
1967
      register IndexPacket
1986
1968
        *restrict indexes;
1987
1969
 
1988
 
      register ssize_t
 
1970
      register long
1989
1971
        i,
1990
1972
        id;
1991
1973
 
2030
2012
      if (distort_image->colorspace == CMYKColorspace)
2031
2013
        ConvertRGBToCMYK(&invalid);   /* what about other color spaces? */
2032
2014
 
2033
 
      for (i=0; i < (ssize_t) distort_image->columns; i++)
 
2015
      for (i=0; i < (long) distort_image->columns; i++)
2034
2016
      {
2035
2017
        /* map pixel coordinate to distortion space coordinate */
2036
2018
        d.x = (double) (geometry.x+i+0.5)*output_scaling;
2134
2116
          case PolynomialDistortion:
2135
2117
          {
2136
2118
            /* multi-ordered polynomial */
2137
 
            register ssize_t
 
2119
            register long
2138
2120
              k;
2139
 
            ssize_t
2140
 
              nterms=(ssize_t)coeff[1];
 
2121
            long
 
2122
              nterms=(long)coeff[1];
2141
2123
 
2142
2124
            PointInfo
2143
2125
              du,dv; /* the du,dv vectors from unit dx,dy -- derivatives */
2231
2213
                fx = 1/fx;  fy = 1/fy;
2232
2214
                gx *= -fx*fx;  gy *= -fy*fy;
2233
2215
              }
2234
 
              /* Set the source pixel to lookup and EWA derivative vectors */
 
2216
              /* Set source pixel and EWA derivative vectors */
2235
2217
              s.x = d.x*fx + coeff[8];
2236
2218
              s.y = d.y*fy + coeff[9];
2237
2219
              ScaleFilter( resample_filter[id],
2238
2220
                  gx*d.x*d.x + fx, gx*d.x*d.y,
2239
2221
                  gy*d.x*d.y,      gy*d.y*d.y + fy );
2240
2222
            }
2241
 
            else {
2242
 
              /* Special handling to avoid divide by zero when r==0
2243
 
              **
2244
 
              ** The source and destination pixels match in this case
2245
 
              ** which was set at the top of the loop using  s = d;
2246
 
              ** otherwise...   s.x=coeff[8]; s.y=coeff[9];
2247
 
              */
 
2223
            else { /* Special handling to avoid divide by zero when r=0 */
 
2224
              s.x=s.y=0.0;
2248
2225
              if ( method == BarrelDistortion )
2249
2226
                ScaleFilter( resample_filter[id],
2250
2227
                     coeff[3], 0, 0, coeff[7] );
2262
2239
              This is more of a 'displacement' function rather than an
2263
2240
              absolute distortion function.
2264
2241
            */
2265
 
            size_t
 
2242
            unsigned long
2266
2243
              i;
2267
2244
            double
2268
2245
              denominator;
2375
2352
%  The format of the SparseColorImage() method is:
2376
2353
%
2377
2354
%      Image *SparseColorImage(const Image *image,const ChannelType channel,
2378
 
%        const SparseColorMethod method,const size_t number_arguments,
 
2355
%        const SparseColorMethod method,const unsigned long number_arguments,
2379
2356
%        const double *arguments,ExceptionInfo *exception)
2380
2357
%
2381
2358
%  A description of each parameter follows:
2402
2379
*/
2403
2380
MagickExport Image *SparseColorImage(const Image *image,
2404
2381
  const ChannelType channel,const SparseColorMethod method,
2405
 
  const size_t number_arguments,const double *arguments,
 
2382
  const unsigned long number_arguments,const double *arguments,
2406
2383
  ExceptionInfo *exception)
2407
2384
{
2408
2385
#define SparseColorTag  "Distort/SparseColor"
2419
2396
  MagickPixelPacket
2420
2397
    zero;
2421
2398
 
2422
 
  size_t
 
2399
  unsigned long
2423
2400
    number_colors;
2424
2401
 
2425
2402
  assert(image != (Image *) NULL);
2453
2430
    switch (method) {
2454
2431
      case BarycentricColorInterpolate:
2455
2432
      {
2456
 
        register ssize_t x=0;
 
2433
        register long x=0;
2457
2434
        fprintf(stderr, "Barycentric Sparse Color:\n");
2458
2435
        if ( channel & RedChannel )
2459
2436
          fprintf(stderr, "  -channel R -fx '%+lf*i %+lf*j %+lf' \\\n",
2474
2451
      }
2475
2452
      case BilinearColorInterpolate:
2476
2453
      {
2477
 
        register ssize_t x=0;
 
2454
        register long x=0;
2478
2455
        fprintf(stderr, "Bilinear Sparse Color\n");
2479
2456
        if ( channel & RedChannel )
2480
2457
          fprintf(stderr, "   -channel R -fx '%+lf*i %+lf*j %+lf*i*j %+lf;\n",
2521
2498
      return((Image *) NULL);
2522
2499
    }
2523
2500
  { /* ----- MAIN CODE ----- */
 
2501
    long
 
2502
      j,
 
2503
      progress;
 
2504
 
 
2505
    MagickBooleanType
 
2506
      status;
 
2507
 
2524
2508
    CacheView
2525
2509
      *sparse_view;
2526
2510
 
2527
 
    MagickBooleanType
2528
 
      status;
2529
 
 
2530
 
    MagickOffsetType
2531
 
      progress;
2532
 
 
2533
 
    ssize_t
2534
 
      j;
2535
 
 
2536
2511
    status=MagickTrue;
2537
2512
    progress=0;
2538
2513
    GetMagickPixelPacket(sparse_image,&zero);
2540
2515
#if defined(MAGICKCORE_OPENMP_SUPPORT)
2541
2516
  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
2542
2517
#endif
2543
 
    for (j=0; j < (ssize_t) sparse_image->rows; j++)
 
2518
    for (j=0; j < (long) sparse_image->rows; j++)
2544
2519
    {
2545
2520
      MagickBooleanType
2546
2521
        sync;
2551
2526
      register IndexPacket
2552
2527
        *restrict indexes;
2553
2528
 
2554
 
      register ssize_t
 
2529
      register long
2555
2530
        i;
2556
2531
 
2557
2532
      register PixelPacket
2567
2542
/* FUTURE: get pixel from source image - so channel can replace parts */
2568
2543
      indexes=GetCacheViewAuthenticIndexQueue(sparse_view);
2569
2544
      pixel=zero;
2570
 
      for (i=0; i < (ssize_t) sparse_image->columns; i++)
 
2545
      for (i=0; i < (long) sparse_image->columns; i++)
2571
2546
      {
2572
2547
        switch (method)
2573
2548
        {
2574
2549
          case BarycentricColorInterpolate:
2575
2550
          {
2576
 
            register ssize_t x=0;
 
2551
            register long x=0;
2577
2552
            if ( channel & RedChannel )
2578
2553
              pixel.red     = coeff[x]*i +coeff[x+1]*j
2579
2554
                              +coeff[x+2], x+=3;
2593
2568
          }
2594
2569
          case BilinearColorInterpolate:
2595
2570
          {
2596
 
            register ssize_t x=0;
 
2571
            register long x=0;
2597
2572
            if ( channel & RedChannel )
2598
2573
              pixel.red     = coeff[x]*i     + coeff[x+1]*j +
2599
2574
                              coeff[x+2]*i*j + coeff[x+3], x+=4;
2614
2589
          case ShepardsColorInterpolate:
2615
2590
          { /* Shepards Method,uses its own input arguments as coefficients.
2616
2591
            */
2617
 
            size_t
 
2592
            unsigned long
2618
2593
              k;
2619
2594
            double
2620
2595
              denominator;
2626
2601
            if ( channel & OpacityChannel ) pixel.opacity = 0.0;
2627
2602
            denominator = 0.0;
2628
2603
            for(k=0; k<number_arguments; k+=2+number_colors) {
2629
 
              register ssize_t x=(ssize_t) k+2;
 
2604
              register long x=(long) k+2;
2630
2605
              double weight =
2631
2606
                  ((double)i-arguments[ k ])*((double)i-arguments[ k ])
2632
2607
                + ((double)j-arguments[k+1])*((double)j-arguments[k+1]);
2656
2631
          case VoronoiColorInterpolate:
2657
2632
          default:
2658
2633
          { /* Just use the closest control point you can find! */
2659
 
            size_t
 
2634
            unsigned long
2660
2635
              k;
2661
2636
            double
2662
2637
              minimum = MagickHuge;
2666
2641
                  ((double)i-arguments[ k ])*((double)i-arguments[ k ])
2667
2642
                + ((double)j-arguments[k+1])*((double)j-arguments[k+1]);
2668
2643
              if ( distance < minimum ) {
2669
 
                register ssize_t x=(ssize_t) k+2;
 
2644
                register long x=(long) k+2;
2670
2645
                if ( channel & RedChannel     ) pixel.red     = arguments[x++];
2671
2646
                if ( channel & GreenChannel   ) pixel.green   = arguments[x++];
2672
2647
                if ( channel & BlueChannel    ) pixel.blue    = arguments[x++];