Changeset 18957
- Timestamp:
- Aug 8, 2008, 8:07:30 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageConvolve.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageConvolve.c
r17810 r18957 7 7 /// @author Eugene Magnier, IfA 8 8 /// 9 /// @version $Revision: 1.7 1$ $Name: not supported by cvs2svn $10 /// @date $Date: 2008-0 5-24 23:01:42$9 /// @version $Revision: 1.72 $ $Name: not supported by cvs2svn $ 10 /// @date $Date: 2008-08-08 18:07:30 $ 11 11 /// 12 12 /// Copyright 2004-2007 Institute for Astronomy, University of Hawaii … … 30 30 #include "psImagePixelManip.h" 31 31 #include "psTrace.h" 32 #include "psThread.h" 32 33 33 34 #include "psImageConvolve.h" … … 757 758 758 759 760 // Convolve mask columns 761 static bool imageConvolveMaskColumns(psImage *target, // Output, convolved image 762 const psImage *input, // Input image 763 int start, int stop, // Range of rows 764 psMaskType maskVal, // Value to mask; NOTE subtle difference! 765 int xMin, int xMax // Range in x for kernel 766 ) 767 { 768 // Dereference mask images 769 psMaskType **inputData = input->data.PS_TYPE_MASK_DATA; 770 psMaskType **targetData = target->data.PS_TYPE_MASK_DATA; 771 772 int numCols = input->numCols; // Number of columns 773 774 for (int y = start; y < stop; y++) { 775 int min = 0, max = 0; // Minimum and maximum points to mask 776 bool masking = false; // Currently masking? 777 for (int x = 0; x < numCols; x++) { 778 if (inputData[y][x] & maskVal) { 779 if (!masking) { 780 masking = true; 781 min = x + xMin; 782 max = x + xMax; 783 } else { 784 max++; 785 } 786 } else if (masking) { 787 // Do the masking 788 masking = false; 789 min = PS_MAX(0, min); 790 max = PS_MIN(numCols - 1, max); 791 memset(&targetData[y][min], 0xff, (max - min + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK)); 792 } 793 } 794 if (masking) { 795 // Mask from the minimum to the end of the row 796 min = PS_MAX(0, min); 797 memset(&targetData[y][min], 0xff, (numCols - min) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK)); 798 } 799 } 800 return true; 801 } 802 803 static bool imageConvolveMaskRows(psImage *target, // Output, convolved image 804 const psImage *input, // Input image 805 int start, int stop, // Range of rows 806 psMaskType setVal, // Value to set; NOTE subtle difference! 807 int yMin, int yMax // Range in y for kernel 808 ) 809 { 810 // Dereference mask images 811 psMaskType **inputData = input->data.PS_TYPE_MASK_DATA; 812 psMaskType **targetData = target->data.PS_TYPE_MASK_DATA; 813 814 int numRows = input->numRows; // Number of rows 815 816 for (int x = start; x < stop; x++) { 817 int min = 0, max = 0; // Minimum and maximum points to mask 818 bool masking = false; // Currently masking? 819 for (int y = 0; y < numRows; y++) { 820 if (inputData[y][x]) { 821 if (!masking) { 822 masking = true; 823 min = y + yMin; 824 max = y + yMax; 825 } else { 826 max++; 827 } 828 } else if (masking) { 829 // Do the masking 830 masking = false; 831 min = PS_MAX(0, min); 832 max = PS_MIN(numRows - 1, max); 833 for (int i = min; i <= max; i++) { 834 targetData[i][x] |= setVal; 835 } 836 } 837 } 838 if (masking) { 839 // Mask from the minimum to the end of the column 840 for (int i = PS_MAX(0, min); i < numRows; i++) { 841 targetData[i][x] |= setVal; 842 } 843 } 844 } 845 return true; 846 } 847 848 static bool imageConvolveMaskThread(const psThreadJob *job) 849 { 850 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 851 852 psArray *args = job->args; // Arguments for job 853 854 psImage *target = args->data[0]; // Output mask image 855 const psImage *input = args->data[1];// Input mask image 856 int start = PS_SCALAR_VALUE(args->data[2], S32); // Row/col to start at 857 int stop = PS_SCALAR_VALUE(args->data[3], S32); // Row/col to stop at 858 psMaskType maskVal = PS_SCALAR_VALUE(args->data[4], U8); // Value to mask/set 859 int kernelMin = PS_SCALAR_VALUE(args->data[5], S32); // Minimum range for kernel 860 int kernelMax = PS_SCALAR_VALUE(args->data[6], S32); // Maximum range for kernel 861 bool row = PS_SCALAR_VALUE(args->data[7], U8); // Do row (true) or column (false)? 862 863 return row ? imageConvolveMaskRows(target, input, start, stop, maskVal, kernelMin, kernelMax) : 864 imageConvolveMaskColumns(target, input, start, stop, maskVal, kernelMin, kernelMax); 865 } 759 866 760 867 … … 792 899 } 793 900 901 static bool threadsInit = false; // Threads initialised? 902 int numThreads = psThreadPoolSize();// Number of threads 903 if (numThreads > 0 && !threadsInit) { 904 psThreadTask *task = psThreadTaskAlloc("PSLIB_IMAGE_CONVOLVE_MASK", 8); 905 task->function = &imageConvolveMaskThread; 906 psThreadTaskAdd(task); 907 psFree(task); 908 threadsInit = true; 909 } 910 794 911 int numRows = mask->numRows; // Number of rows 795 912 int numCols = mask->numCols; // Number of columns … … 805 922 psImageInit(conv, 0); 806 923 807 // Dereference mask images808 psMaskType **maskData = mask->data.PS_TYPE_MASK_DATA;809 psMaskType **convData = conv->data.PS_TYPE_MASK_DATA;810 psMaskType **outData = out->data.PS_TYPE_MASK_DATA;811 812 924 // Since we're just masking everything inside a square, it's separable 925 926 // Rows 927 if (numThreads > 0) { 928 float cols = (float)numCols / (float)numThreads; // Number of cols to do at once 929 for (int i = 0; i < numThreads; i++) { 930 int start = i * cols; // Starting colunms 931 int stop = (i + 1) * cols; // Stopping columns 932 933 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK"); 934 psArrayAdd(job->args, 1, conv); 935 psArrayAdd(job->args, 1, (psImage*)mask); // Casting away const to put on arguments 936 PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32); 937 PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32); 938 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_MASK); 939 PS_ARRAY_ADD_SCALAR(job->args, xMin, PS_TYPE_S32); 940 PS_ARRAY_ADD_SCALAR(job->args, xMax, PS_TYPE_S32); 941 PS_ARRAY_ADD_SCALAR(job->args, 0x00, PS_TYPE_U8); 942 if (!psThreadJobAddPending(job)) { 943 psFree(job); 944 psFree(conv); 945 psFree(out); 946 return NULL; 947 } 948 psFree(job); 949 } 950 } else if (!imageConvolveMaskColumns(conv, mask, 0, numRows, maskVal, xMin, xMax)) { 951 psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask columns."); 952 psFree(conv); 953 psFree(out); 954 return NULL; 955 } 956 957 if (!psThreadPoolWait(true)) { 958 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 959 psFree(conv); 960 psFree(out); 961 return NULL; 962 } 963 964 // Columns 965 if (numThreads > 0) { 966 float cols = (float)numCols / (float)numThreads; // Number of columns to do at once 967 for (int i = 0; i < numThreads; i++) { 968 int start = i * cols; // Starting column 969 int stop = (i + 1) * cols; // Stopping column 970 971 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK"); 972 psArrayAdd(job->args, 1, conv); 973 psArrayAdd(job->args, 1, out); 974 PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32); 975 PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32); 976 PS_ARRAY_ADD_SCALAR(job->args, setVal, PS_TYPE_MASK); 977 PS_ARRAY_ADD_SCALAR(job->args, xMin, PS_TYPE_S32); 978 PS_ARRAY_ADD_SCALAR(job->args, xMax, PS_TYPE_S32); 979 PS_ARRAY_ADD_SCALAR(job->args, 0xff, PS_TYPE_U8); 980 if (!psThreadJobAddPending(job)) { 981 psFree(job); 982 psFree(conv); 983 psFree(out); 984 return NULL; 985 } 986 psFree(job); 987 } 988 } else if (!imageConvolveMaskRows(out, conv, 0, numCols, setVal, yMin, yMax)) { 989 psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask columns."); 990 psFree(conv); 991 psFree(out); 992 return NULL; 993 } 994 995 if (!psThreadPoolWait(true)) { 996 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 997 psFree(conv); 998 psFree(out); 999 return NULL; 1000 } 1001 1002 1003 #if 0 813 1004 for (int y = 0; y < numRows; y++) { 814 1005 int min = 0, max = 0; // Minimum and maximum points to mask … … 866 1057 } 867 1058 } 1059 #endif 868 1060 869 1061 psFree(conv); … … 871 1063 return out; 872 1064 } 1065
Note:
See TracChangeset
for help on using the changeset viewer.
