< prev index next >

src/java.desktop/share/native/libmlib_image/mlib_ImageConvKernelConvert.c

Print this page
rev 59106 : imported patch client


  44  *      fkernel  floating-point kernel
  45  *      m        width of the convolution kernel
  46  *      n        height of the convolution kernel
  47  *      type     image type
  48  *
  49  * DESCRIPTION
  50  *      Convert a floating point convolution kernel to integer kernel
  51  *      with scaling factor. The result integer kernel and scaling factor
  52  *      can be used in convolution functions directly without overflow.
  53  *
  54  * RESTRICTION
  55  *      The type can be MLIB_BYTE, MLIB_SHORT, MLIB_USHORT or MLIB_INT.
  56  */
  57 
  58 #include <stdlib.h>
  59 #include "mlib_image.h"
  60 #include "mlib_SysMath.h"
  61 #include "mlib_ImageConv.h"
  62 
  63 /***************************************************************/
  64 #ifdef __sparc
  65 
  66 #define CLAMP_S32(dst, src)                                     \
  67   dst = (mlib_s32)(src)
  68 
  69 #else
  70 
  71 #define CLAMP_S32(dst, src) {                                   \
  72   mlib_d64 s0 = (mlib_d64)(src);                                \
  73   if (s0 > (mlib_d64)MLIB_S32_MAX) s0 = (mlib_d64)MLIB_S32_MAX; \
  74   if (s0 < (mlib_d64)MLIB_S32_MIN) s0 = (mlib_d64)MLIB_S32_MIN; \
  75   dst = (mlib_s32)s0;                                           \
  76 }
  77 
  78 #endif /* __sparc */
  79 
  80 /***************************************************************/
  81 JNIEXPORT
  82 mlib_status mlib_ImageConvKernelConvert(mlib_s32       *ikernel,
  83                                         mlib_s32       *iscale,
  84                                         const mlib_d64 *fkernel,
  85                                         mlib_s32       m,
  86                                         mlib_s32       n,
  87                                         mlib_type      type)
  88 {
  89   mlib_d64 sum_pos, sum_neg, sum, norm, max, f;
  90   mlib_s32 isum_pos, isum_neg, isum, test;
  91   mlib_s32 i, scale, scale1, chk_flag;
  92 
  93   if (ikernel == NULL || iscale == NULL || fkernel == NULL || m < 1 || n < 1) {
  94     return MLIB_FAILURE;
  95   }
  96 
  97   if ((type == MLIB_BYTE) || (type == MLIB_SHORT) || (type == MLIB_USHORT)) {
  98 
  99     if (type != MLIB_SHORT) {               /* MLIB_BYTE, MLIB_USHORT */


 133 
 134     if (scale <= 16)
 135       return MLIB_FAILURE;
 136     if (scale > 31)
 137       scale = 31;
 138 
 139     *iscale = scale;
 140 
 141     chk_flag = mlib_ImageConvVersion(m, n, scale, type);
 142 
 143     if (!chk_flag) {
 144       norm = (1u << scale);
 145       for (i = 0; i < m * n; i++) {
 146         CLAMP_S32(ikernel[i], fkernel[i] * norm);
 147       }
 148 
 149       return MLIB_SUCCESS;
 150     }
 151 
 152     /* try to round coefficients */
 153 #ifdef __sparc
 154     scale1 = 16;                            /* shift of coefficients is 16 */
 155 #else
 156 
 157     if (chk_flag == 3)
 158       scale1 = 16;                          /* MMX */
 159     else
 160       scale1 = (type == MLIB_BYTE) ? 8 : 16;
 161 #endif /* __sparc */
 162     norm = (1u << (scale - scale1));
 163 
 164     for (i = 0; i < m * n; i++) {
 165       if (fkernel[i] > 0)
 166         ikernel[i] = (mlib_s32) (fkernel[i] * norm + 0.5);
 167       else
 168         ikernel[i] = (mlib_s32) (fkernel[i] * norm - 0.5);
 169     }
 170 
 171     isum_pos = 0;
 172     isum_neg = 0;
 173     test = 0;
 174 
 175     for (i = 0; i < m * n; i++) {
 176       if (ikernel[i] > 0)
 177         isum_pos += ikernel[i];
 178       else
 179         isum_neg -= ikernel[i];
 180     }
 181 




  44  *      fkernel  floating-point kernel
  45  *      m        width of the convolution kernel
  46  *      n        height of the convolution kernel
  47  *      type     image type
  48  *
  49  * DESCRIPTION
  50  *      Convert a floating point convolution kernel to integer kernel
  51  *      with scaling factor. The result integer kernel and scaling factor
  52  *      can be used in convolution functions directly without overflow.
  53  *
  54  * RESTRICTION
  55  *      The type can be MLIB_BYTE, MLIB_SHORT, MLIB_USHORT or MLIB_INT.
  56  */
  57 
  58 #include <stdlib.h>
  59 #include "mlib_image.h"
  60 #include "mlib_SysMath.h"
  61 #include "mlib_ImageConv.h"
  62 
  63 /***************************************************************/






  64 
  65 #define CLAMP_S32(dst, src) {                                   \
  66   mlib_d64 s0 = (mlib_d64)(src);                                \
  67   if (s0 > (mlib_d64)MLIB_S32_MAX) s0 = (mlib_d64)MLIB_S32_MAX; \
  68   if (s0 < (mlib_d64)MLIB_S32_MIN) s0 = (mlib_d64)MLIB_S32_MIN; \
  69   dst = (mlib_s32)s0;                                           \
  70 }
  71 


  72 /***************************************************************/
  73 JNIEXPORT
  74 mlib_status mlib_ImageConvKernelConvert(mlib_s32       *ikernel,
  75                                         mlib_s32       *iscale,
  76                                         const mlib_d64 *fkernel,
  77                                         mlib_s32       m,
  78                                         mlib_s32       n,
  79                                         mlib_type      type)
  80 {
  81   mlib_d64 sum_pos, sum_neg, sum, norm, max, f;
  82   mlib_s32 isum_pos, isum_neg, isum, test;
  83   mlib_s32 i, scale, scale1, chk_flag;
  84 
  85   if (ikernel == NULL || iscale == NULL || fkernel == NULL || m < 1 || n < 1) {
  86     return MLIB_FAILURE;
  87   }
  88 
  89   if ((type == MLIB_BYTE) || (type == MLIB_SHORT) || (type == MLIB_USHORT)) {
  90 
  91     if (type != MLIB_SHORT) {               /* MLIB_BYTE, MLIB_USHORT */


 125 
 126     if (scale <= 16)
 127       return MLIB_FAILURE;
 128     if (scale > 31)
 129       scale = 31;
 130 
 131     *iscale = scale;
 132 
 133     chk_flag = mlib_ImageConvVersion(m, n, scale, type);
 134 
 135     if (!chk_flag) {
 136       norm = (1u << scale);
 137       for (i = 0; i < m * n; i++) {
 138         CLAMP_S32(ikernel[i], fkernel[i] * norm);
 139       }
 140 
 141       return MLIB_SUCCESS;
 142     }
 143 
 144     /* try to round coefficients */




 145     if (chk_flag == 3)
 146       scale1 = 16;                          /* MMX */
 147     else
 148       scale1 = (type == MLIB_BYTE) ? 8 : 16;

 149     norm = (1u << (scale - scale1));
 150 
 151     for (i = 0; i < m * n; i++) {
 152       if (fkernel[i] > 0)
 153         ikernel[i] = (mlib_s32) (fkernel[i] * norm + 0.5);
 154       else
 155         ikernel[i] = (mlib_s32) (fkernel[i] * norm - 0.5);
 156     }
 157 
 158     isum_pos = 0;
 159     isum_neg = 0;
 160     test = 0;
 161 
 162     for (i = 0; i < m * n; i++) {
 163       if (ikernel[i] > 0)
 164         isum_pos += ikernel[i];
 165       else
 166         isum_neg -= ikernel[i];
 167     }
 168 


< prev index next >