| | 117 | static ResampleFilter **DestroyResampleFilterThreadSet(ResampleFilter **filter) |
| | 118 | { |
| | 119 | register long |
| | 120 | i; |
| | 121 | |
| | 122 | assert(filter != (ResampleFilter **) NULL); |
| | 123 | for (i=0; i < (long) GetCacheViewMaximumThreads(); i++) |
| | 124 | if (filter[i] != (ResampleFilter *) NULL) |
| | 125 | filter[i]=DestroyResampleFilter(filter[i]); |
| | 126 | return((ResampleFilter **) RelinquishMagickMemory(filter)); |
| | 127 | } |
| | 128 | |
| | 129 | static ResampleFilter **AcquireResampleFilterThreadSet(const Image *image, |
| | 130 | ExceptionInfo *exception) |
| | 131 | { |
| | 132 | register long |
| | 133 | i; |
| | 134 | |
| | 135 | ResampleFilter |
| | 136 | **filter; |
| | 137 | |
| | 138 | filter=(ResampleFilter **) AcquireQuantumMemory(GetCacheViewMaximumThreads(), |
| | 139 | sizeof(*filter)); |
| | 140 | if (filter == (ResampleFilter **) NULL) |
| | 141 | return((ResampleFilter **) NULL); |
| | 142 | (void) ResetMagickMemory(filter,0,GetCacheViewMaximumThreads()* |
| | 143 | sizeof(*filter)); |
| | 144 | for (i=0; i < (long) GetCacheViewMaximumThreads(); i++) |
| | 145 | { |
| | 146 | filter[i]=AcquireResampleFilter(image,exception); |
| | 147 | if (filter[i] == (ResampleFilter *) NULL) |
| | 148 | return(DestroyResampleFilterThreadSet(filter)); |
| | 149 | } |
| | 150 | return(filter); |
| | 151 | } |
| | 152 | |
| 804 | | /* Open Image views as needed. */ |
| 805 | | resample_filter=AcquireResampleFilter(image,exception); |
| 806 | | GetMagickPixelPacket(distort_image,&pixel); |
| 807 | | distort_view=AcquireCacheView(distort_image); |
| 808 | | |
| 809 | | /* Define constant scaling vectors for Affine Distortions */ |
| 810 | | switch (method) |
| 811 | | { |
| 812 | | case AffineDistortion: |
| 813 | | case AffineProjectionDistortion: |
| 814 | | case ScaleRotateTranslateDistortion: |
| 815 | | ScaleResampleFilter( resample_filter, |
| 816 | | coefficients[0], coefficients[2], |
| 817 | | coefficients[1], coefficients[3] ); |
| 818 | | break; |
| 819 | | default: |
| 820 | | break; |
| 821 | | } |
| 822 | | |
| 823 | | /* Initialize default pixel validity |
| 824 | | * negative: pixel is invalid output 'matte_color' |
| 825 | | * 0.0 to 1.0: antialiased, mix with resample output |
| 826 | | * 1.0 or greater: use resampled output. |
| 827 | | */ |
| 828 | | validity = 1.0; |
| 829 | | GetMagickPixelPacket(distort_image,&invalid); |
| 830 | | SetMagickPixelPacket(distort_image, &distort_image->matte_color, |
| 831 | | (IndexPacket *) NULL, &invalid); |
| 832 | | if (distort_image->colorspace == CMYKColorspace) |
| 833 | | ConvertRGBToCMYK(&invalid); /* what about other color spaces? */ |
| 834 | | |
| 838 | | q=SetCacheViewPixels(distort_view,0,j,distort_image->columns,1); |
| | 838 | long |
| | 839 | y; |
| | 840 | |
| | 841 | MagickPixelPacket |
| | 842 | pixel, /* pixel to assign to distorted image */ |
| | 843 | invalid; /* the color to assign when distort result is invalid */ |
| | 844 | |
| | 845 | PointInfo |
| | 846 | point; /* point to sample (center of filtered resample of area) */ |
| | 847 | |
| | 848 | register IndexPacket |
| | 849 | *indexes; |
| | 850 | |
| | 851 | register long |
| | 852 | i, |
| | 853 | id, |
| | 854 | x; |
| | 855 | |
| | 856 | register PixelPacket |
| | 857 | *q; |
| | 858 | |
| | 859 | id=GetCacheViewThreadId(); |
| | 860 | q=SetCacheViewPixels(distort_view[id],0,j,distort_image->columns,1); |
| 840 | | break; |
| 841 | | indexes=GetCacheViewIndexes(distort_view); |
| | 862 | { |
| | 863 | status=MagickFalse; |
| | 864 | continue; |
| | 865 | } |
| | 866 | indexes=GetCacheViewIndexes(distort_view[id]); |
| | 867 | |
| | 868 | GetMagickPixelPacket(distort_image,&pixel); |
| | 869 | |
| | 870 | /* Define constant scaling vectors for Affine Distortions */ |
| | 871 | switch (method) |
| | 872 | { |
| | 873 | case AffineDistortion: |
| | 874 | case AffineProjectionDistortion: |
| | 875 | case ScaleRotateTranslateDistortion: |
| | 876 | ScaleResampleFilter( resample_filter[id], |
| | 877 | coefficients[0], coefficients[2], |
| | 878 | coefficients[1], coefficients[3] ); |
| | 879 | break; |
| | 880 | default: |
| | 881 | break; |
| | 882 | } |
| | 883 | |
| | 884 | /* Initialize default pixel validity |
| | 885 | * negative: pixel is invalid output 'matte_color' |
| | 886 | * 0.0 to 1.0: antialiased, mix with resample output |
| | 887 | * 1.0 or greater: use resampled output. |
| | 888 | */ |
| | 889 | validity = 1.0; |
| | 890 | GetMagickPixelPacket(distort_image,&invalid); |
| | 891 | SetMagickPixelPacket(distort_image,&distort_image->matte_color, |
| | 892 | (IndexPacket *) NULL, &invalid); |
| | 893 | if (distort_image->colorspace == CMYKColorspace) |
| | 894 | ConvertRGBToCMYK(&invalid); /* what about other color spaces? */ |
| | 895 | point.x=0; |
| | 896 | point.y=0; |
| 961 | | if (SyncCacheView(distort_view) == MagickFalse) |
| 962 | | break; |
| 963 | | if ((image->progress_monitor != (MagickProgressMonitor) NULL) && |
| 964 | | (QuantumTick(y,image->rows) != MagickFalse)) |
| 965 | | { |
| 966 | | status=image->progress_monitor(DistortImageTag,y,image->rows, |
| 967 | | image->client_data); |
| 968 | | if (status == MagickFalse) |
| 969 | | break; |
| 970 | | } |
| | 1016 | if (SyncCacheView(distort_view[id]) == MagickFalse) |
| | 1017 | status=MagickFalse; |
| | 1018 | if (SetImageProgress(image,DistortImageTag,y,image->rows) == MagickFalse) |
| | 1019 | status=MagickFalse; |