Exemplo n.º 1
0
mlib_status
mlib_s_conv5x5ext_u16(
	mlib_image *dst,
	const mlib_image *src,
	mlib_s32 dx_l,
	mlib_s32 dx_r,
	mlib_s32 dy_t,
	mlib_s32 dy_b,
	const mlib_s32 *kernel,
	mlib_s32 scale,
	mlib_s32 cmask)
{
	mlib_s32 nchan = mlib_ImageGetChannels(src);
	mlib_s32 amask = (1 << nchan) - 1;
	mlib_s32 chk_flag;

	chk_flag = mlib_ImageConvVersion(5, 5, scale, MLIB_SHORT);

	if (nchan == 1)
		cmask = 1;
	if ((cmask & amask) != amask || scale < 25 || chk_flag != 3) {
		if (chk_flag == 0)
			return (mlib_conv5x5ext_u16(dst, src, dx_l, dx_r,
			    dy_t, dy_b, (void *)kernel, scale, cmask));
		return (mlib_i_conv5x5ext_u16(dst, src, dx_l, dx_r,
		    dy_t, dy_b, (void *)kernel, scale, cmask));
	}

	switch (nchan) {
	case 1:
		return (mlib_s_conv5x5_u16ext_1(dst, src,
			dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask));
	case 2:
		return (mlib_s_conv5x5_u16ext_2(dst, src,
			dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask));
	case 3:
		return (mlib_s_conv5x5_u16ext_3(dst, src,
			dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask));
	case 4:
		return (mlib_s_conv5x5_u16ext_4(dst, src,
			dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask));
	}

	return (MLIB_FAILURE);
}
Exemplo n.º 2
0
mlib_status
mlib_v_conv5x5Index_8_16ext(
    const mlib_image *src,
    mlib_image *dst,
    const mlib_s32 *kern,
    mlib_s32 scale,
    const void *colormap)
{
    if (mlib_ImageConvVersion(5, 5, scale, MLIB_BYTE) == 0)
        return mlib_conv5x5Index_8_16ext(src, dst, kern, scale,
                                         colormap);

    if (mlib_ImageGetLutChannels(colormap) == 3) {
        return mlib_convMxN_Index3_8_16ext(dst, src, 5, 5, 2, 2, 2, 2,
                                           kern, scale, colormap);
    } else {
        return mlib_convMxN_Index4_8_16ext(dst, src, 5, 5, 2, 2, 2, 2,
                                           kern, scale, colormap);
    }
}
Exemplo n.º 3
0
mlib_status
mlib_s_conv2x2Index_8_16nw_(
    const mlib_image *src,
    mlib_image *dst,
    const mlib_s32 *kern,
    mlib_s32 scale,
    const void *colormap)
{
	if (mlib_ImageConvVersion(2, 2, scale, MLIB_BYTE) == 0)
		return mlib_conv2x2Index_8_16nw(src, dst, kern, scale,
		    colormap);

	if (mlib_ImageGetLutChannels(colormap) == 3) {
		return mlib_convMxN_Index3_8_16nw(dst, src, 2, 2, 0, 0, kern,
		    scale, colormap);
	} else {
		return mlib_convMxN_Index4_8_16nw(dst, src, 2, 2, 0, 0, kern,
		    scale, colormap);
	}
}
Exemplo n.º 4
0
mlib_status
mlib_s_conv3x3nw_u16(
    mlib_image *dst,
    mlib_image *src,
    mlib_s32 *kernel,
    mlib_s32 scalef_expon,
    mlib_s32 cmask)
{
	mlib_s32 nchan = mlib_ImageGetChannels(src);
	mlib_s32 amask = (1 << nchan) - 1;
	mlib_s32 chk_flag;

	chk_flag = mlib_ImageConvVersion(3, 3, scalef_expon, MLIB_USHORT);

	if (nchan == 1)
		cmask = 1;
	if ((cmask & amask) != amask || chk_flag != 3) {
		if (chk_flag == 0)
			return mlib_conv3x3nw_u16(dst, src, kernel,
			    scalef_expon, cmask);
		return mlib_i_conv3x3nw_u16(dst, src, kernel, scalef_expon,
		    cmask);
	}

	switch (nchan) {
	case 1:
		return (mlib_s_conv3x3_u16nw_1(dst, src, kernel, scalef_expon));
	case 2:
		return (mlib_s_conv3x3_u16nw_2(dst, src, kernel, scalef_expon));
	case 3:
		return (mlib_s_conv3x3_u16nw_3(dst, src, kernel, scalef_expon));
	case 4:
		return (mlib_s_conv3x3_u16nw_4(dst, src, kernel, scalef_expon));
	}

	return (MLIB_FAILURE);
}
mlib_status mlib_ImageConvKernelConvert(mlib_s32       *ikernel,
                                        mlib_s32       *iscale,
                                        const mlib_d64 *fkernel,
                                        mlib_s32       m,
                                        mlib_s32       n,
                                        mlib_type      type)
{
  mlib_d64 sum_pos, sum_neg, sum, norm, max, f;
  mlib_s32 isum_pos, isum_neg, isum, test;
  mlib_s32 i, scale, scale1, chk_flag;

  if (ikernel == NULL || iscale == NULL || fkernel == NULL || m < 1 || n < 1) {
    return MLIB_FAILURE;
  }

  if ((type == MLIB_BYTE) || (type == MLIB_SHORT) || (type == MLIB_USHORT)) {

    if (type != MLIB_SHORT) {               /* MLIB_BYTE, MLIB_USHORT */
      sum_pos = 0;
      sum_neg = 0;

      for (i = 0; i < m * n; i++) {
        if (fkernel[i] > 0)
          sum_pos += fkernel[i];
        else
          sum_neg -= fkernel[i];
      }

      sum = (sum_pos > sum_neg) ? sum_pos : sum_neg;
      scale = mlib_ilogb(sum);
      scale++;

      scale = 31 - scale;
    }
    else {                                  /* MLIB_SHORT */
      sum = 0;
      max = 0;

      for (i = 0; i < m * n; i++) {
        f = mlib_fabs(fkernel[i]);
        sum += f;
        max = (max > f) ? max : f;
      }

      scale1 = mlib_ilogb(max) + 1;
      scale = mlib_ilogb(sum);
      scale = (scale > scale1) ? scale : scale1;
      scale++;

      scale = 32 - scale;
    }

    if (scale <= 16)
      return MLIB_FAILURE;
    if (scale > 31)
      scale = 31;

    *iscale = scale;

    chk_flag = mlib_ImageConvVersion(m, n, scale, type);

    if (!chk_flag) {
      norm = (1u << scale);
      for (i = 0; i < m * n; i++) {
        CLAMP_S32(ikernel[i], fkernel[i] * norm);
      }

      return MLIB_SUCCESS;
    }

    /* try to round coefficients */
#ifdef __sparc
    scale1 = 16;                            /* shift of coefficients is 16 */
#else

    if (chk_flag == 3)
      scale1 = 16;                          /* MMX */
    else
      scale1 = (type == MLIB_BYTE) ? 8 : 16;
#endif /* __sparc */
    norm = (1u << (scale - scale1));

    for (i = 0; i < m * n; i++) {
      if (fkernel[i] > 0)
        ikernel[i] = (mlib_s32) (fkernel[i] * norm + 0.5);
      else
        ikernel[i] = (mlib_s32) (fkernel[i] * norm - 0.5);
    }

    isum_pos = 0;
    isum_neg = 0;
    test = 0;

    for (i = 0; i < m * n; i++) {
      if (ikernel[i] > 0)
        isum_pos += ikernel[i];
      else
        isum_neg -= ikernel[i];
    }

    if (type == MLIB_BYTE || type == MLIB_USHORT) {
      isum = (isum_pos > isum_neg) ? isum_pos : isum_neg;

      if (isum >= (1 << (31 - scale1)))
        test = 1;
    }
    else {
      isum = isum_pos + isum_neg;

      if (isum >= (1 << (32 - scale1)))
        test = 1;
      for (i = 0; i < m * n; i++) {
        if (abs(ikernel[i]) >= (1 << (31 - scale1)))
          test = 1;
      }
    }

    if (test == 1) {                        /* rounding according scale1 cause overflow, truncate instead of round */
      for (i = 0; i < m * n; i++)
        ikernel[i] = (mlib_s32) (fkernel[i] * norm) << scale1;
    }
    else {                                  /* rounding is Ok */
      for (i = 0; i < m * n; i++)
        ikernel[i] = ikernel[i] << scale1;
    }

    return MLIB_SUCCESS;
  }
  else if ((type == MLIB_INT) || (type == MLIB_BIT)) {
    max = 0;

    for (i = 0; i < m * n; i++) {
      f = mlib_fabs(fkernel[i]);
      max = (max > f) ? max : f;
    }

    scale = mlib_ilogb(max);

    if (scale > 29)
      return MLIB_FAILURE;

    if (scale < -100)
      scale = -100;

    *iscale = 29 - scale;
    scale = 29 - scale;

    norm = 1.0;
    while (scale > 30) {
      norm *= (1 << 30);
      scale -= 30;
    }

    norm *= (1 << scale);

    for (i = 0; i < m * n; i++) {
      if (fkernel[i] > 0) {
        CLAMP_S32(ikernel[i], fkernel[i] * norm + 0.5);
      }
      else {
        CLAMP_S32(ikernel[i], fkernel[i] * norm - 0.5);
      }
    }

    return MLIB_SUCCESS;
  }
  else {
    return MLIB_FAILURE;
  }
}
Exemplo n.º 6
0
mlib_status mlib_ImageConvMxN_f(mlib_image       *dst,
                                const mlib_image *src,
                                const void       *kernel,
                                mlib_s32         m,
                                mlib_s32         n,
                                mlib_s32         dm,
                                mlib_s32         dn,
                                mlib_s32         scale,
                                mlib_s32         cmask,
                                mlib_edge        edge)
{
  mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1];
  mlib_type type;
  mlib_s32 nchan, dx_l, dx_r, dy_t, dy_b;
  mlib_s32 edg_sizes[8];
  mlib_status ret;

  if (m < 1 || n < 1 || dm < 0 || dm > m - 1 || dn < 0 || dn > n - 1)
    return MLIB_FAILURE;

  if (kernel == NULL)
    return MLIB_NULLPOINTER;

  ret =
    mlib_ImageClippingMxN(dst_i, src_i, dst_e, src_e, edg_sizes, dst, src, m, n, dm, dn);

  if (ret != MLIB_SUCCESS)
    return ret;

  nchan = mlib_ImageGetChannels(dst);
  type = mlib_ImageGetType(dst);

  if (nchan == 1)
    cmask = 1;

  if ((cmask & ((1 << nchan) - 1)) == 0)
    return MLIB_SUCCESS;

  dx_l = edg_sizes[0];
  dx_r = edg_sizes[1];
  dy_t = edg_sizes[2];
  dy_b = edg_sizes[3];

  if (dx_l + dx_r + dy_t + dy_b == 0)
    edge = MLIB_EDGE_DST_NO_WRITE;

  if (edge != MLIB_EDGE_SRC_EXTEND) {
    if (mlib_ImageGetWidth(dst_i) >= m && mlib_ImageGetHeight(dst_i) >= n) {
      switch (type) {
        case MLIB_BYTE:
          ret = mlib_convMxNnw_u8(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
          break;
        case MLIB_SHORT:
#ifdef __sparc
          ret = mlib_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
#else

          if (mlib_ImageConvVersion(m, n, scale, type) == 0)
            ret = mlib_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
          else
            ret = mlib_i_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
#endif /* __sparc */
          break;
        case MLIB_USHORT:
#ifdef __sparc
          ret = mlib_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
#else

          if (mlib_ImageConvVersion(m, n, scale, type) == 0)
            ret = mlib_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
          else
            ret = mlib_i_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
#endif /* __sparc */
          break;
        case MLIB_INT:
          ret = mlib_convMxNnw_s32(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);
          break;
        case MLIB_FLOAT:
          ret = mlib_convMxNnw_f32(dst_i, src_i, kernel, m, n, dm, dn, cmask);
          break;
        case MLIB_DOUBLE:
          ret = mlib_convMxNnw_d64(dst_i, src_i, kernel, m, n, dm, dn, cmask);
          break;
      }
    }

    switch (edge) {
      case MLIB_EDGE_DST_FILL_ZERO:
        mlib_ImageConvZeroEdge(dst_e, dx_l, dx_r, dy_t, dy_b, cmask);
        break;
      case MLIB_EDGE_DST_COPY_SRC:
        mlib_ImageConvCopyEdge(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, cmask);
        break;
    }
  }
  else {                                    /* MLIB_EDGE_SRC_EXTEND */
    /* adjust src_e image */
    mlib_ImageSetSubimage(src_e, src_e, dx_l - dm, dy_t - dn,
                          mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e));

    switch (type) {
      case MLIB_BYTE:
        ret =
          mlib_convMxNext_u8(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,
                             cmask);
        break;
      case MLIB_SHORT:
#ifdef __sparc
        ret =
          mlib_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,
                              cmask);
#else

        if (mlib_ImageConvVersion(m, n, scale, type) == 0)
          ret =
            mlib_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,
                                cmask);
        else
          ret =
            mlib_i_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b,
                                  scale, cmask);
#endif /* __sparc */
        break;
      case MLIB_USHORT:
#ifdef __sparc
        ret =
          mlib_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,
                              cmask);
#else

        if (mlib_ImageConvVersion(m, n, scale, type) == 0)
          ret =
            mlib_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,
                                cmask);
        else
          ret =
            mlib_i_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b,
                                  scale, cmask);
#endif /* __sparc */
        break;
      case MLIB_INT:
        ret =
          mlib_convMxNext_s32(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,
                              cmask);
        break;
      case MLIB_FLOAT:
        mlib_convMxNext_f32(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, cmask);
        break;
      case MLIB_DOUBLE:
        mlib_convMxNext_d64(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, cmask);
        break;
    }
  }

  return ret;
}