mlib_status
__mlib_ImageConstNotOr(
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 *c)
{
	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);

	if ((mlib_ImageGetType(src) == MLIB_BYTE) ||
	    (mlib_ImageGetType(src) == MLIB_SHORT) ||
	    (mlib_ImageGetType(src) == MLIB_USHORT) ||
	    mlib_ImageGetType(src) == MLIB_INT) {

		return (mlib_v_ImageConstLogic(dst, src, c));

	} else if (mlib_ImageGetType(src) == MLIB_BIT) {

		if (mlib_ImageGetBitOffset(src) ==
		    mlib_ImageGetBitOffset(dst)) {
			return (mlib_v_ImageConstNotOr_Bit(dst, src, c));
		} else {
			return (mlib_ImageConstNotOr_Bit(dst, src, c));
		}

	} else
		return (MLIB_FAILURE);
}
mlib_status
__mlib_ImageNotAnd(
    mlib_image *dst,
    const mlib_image *src1,
    const mlib_image *src2)
{
    MLIB_IMAGE_CHECK(src1);
    MLIB_IMAGE_CHECK(src2);
    MLIB_IMAGE_CHECK(dst);

    if ((mlib_ImageGetType(src1) == MLIB_BYTE) ||
            (mlib_ImageGetType(src1) == MLIB_SHORT) ||
            (mlib_ImageGetType(src1) == MLIB_USHORT) ||
            mlib_ImageGetType(src1) == MLIB_INT) {

        return (mlib_v_ImageLogic(dst, src1, src2));

    } else if (mlib_ImageGetType(src1) == MLIB_BIT) {

        if ((mlib_ImageGetBitOffset(src1) ==
                mlib_ImageGetBitOffset(dst)) &&
                (mlib_ImageGetBitOffset(src2) ==
                 mlib_ImageGetBitOffset(dst))) {
            return (mlib_v_ImageNotAnd_Bit(dst, src1, src2));
        } else {
            return (mlib_ImageNotAnd_Bit(dst, src1, src2));
        }

    } else
        return (MLIB_FAILURE);
}
mlib_status
__mlib_ImageMinFilter3x3(
    mlib_image *dst,
    const mlib_image *src)
{
	mlib_image dst_i[1], src_i[1];
	mlib_type type;
	mlib_s32 wid, hgt, slb, dlb;
	mlib_status ret;
	void *da, *sa;

	ret = mlib_ImageClipping(dst_i, src_i, NULL, NULL, NULL, dst, src, 3);

	if (ret != MLIB_SUCCESS)
		return (ret);

	MLIB_IMAGE_HAVE_CHAN(dst, 1);

	type = mlib_ImageGetType(dst_i);
	wid = mlib_ImageGetWidth(dst_i);
	hgt = mlib_ImageGetHeight(dst_i);
	dlb = mlib_ImageGetStride(dst_i);
	da = (void *)mlib_ImageGetData(dst_i);

	sa = mlib_ImageGetData(src_i);
	slb = mlib_ImageGetStride(src_i);

	if (wid < 3 || hgt < 3)
		return (MLIB_SUCCESS);

	switch (type) {
	case MLIB_BIT:
		return mlib_ImageMinFilter3x3_BIT(da, sa, dlb, slb, wid, hgt,
		    mlib_ImageGetBitOffset(dst_i),
		    mlib_ImageGetBitOffset(src_i));

	case MLIB_BYTE:
		return (mlib_ImageMinFilter3x3_U8(da, sa, dlb, slb, wid, hgt));

	case MLIB_SHORT:
		return (mlib_ImageMinFilter3x3_S16(da, sa, dlb, slb, wid, hgt));

	case MLIB_USHORT:
		return (mlib_ImageMinFilter3x3_U16(da, sa, dlb, slb, wid, hgt));

	case MLIB_INT:
		return (mlib_ImageMinFilter3x3_S32(da, sa, dlb, slb, wid, hgt));

	default:
		return (MLIB_FAILURE);
	}
}
void mlib_v_ImageClear_BIT_1(mlib_image     *img,
                             const mlib_s32 *color)
{
  mlib_u8 *pimg = (mlib_u8 *) mlib_ImageGetData(img);
  mlib_s32 img_height = mlib_ImageGetHeight(img);
  mlib_s32 img_width = mlib_ImageGetWidth(img);
  mlib_s32 img_stride = mlib_ImageGetStride(img);
  mlib_s32 img_bitoff = mlib_ImageGetBitOffset(img);
  mlib_s32 i, j, b_j, k;
  mlib_u8 bcolor0, bmask, emask, src;
  mlib_d64 dcolor, *dpimg;
  mlib_u32 color0;

  if (img_width == img_stride * 8) {
    img_width *= img_height;
    img_height = 1;
  }

  color0 = ((color[0] & 1) << 31) >> 31;
  bcolor0 = color0 & 0xFF;

  dcolor = vis_to_double_dup(color0);
  for (i = 0, j = 0; i < img_height; i++) {
    mlib_u8 *pimg_row = pimg + i * img_stride, *pimg_row_end;

    if (img_bitoff + img_width <= 8) {
      bmask = (0xFF >> (8 - img_width)) << (8 - img_bitoff - img_width);
      src = pimg_row[0];
      pimg_row[0] = (src & ~bmask) | (color0 & bmask);
      continue;
    }
    else {
mlib_status mlib_ImageConvClearEdge_Bit(mlib_image     *img,
                                        mlib_s32       dx_l,
                                        mlib_s32       dx_r,
                                        mlib_s32       dy_t,
                                        mlib_s32       dy_b,
                                        const mlib_s32 *color,
                                        mlib_s32       cmask)
{
  mlib_u8  *pimg = mlib_ImageGetData(img), *pd;
  mlib_s32 img_height = mlib_ImageGetHeight(img);
  mlib_s32 img_width  = mlib_ImageGetWidth(img);
  mlib_s32 img_stride = mlib_ImageGetStride(img);
  mlib_s32 bitoff = mlib_ImageGetBitOffset(img);
  mlib_s32 bitoff_end;
  mlib_u8  color_i, mask, mask_end, tmp_color;
  mlib_u8  tmp_start, tmp_end;
  mlib_s32 i, j, amount;

  if ((mlib_ImageGetType(img) != MLIB_BIT) || (mlib_ImageGetChannels(img) != 1))
    return MLIB_FAILURE;

  color_i = (mlib_u8)(color[0] & 1);
  color_i |= (color_i << 1);
  color_i |= (color_i << 2);
  color_i |= (color_i << 4);

  pd = pimg;

  if (dx_l > 0) {
    if (bitoff + dx_l <= 8) {
      mask = (0xFF >> bitoff) & (0xFF << ((8 - (bitoff + dx_l)) & 7));
      tmp_color = color_i & mask;
      mask = ~mask;

      for (i = dy_t; i < (img_height - dy_b); i++) {
        pd[i*img_stride] = (pd[i*img_stride] & mask) | tmp_color;
      }

    } else {
mlib_status
__mlib_ImageZoomTranslate(
    mlib_image *dst,
    const mlib_image *src,
    mlib_d64 zoomx,
    mlib_d64 zoomy,
    mlib_d64 tx,
    mlib_d64 ty,
    mlib_filter filter,
    mlib_edge edge)
{
	mlib_type type;
	mlib_s32 nchan, t_ind;
	mlib_status res;
#ifndef	_NO_LONGLONG
	const mlib_s16 *flt_table;
#else
	const mlib_f32 *flt_table;
#endif
	mlib_clipping nearest, current;
	mlib_work_image border, *param = &border;

	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_CHAN_EQUAL(src, dst);

	if (zoomx <= 0 || zoomy <= 0)
		return (MLIB_OUTOFRANGE);

	if (mlib_ImageGetWidth(src) >= (1 << 15) ||
	    mlib_ImageGetHeight(src) >= (1 << 15)) {
		return (MLIB_FAILURE);
	}

	border.nearest = &nearest;
	border.current = &current;

	mlib_ImageZoomClipping(dst, src, zoomx, zoomy, tx, ty, filter, edge,
	    &border);

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

	switch (type) {
	case MLIB_BIT:
		if (nchan != 1 || filter != MLIB_NEAREST) {
			return (MLIB_FAILURE);
		}
		if (current.width > 0) {
			int s_bitoff = mlib_ImageGetBitOffset(src);
			int d_bitoff = mlib_ImageGetBitOffset(dst);

			return mlib_ImageZoom_BIT_1_Nearest(&border, s_bitoff,
			    d_bitoff);
		}
		return (MLIB_SUCCESS);

	case MLIB_BYTE:
		t_ind = 0;
		break;
	case MLIB_SHORT:
		t_ind = 1;
		break;
	case MLIB_USHORT:
		t_ind = 2;
		break;
	case MLIB_INT:
		t_ind = 3;
		break;
	default:
		return (MLIB_FAILURE);
	}

	if (current.width > 0) {
		switch (filter) {
		case MLIB_NEAREST:
			res = mlib_zoom_nn_funs[border.ind_fun_nn] (&border);
			break;

		case MLIB_BILINEAR:
			if (zoomy < mlib_zoom_bl_level[t_ind]) {
				res =
				    mlib_zoom_bl_lo[4 * t_ind + (nchan -
				    1)] (&border);
			} else {
				res =
				    mlib_zoom_bl_hi[4 * t_ind + (nchan -
				    1)] (&border);
			}
			break;

		case MLIB_BICUBIC:
		case MLIB_BICUBIC2:
			if (type == MLIB_INT) {
				res = mlib_zoom_bc_s32[nchan - 1] (&border);
				break;
			}

#ifndef	_NO_LONGLONG
			if (filter == MLIB_BICUBIC) {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8_bc;
				} else {
					flt_table = mlib_filters_s16_bc;
				}
			} else {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8_bc2;
				} else {
					flt_table = mlib_filters_s16_bc2;
				}
			}
#else
			if (filter == MLIB_BICUBIC) {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8f_bc;
				} else {
					flt_table = mlib_filters_s16f_bc;
				}
			} else {
				if (type == MLIB_BYTE) {
					flt_table = mlib_filters_u8f_bc2;
				} else {
					flt_table = mlib_filters_s16f_bc2;
				}
			}
#endif

			if (zoomy < mlib_zoom_bc_level[t_ind]) {
				res =
				    mlib_zoom_bc_lo[4 * t_ind + (nchan -
				    1)] (&border, flt_table);
			} else {
				res =
				    mlib_zoom_bc_hi[4 * t_ind + (nchan -
				    1)] (&border, flt_table);
			}
			break;

		default:
			return (MLIB_FAILURE);
		}

		if (res != MLIB_SUCCESS)
			return (res);
	}

	if (filter == MLIB_NEAREST && edge != MLIB_EDGE_SRC_EXTEND_INDEF) {
		return (MLIB_SUCCESS);
	}

	MLIB_EDGE_RULES;

	return (MLIB_SUCCESS);
}
mlib_status FUNC(
    MxN) (
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 *kernel,
    mlib_s32 m,
    mlib_s32 n,
    mlib_s32 dm,
    mlib_s32 dn,
    mlib_s32 scale,
    const void *colormap)
{
	mlib_type stype, dtype;
	mlib_u8 *sl, *dl;
	mlib_u8 *lut_table;
	mlib_s32 offset, off, kw, dn1;
	mlib_s32 schan, dchan, sll, dll, sw, sh, dw, dh;
	mlib_s32 row, i, j, bsize, buff_ind = 0, func_ind, method;
	mlib_u16 *pbuff, *buff_lcl[2 * MAX_N], **buff_arr = buff_lcl, **buff;
	mlib_d64 *buffd;
	mlib_d64 kern_lcl[MAX_N * MAX_M], *kern = kern_lcl, *pkern;
	mlib_d64 dscale;
	func_dm_type func_dm;

	mlib_s32 vis_scale, kern_i;
	mlib_s32 kern_size, isum;
	mlib_d64 sum, norm;
	mlib_f32 fscale;
	mlib_s32 bit_offset;
	mlib_u8 *buff_dst;

	MLIB_IMAGE_GET_ALL_PARAMS(dst, dtype, dchan, dw, dh, dll, dl);
	MLIB_IMAGE_GET_ALL_PARAMS(src, stype, schan, sw, sh, sll, sl);
	bit_offset = mlib_ImageGetBitOffset(dst);

	if (!(stype == MLIB_BYTE && schan == 1)) {
		return (MLIB_FAILURE);
	}
#if 0
	for (i = 0; i <= m * dn + dm; i++) {
		if (kernel[i])
			return (MLIB_FAILURE);
	}

#endif /* 0 */

	dn = n - 1 - dn;
	dm = m - 1 - dm;
	kern_size = m * dn + dm;

	if (n > MAX_N || m > MAX_M) {
		kern =
		    __mlib_malloc(n * m * sizeof (mlib_d64) +
		    2 * n * sizeof (mlib_u16 *));

		if (kern == NULL)
			return (MLIB_FAILURE);
		buff_arr = (mlib_u16 **)(kern + n * m);
	}

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

	dscale /= (1 << scale);

/* load kernel */
	kernel += m * n - 1;
	sum = 0;
	for (i = 0; i < kern_size; i++) {
		kern[i] = dscale * kernel[-i];
		sum += mlib_fabs(kern[i]);
	}

	vis_scale = mlib_ilogb(sum);

	if (vis_scale > 13)
		return (MLIB_OUTOFRANGE);
	vis_scale = 14 - vis_scale;

	if (vis_scale > 15)
		vis_scale = 15;
	norm = 32768 >> (15 - vis_scale);
	isum = 0;
	for (i = 0; i < kern_size; i++) {
		if (kern[i] > 0.0) {
			kern_i = (mlib_s32)(kern[i] * norm + 0.5);
		} else {
			kern_i = (mlib_s32)(kern[i] * norm - 0.5);
		}

		isum += abs(kern_i);
		kern[i] = vis_to_double_dup((kern_i << 16) | (kern_i & 0xffff));
	}

/* recalc without rounding */
	if (isum > 32767) {
		dscale *= norm;
		for (i = 0; i < kern_size; i++) {
			kern_i = (mlib_s32)(dscale * kernel[-i]);
			kern[i] =
			    vis_to_double_dup((kern_i << 16) | (kern_i &
			    0xffff));
		}
	}

	fscale = vis_to_float(1 << (vis_scale - 1));
	vis_write_gsr(((16 - vis_scale) << 3) + 2);

	offset = mlib_ImageGetLutOffset(colormap);
	lut_table = (mlib_u8 *)mlib_ImageGetLutInversTable(colormap);

	bsize = (sw + m) * NCHAN;
	bsize = (bsize + 7) & ~7;
	dn1 = (dn) ? dn : 1;
	pbuff =
	    __mlib_malloc((dn1 + 1) * bsize * sizeof (mlib_u16) + EXTRA_BUFF);

	if (pbuff == NULL) {
		if (kern != kern_lcl)
			__mlib_free(kern);
		return (MLIB_FAILURE);
	}

	for (j = 0; j < dn1; j++) {
		buff_arr[dn1 + j] = buff_arr[j] = pbuff + j * bsize;
	}

	buff_ind = 0;
	buffd = (mlib_d64 *)(pbuff + dn1 * bsize);
	buff_dst = (mlib_u8 *)((mlib_u16 *)buffd + bsize);

/* clear buffer */
	for (i = 0; i < dn * (bsize / 4); i++) {
		((mlib_d64 *)pbuff)[i] = 0;
	}

	func_ind = dm;

	if (func_ind > KH_MAX)
		func_ind = KH_MAX;
	method = mlib_ImageGetMethod(colormap);

	if (method == LUT_COLOR_CUBE_SEARCH)
		func_ind += KH_MAX + 1;
	else if (method == LUT_COLOR_DIMENSIONS)
		func_ind += 2 * (KH_MAX + 1);
	func_dm = func_dm_arr[func_ind];

	for (row = 0; row < sh; row++) {
		mlib_u8 *sp = sl;

		buff = buff_arr + buff_ind;

/* convert source line */
		for (i = 0; i < sw; i++) {
			mlib_d64 ss;

			ss = LD_U8(sp, i);
			ss = vis_fmul8x16al(vis_read_lo(ss), fscale);
			ST_U16(buffd, i, ss);
		}

		pkern = kern;
		for (j = 0; j < dn; j++) {
			for (off = 0; off < m; off += kw) {
				kw = m - off;

				if (kw > KW_MAX) {
					if (kw > 2 * KW_MAX)
						kw = KW_MAX;
					else
						kw = kw / 2;
				}

				func_m_arr[kw] (buffd, buff[j] + off * NCHAN,
				    pkern + off, sw);
			}

			pkern += m;
		}

#ifdef USE_COLOR2INDEXLINE
		func_dm(buff_dst, (void *)buffd, buff[dn] + dm * NCHAN, pkern,
		    colormap, lut_table, sw, dm, 0);
/*
 * mlib_ImageColorTrue2IndexLine_U8_BIT_1
 * (buff_dst, dl, bit_offset, sw, colormap);
 */
#else /* USE_COLOR2INDEXLINE */
		func_dm(dl, (void *)buffd, buff[dn] + dm * NCHAN, pkern,
		    colormap, lut_table, sw, dm, bit_offset);
#endif /* USE_COLOR2INDEXLINE */

		buff_ind++;

		if (buff_ind >= dn1)
			buff_ind -= dn1;

		sl += sll;
		dl += dll;
	}

	__mlib_free(pbuff);

	if (kern != kern_lcl)
		__mlib_free(kern);

	return (MLIB_SUCCESS);
}
mlib_status
FUNC(MxN) (
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 **dmask,
    mlib_s32 m,
    mlib_s32 n,
    mlib_s32 scale,
    const void *colormap)
{
	mlib_type stype, dtype;
	const mlib_s32 *dmask0;
	mlib_s32 method = mlib_ImageGetMethod(colormap);
	mlib_u8 *sl, *dl;
	mlib_s32 schan, dchan, sll, dll, sw, sh, dw, dh, num_blk, tail;
	mlib_s32 off, off1, kw, mstep, kern_size, i, j;
	mlib_u8 *pbuff, *p_lut;
	mlib_s32 kern_lcl[MAX_KERN], *kern = kern_lcl, *pkern;
	mlib_s64 dscale, dscale0;
	mlib_s32 step0, half_step0;
	mlib_s32 bit_offset = mlib_ImageGetBitOffset(dst);

	MLIB_IMAGE_GET_ALL_PARAMS(dst, dtype, dchan, dw, dh, dll, dl);
	MLIB_IMAGE_GET_ALL_PARAMS(src, stype, schan, sw, sh, sll, sl);

	p_lut = (mlib_u8 *)mlib_ImageGetLutInversTable(colormap);
	step0 = abs(p_lut[1] - p_lut[0]);

	kern_size = n * m * NCHAN;

	if (kern_size > MAX_KERN) {
		kern = __mlib_malloc(kern_size * sizeof (mlib_s32));

		if (kern == NULL)
			return (MLIB_FAILURE);
	}

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

	dscale *= (1 << scale);

	dscale0 = step0;
	half_step0 = (step0 - 1) >> 1;

	dmask0 = dmask[0];
	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			kern[j * m + i] =
			    half_step0 - (mlib_s32)((dmask0[j * m +
			    i] * dscale0) / dscale);
		}
	}

	num_blk = sw / m;
	tail = sw % m;
	pbuff = __mlib_malloc(sw * NCHAN * sizeof (mlib_u8));

	if (pbuff == NULL) {
		if (kern != kern_lcl)
			__mlib_free(kern);
		return (MLIB_FAILURE);
	}

	mstep = m * NCHAN;
	pkern = kern;

	for (j = 0; j < sh; j++) {
		for (off = 0; off < m; off += kw) {
			kw = m - off;

			if (kw > KW_MAX)
				kw = KW_MAX;
			off1 = off * NCHAN;
			if (tail - off >= kw) {
				func_m_arr[kw] (pbuff + off1, sl + off1,
				pkern + off1, mstep, num_blk + 1, 0);
			} else {
				func_m_arr[kw] (pbuff + off1, sl + off1,
				pkern + off1, mstep, num_blk, tail - off);
			}
		}

		pkern += mstep;

		if (pkern >= kern + kern_size)
			pkern = kern;

		mlib_ImageColorTrue2IndexLine_U8_BIT_1(pbuff, dl, bit_offset,
		    sw, colormap);

		sl += sll;
		dl += dll;
	}

	__mlib_free(pbuff);

	if (kern != kern_lcl)
		__mlib_free(kern);

	return (MLIB_SUCCESS);
}
Exemple #9
0
mlib_status mlib_ImageLookUp(mlib_image       *dst,
                             const mlib_image *src,
                             const void       **table)
{
  mlib_s32 slb, dlb, xsize, ysize, nchan, ichan, bitoff_src;
  mlib_type stype, dtype;
  void *sa, *da;

  MLIB_IMAGE_CHECK(src);
  MLIB_IMAGE_CHECK(dst);
  MLIB_IMAGE_SIZE_EQUAL(src, dst);
  MLIB_IMAGE_CHAN_SRC1_OR_EQ(src, dst);

  stype = mlib_ImageGetType(src);
  dtype = mlib_ImageGetType(dst);
  ichan = mlib_ImageGetChannels(src);
  nchan = mlib_ImageGetChannels(dst);
  xsize = mlib_ImageGetWidth(src);
  ysize = mlib_ImageGetHeight(src);
  slb = mlib_ImageGetStride(src);
  dlb = mlib_ImageGetStride(dst);
  sa = mlib_ImageGetData(src);
  da = mlib_ImageGetData(dst);

  if (ichan == nchan) {
    if (dtype == MLIB_BYTE) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, U8, mlib_u8);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, U8, mlib_u8);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, U8, mlib_u8);
      }
      else if (stype == MLIB_INT) {
        CALL_FUNC(S32, U8, mlib_u8);
      }
      else if (stype == MLIB_BIT) {
        if (nchan != 1)
          return MLIB_FAILURE;

        bitoff_src = mlib_ImageGetBitOffset(src); /* bits to first byte */
        return mlib_ImageLookUp_Bit_U8_1(sa, slb, da, dlb, xsize, ysize, nchan,
                                         bitoff_src, (const mlib_u8 **) table);
      }
    }
    else if (dtype == MLIB_SHORT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, S16, mlib_s16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, S16, mlib_s16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, S16, mlib_s16);
      }
      else if (stype == MLIB_INT) {
        CALL_FUNC(S32, S16, mlib_s16);
      }
    }
    else if (dtype == MLIB_USHORT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, U16, mlib_u16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, U16, mlib_u16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, U16, mlib_u16);
      }
      else if (stype == MLIB_INT) {
        CALL_FUNC(S32, U16, mlib_u16);
      }
    }
    else if (dtype == MLIB_INT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUp_S32_S32(sa, slb, da, dlb, xsize, ysize, (const mlib_s32 **) table,
                                     nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_FLOAT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUp_S32_S32(sa, slb, da, dlb, xsize, ysize, (const mlib_s32 **) table,
                                     nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_DOUBLE) {
      if (stype == MLIB_BYTE) {
        mlib_ImageLookUp_U8_D64(sa, slb, da, dlb / 8, xsize, ysize, nchan,
                                (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_SHORT) {
        mlib_ImageLookUp_S16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                 (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_USHORT) {
        mlib_ImageLookUp_U16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                 (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_INT) {
        mlib_ImageLookUp_S32_D64(sa, slb / 4, da, dlb / 8, xsize, ysize, nchan,
                                 (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
    }
  }
  else if (ichan == 1) {
    if (dtype == MLIB_BYTE) {
      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, U8, mlib_u8);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, U8, mlib_u8);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, U8, mlib_u8);
      }
      else if (stype == MLIB_INT) {
        CALL_SIFUNC(S32, U8, mlib_u8);
      }
      else if (stype == MLIB_BIT) {
        bitoff_src = mlib_ImageGetBitOffset(src); /* bits to first byte */

        if (nchan == 2) {
          return mlib_ImageLookUp_Bit_U8_2(sa, slb, da, dlb, xsize, ysize, nchan,
                                           bitoff_src, (const mlib_u8 **) table);
        }
        else if (nchan == 3) {
          return mlib_ImageLookUp_Bit_U8_3(sa, slb, da, dlb, xsize, ysize, nchan,
                                           bitoff_src, (const mlib_u8 **) table);
        }
        else {                              /* (nchan == 4) */
          return mlib_ImageLookUp_Bit_U8_4(sa, slb, da, dlb, xsize, ysize, nchan,
                                           bitoff_src, (const mlib_u8 **) table);
        }
      }
    }
    else if (dtype == MLIB_SHORT) {
      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, S16, mlib_s16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, S16, mlib_s16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, S16, mlib_s16);
      }
      else if (stype == MLIB_INT) {
        CALL_SIFUNC(S32, S16, mlib_s16);
      }
    }
    else if (dtype == MLIB_USHORT) {
      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, U16, mlib_u16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, U16, mlib_u16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, U16, mlib_u16);
      }
      else if (stype == MLIB_INT) {
        CALL_SIFUNC(S32, U16, mlib_u16);
      }
    }
    else if (dtype == MLIB_INT) {

      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUpSI_S32_S32(sa, slb, da, dlb, xsize, ysize,
                                       (const mlib_s32 **) table, nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_FLOAT) {

      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUpSI_S32_S32(sa, slb, da, dlb, xsize, ysize,
                                       (const mlib_s32 **) table, nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_DOUBLE) {
      if (stype == MLIB_BYTE) {
        mlib_ImageLookUpSI_U8_D64(sa, slb, da, dlb / 8, xsize, ysize, nchan,
                                  (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_SHORT) {
        mlib_ImageLookUpSI_S16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                   (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_USHORT) {
        mlib_ImageLookUpSI_U16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                   (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_INT) {
        mlib_ImageLookUpSI_S32_D64(sa, slb / 4, da, dlb / 8, xsize, ysize, nchan,
                                   (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
    }
  }

  return MLIB_FAILURE;
}
mlib_status FUNC(
    MxN) (
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 **dmask,
    mlib_s32 m,
    mlib_s32 n,
    mlib_s32 scale,
    const void *colormap)
{
	mlib_type stype, dtype;
	const mlib_s32 *dmask0 = dmask[0], *dmask1 = dmask[1], *dmask2 =
	    dmask[2];
	mlib_s32 method = mlib_ImageGetMethod(colormap);
	mlib_u8 *sl, *dl;
	mlib_s32 schan, dchan, sll, dll, sw, sh, dw, dh, num_blk;
	mlib_s32 off, off1, kw, mstep, line_size, kern_size, xsize16, i, j, k;
	__m128i *pbuff, *pb;
	mlib_u8 *p_dim;
	mlib_s16 *kern, *pkern;
	__m128i *dkern;
	mlib_d64 dscale, dscale0, dscale1, dscale2;
	__m128i ss, d0, d1, k0, k1;
	__m128i _s_zero = _mm_xor_si128(_s_zero, _s_zero);
	mlib_s32 step0, half_step0, v0;
	mlib_s32 bit_offset = mlib_ImageGetBitOffset(dst);
	mlib_u8 *p_lut;

	MLIB_IMAGE_GET_ALL_PARAMS(dst, dtype, dchan, dw, dh, dll, dl);
	MLIB_IMAGE_GET_ALL_PARAMS(src, stype, schan, sw, sh, sll, sl);

	p_lut = (mlib_u8 *)mlib_ImageGetLutInversTable(colormap);
	step0 = abs(p_lut[1] - p_lut[0]);

	num_blk = (sw + (m - 1)) / m;
	mstep = m * NCHAN;
	line_size = (mstep * num_blk + 15) & ~15;
	xsize16 = (NCHAN * sw + 15) / 16;

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

	dscale /= (1 << scale);

	dscale0 = dscale * step0;
	half_step0 = (step0 - 1) >> 1;

	kern_size = n * line_size;
	kern = __mlib_malloc(kern_size * sizeof (mlib_s16));

	if (kern == NULL)
		return (MLIB_FAILURE);

	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			pkern = kern + j * line_size + i;
			v0 = half_step0 - (mlib_s32)(dmask0[j * m +
			    i] * dscale0);
			for (k = 0; k < num_blk; k++) {
				pkern[k * mstep] = v0;
			}
		}
	}

	pbuff = __mlib_malloc(xsize16 * sizeof (__m128i) + 16);

	if (pbuff == NULL) {
		__mlib_free(kern);
		return (MLIB_FAILURE);
	}

	pkern = kern;

#ifdef  __SUNPRO_C
#pragma pipeloop(0)
#endif
	for (j = 0; j < sh; j++) {
		dkern = (__m128i *)pkern;

		__m128i *sp = (__m128i *)sl;
		pb = pbuff;

#ifdef  __SUNPRO_C
#pragma pipeloop(0)
#endif
		for (i = 0; i < xsize16; i++) {
			ss = _mm_loadu_si128(sp);
			sp++;
			k0 = _mm_loadu_si128(dkern);
			dkern++;
			k1 = _mm_loadu_si128(dkern);
			dkern++;
			d0 = _mm_unpacklo_epi8(ss, _s_zero);
			d1 = _mm_unpackhi_epi8(ss, _s_zero);
			d0 = _mm_add_epi16(d0, k0);
			d1 = _mm_add_epi16(d1, k1);
			d1 = _mm_packus_epi16(d0, d1);
			_mm_storeu_si128(pb, d1);
			pb++;
		}

		pkern += line_size;

		if (pkern >= kern + kern_size)
			pkern = kern;

		mlib_ImageColorTrue2IndexLine_U8_BIT_1((mlib_u8 *)pbuff, dl,
		    bit_offset, sw, colormap);

		sl += sll;
		dl += dll;
	}

	__mlib_free(pbuff);
	__mlib_free(kern);

	return (MLIB_SUCCESS);
}
Exemple #11
0
mlib_status mlib_ImageAffine_alltypes(mlib_image       *dst,
                                      const mlib_image *src,
                                      const mlib_d64   *mtx,
                                      mlib_filter      filter,
                                      mlib_edge        edge,
                                      const void       *colormap)
{
  mlib_affine_param param[1];
  mlib_status res;
  mlib_type type;
  mlib_s32 nchan, t_ind, kw, kw1;
  mlib_addr align;
  mlib_d64 buff_lcl[BUFF_SIZE / 8];
  mlib_u8 **lineAddr = NULL;

  /* check for obvious errors */
  MLIB_IMAGE_TYPE_EQUAL(src, dst);
  MLIB_IMAGE_CHAN_EQUAL(src, dst);

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

  switch (filter) {
    case MLIB_NEAREST:
      kw = 1;
      kw1 = 0;
      break;

    case MLIB_BILINEAR:
      kw = 2;
      kw1 = 0;
      break;

    case MLIB_BICUBIC:
    case MLIB_BICUBIC2:
      kw = 4;
      kw1 = 1;
      break;

    default:
      return MLIB_FAILURE;
  }

  STORE_PARAM(param, lineAddr);
  STORE_PARAM(param, filter);

  res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,
                         kw, kw, kw1, kw1, edge, mtx, MLIB_SHIFT, MLIB_SHIFT);

  if (res != MLIB_SUCCESS)
    return res;

  lineAddr = param->lineAddr;

  if (type == MLIB_BYTE)
    t_ind = 0;
  else if (type == MLIB_SHORT)
    t_ind = 1;
  else if (type == MLIB_INT)
    t_ind = 2;
  else if (type == MLIB_USHORT)
    t_ind = 3;
  else if (type == MLIB_FLOAT)
    t_ind = 4;
  else if (type == MLIB_DOUBLE)
    t_ind = 5;

  if (colormap != NULL && filter != MLIB_NEAREST) {
    if (t_ind != 0 && t_ind != 1)
      return MLIB_FAILURE;

    if (mlib_ImageGetLutType(colormap) == MLIB_SHORT)
      t_ind += 2;
    t_ind = 2 * t_ind;

    if (mlib_ImageGetLutChannels(colormap) == 4)
      t_ind++;
  }

  if (type == MLIB_BIT) {
    mlib_s32 s_bitoff = mlib_ImageGetBitOffset(src);
    mlib_s32 d_bitoff = mlib_ImageGetBitOffset(dst);

    if (nchan != 1 || filter != MLIB_NEAREST)
      return MLIB_FAILURE;
    mlib_ImageAffine_bit_1ch_nn(param, s_bitoff, d_bitoff);
  }
  else {
    switch (filter) {
      case MLIB_NEAREST:

        if (t_ind >= 3)
          t_ind -= 2;                                      /* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */

        /* two channels as one channel of next type */
        align = (mlib_addr) (param->dstData) | (mlib_addr) lineAddr[0];
        align |= param->dstYStride | param->srcYStride;
        while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < MAX_T_IND) {
          nchan >>= 1;
          t_ind++;
        }

        res = mlib_AffineFunArr_nn[4 * t_ind + (nchan - 1)] (param);
        break;

      case MLIB_BILINEAR:

        if (colormap != NULL) {
          res = mlib_AffineFunArr_bl_i[t_ind] (param, colormap);
        }
        else {
          res = mlib_AffineFunArr_bl[4 * t_ind + (nchan - 1)] (param);
        }

        break;

      case MLIB_BICUBIC:
      case MLIB_BICUBIC2:

        if (colormap != NULL) {
          res = mlib_AffineFunArr_bc_i[t_ind] (param, colormap);
        }
        else {
          res = mlib_AffineFunArr_bc[4 * t_ind + (nchan - 1)] (param);
        }

        break;
    }

    if (res != MLIB_SUCCESS) {
      if (param->buff_malloc != NULL)
        mlib_free(param->buff_malloc);
      return res;
    }
  }

  if (edge == MLIB_EDGE_SRC_PADDED)
    edge = MLIB_EDGE_DST_NO_WRITE;

  if (filter != MLIB_NEAREST && edge != MLIB_EDGE_DST_NO_WRITE) {
    mlib_affine_param param_e[1];
    mlib_d64 buff_lcl1[BUFF_SIZE / 8];

    STORE_PARAM(param_e, lineAddr);
    STORE_PARAM(param_e, filter);

    res = mlib_AffineEdges(param_e, dst, src, buff_lcl1, BUFF_SIZE,
                           kw, kw, kw1, kw1, -1, mtx, MLIB_SHIFT, MLIB_SHIFT);

    if (res != MLIB_SUCCESS) {
      if (param->buff_malloc != NULL)
        mlib_free(param->buff_malloc);
      return res;
    }

    switch (edge) {
      case MLIB_EDGE_DST_FILL_ZERO:
        mlib_ImageAffineEdgeZero(param, param_e, colormap);
        break;

      case MLIB_EDGE_OP_NEAREST:
        mlib_ImageAffineEdgeNearest(param, param_e);
        break;

      case MLIB_EDGE_SRC_EXTEND:

        if (filter == MLIB_BILINEAR) {
          res = mlib_ImageAffineEdgeExtend_BL(param, param_e, colormap);
        }
        else {
          res = mlib_ImageAffineEdgeExtend_BC(param, param_e, colormap);
        }

        break;
    }

    if (param_e->buff_malloc != NULL)
      mlib_free(param_e->buff_malloc);
  }

  if (param->buff_malloc != NULL)
    mlib_free(param->buff_malloc);

  return res;
}
mlib_status
__mlib_ImageZoomTranslate(
    mlib_image *dst,
    const mlib_image *src,
    mlib_d64 zoomx,
    mlib_d64 zoomy,
    mlib_d64 tx,
    mlib_d64 ty,
    mlib_filter filter,
    mlib_edge edge)
{
	mlib_type type;
	mlib_s32 nchan;
	mlib_clipping nearest, current;
	mlib_work_image border, *param = &border;

	MLIB_IMAGE_CHECK(src);
	MLIB_IMAGE_CHECK(dst);
	MLIB_IMAGE_TYPE_EQUAL(src, dst);
	MLIB_IMAGE_CHAN_EQUAL(src, dst);

	if (zoomx <= 0 || zoomy <= 0)
		return (MLIB_OUTOFRANGE);

	if (mlib_ImageGetWidth(src) >= (1 << 15) ||
	    mlib_ImageGetHeight(src) >= (1 << 15)) {
		return (MLIB_FAILURE);
	}

	border.nearest = &nearest;
	border.current = &current;

	mlib_ImageZoomClipping(dst, src, zoomx, zoomy,
	    tx, ty, filter, edge, &border);

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

	if (type == MLIB_BIT) {
		if (nchan != 1 || filter != MLIB_NEAREST)
			return (MLIB_FAILURE);
		if (current.width > 0) {
			int s_bitoff = mlib_ImageGetBitOffset(src);
			int d_bitoff = mlib_ImageGetBitOffset(dst);

			return mlib_ImageZoom_BIT_1_Nearest(&border, s_bitoff,
			    d_bitoff);
		}
		return (MLIB_SUCCESS);
	}

	if (filter == MLIB_BICUBIC) {
		if (type == MLIB_BYTE) {
			border.filter1 = (void *)mlib_filters_u8_bc;
			border.filter3 = (void *)mlib_filters_u8_bc_3;
			border.filter4 = (void *)mlib_filters_u8_bc_4;
		} else {
			border.filter1 = (void *)mlib_filters_s16_bc;
			border.filter3 = (void *)mlib_filters_s16_bc_3;
			border.filter4 = (void *)mlib_filters_s16_bc_4;
		}
	} else {
		if (type == MLIB_BYTE) {
			border.filter1 = (void *)mlib_filters_u8_bc2;
			border.filter3 = (void *)mlib_filters_u8_bc2_3;
			border.filter4 = (void *)mlib_filters_u8_bc2_4;
		} else {
			border.filter1 = (void *)mlib_filters_s16_bc2;
			border.filter3 = (void *)mlib_filters_s16_bc2_3;
			border.filter4 = (void *)mlib_filters_s16_bc2_4;
		}
	}

	if (current.width > 0) {
		if (filter == MLIB_NEAREST) {
			RETURN(mlib_zoom_nn_funs[border.ind_fun_nn]);
		} else

		switch (type) {

/* handle MLIB_BYTE data type of image */
		case MLIB_BYTE: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_1s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_1_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_1_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_1_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_2s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_2_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_2_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_2_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_3s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_3_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_3_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_3_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U8_4s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_4_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U8_4_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U8_4_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* handle MLIB_SHORT data type of image */
		case MLIB_SHORT: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    RETURN(mlib_m_ImageZoom_S16_1_Bilinear);
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_1_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_1_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_S16_2s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_2_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_2_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_2_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_S16_3s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_3_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_3_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_3_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_S16_4s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_4_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_S16_4_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_S16_4_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* handle MLIB_USHORT data type of image */
		case MLIB_USHORT: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    RETURN(mlib_m_ImageZoom_U16_1_Bilinear);
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_1_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_1_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U16_2s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_2_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_2_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_2_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U16_3s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_3_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_3_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_3_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy <= 0.5) {
					RETURN(
					    mlib_m_ImageZoom_U16_4s_Bilinear);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_4_Bilinear);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    if (zoomy <= 0.25) {
					RETURN(
					    mlib_m_ImageZoom_U16_4_Bicubic);
				    } else {
					RETURN(
					    mlib_m_ImageZoom_U16_4_1_Bicubic);
				    }
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* handle MLIB_INT data type of image */
		case MLIB_INT: {

		    switch (mlib_ImageGetChannels(src)) {

		    case 1:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    RETURN(mlib_ImageZoomBilinear_S32_1);
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_1);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 2:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy < 2) {
					    RETURN(
						mlib_ImageZoomBilinear_S32_2s);
				    } else {
					    RETURN(
						mlib_ImageZoomBilinear_S32_2);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_2);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 3:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy < 2 || mlib_ImageGetHeight(dst)
					> 256) {
					    RETURN(
						mlib_ImageZoomBilinear_S32_3s);
				    } else {
					    RETURN(
						mlib_ImageZoomBilinear_S32_3);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_3);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    case 4:
			    switch (filter) {

			    case MLIB_BILINEAR:
				    if (zoomy < 2 || mlib_ImageGetHeight(dst)
					> 256) {
					    RETURN(
						mlib_ImageZoomBilinear_S32_4s);
				    } else {
					    RETURN(
						mlib_ImageZoomBilinear_S32_4);
				    }
				    break;

			    case MLIB_BICUBIC:
			    case MLIB_BICUBIC2:
				    RETURN(mlib_ImageZoomBicubic_S32_4);
				    break;

			    default:
				    return (MLIB_FAILURE);
			    }
			    break;

		    default:
			    return (MLIB_FAILURE);

		    }
		}
		break;

/* discard any other data types */
		default:
			return (MLIB_FAILURE);
		}
	}

	if (filter == MLIB_NEAREST && edge != MLIB_EDGE_SRC_EXTEND_INDEF) {
		return (MLIB_SUCCESS);
	}

	MLIB_EDGE_RULES
	return (MLIB_SUCCESS);
}
mlib_status FUNC(
    MxN) (
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 *kernel,
    mlib_s32 m,
    mlib_s32 n,
    mlib_s32 dm,
    mlib_s32 dn,
    mlib_s32 scale,
    const void *colormap)
{
	mlib_type stype, dtype;
	mlib_u8 *sl, *dl;
	mlib_u8 *lut_table;
	mlib_s32 offset, off, kw, dn1;
	mlib_s32 schan, dchan, sll, dll, sw, sh, dw, dh;
	mlib_s32 row, i, j, bsize, buff_ind = 0, func_ind, method;
	mlib_s64 *pbuff, *buffd, *buff_lcl[2 * MAX_N], **buff_arr =
	    buff_lcl, **buff;
	mlib_s32 kern_lcl[MAX_N * MAX_M], *kern = kern_lcl, *pkern;
	mlib_s64 dscale;

	func_dm_type func_dm;
	mlib_s32 bit_offset;

	MLIB_IMAGE_GET_ALL_PARAMS(dst, dtype, dchan, dw, dh, dll, dl);
	MLIB_IMAGE_GET_ALL_PARAMS(src, stype, schan, sw, sh, sll, sl);
	bit_offset = mlib_ImageGetBitOffset(dst);

	if (!(stype == MLIB_BYTE && schan == 1)) {
		return (MLIB_FAILURE);
	}

	dn = n - 1 - dn;
	dm = m - 1 - dm;

	if (n > MAX_N || m > MAX_M) {
		kern =
		    __mlib_malloc(n * m * sizeof (mlib_s32) +
		    2 * n * sizeof (mlib_s32 *));

		if (kern == NULL)
			return (MLIB_FAILURE);
		buff_arr = (mlib_s64 **)(kern + n * m);

	}

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

	kernel += m * n - 1;
	for (i = 0; i < (m * dn + dm); i++) {
		kern[i] = kernel[-i];
	}

	offset = mlib_ImageGetLutOffset(colormap);
	lut_table = (mlib_u8 *)mlib_ImageGetLutInversTable(colormap);

	bsize = (sw + m) * NCHAN;
	dn1 = (dn) ? dn : 1;
	pbuff = __mlib_malloc((dn1 + 1) * bsize * sizeof (mlib_s64));

	if (pbuff == NULL) {
		if (kern != kern_lcl)
			__mlib_free(kern);
		return (MLIB_FAILURE);
	}

	for (j = 0; j < dn1; j++) {
		buff_arr[dn1 + j] = buff_arr[j] = pbuff + j * bsize;
	}

	buff_ind = 0;
	buffd = pbuff + dn1 * bsize;

/* clear buffer */
	for (i = 0; i < dn * bsize; i++) {
		pbuff[i] = 0;
	}

	func_ind = dm;

	if (func_ind > KH_MAX)
		func_ind = KH_MAX;
	method = mlib_ImageGetMethod(colormap);

	if (method == LUT_COLOR_CUBE_SEARCH)
		func_ind += KH_MAX + 1;
	else if (method == LUT_COLOR_DIMENSIONS)
		func_ind += 2 * (KH_MAX + 1);
	func_dm = func_dm_arr[func_ind];

	for (row = 0; row < sh; row++) {
		buff = buff_arr + buff_ind;

/* convert source line to mlib_d64 */
		for (i = 0; i < sw * NCHAN; i++) {
			buffd[i] = sl[i] * dscale;
		}

		pkern = kern;
		for (j = 0; j < dn; j++) {
			for (off = 0; off < m; off += kw) {
				kw = m - off;

				if (kw > KW_MAX) {
					if (kw > 2 * KW_MAX)
						kw = KW_MAX;
					else
						kw = kw / 2;
				}

				func_m_arr[kw] (buffd, buff[j] + off * NCHAN,
				    pkern + off, sw);
			}

			pkern += m;
		}

		func_dm(dl, buffd, buff[dn] + dm * NCHAN,
			pkern, dscale, colormap,
		    lut_table, sw, dm, bit_offset);

		buff_ind++;

		if (buff_ind >= dn1)
			buff_ind -= dn1;

		sl += sll;
		dl += dll;
	}

	__mlib_free(pbuff);

	if (kern != kern_lcl)
		__mlib_free(kern);

	return (MLIB_SUCCESS);
}
Exemple #14
0
		da = (mlib_u8 *)mlib_ImageGetData(dst);

		width = mlib_ImageGetWidth(src) * mlib_ImageGetChannels(src);
		height = mlib_ImageGetHeight(src);

		if (!mlib_ImageIsNotOneDvector(src) &&
		    !mlib_ImageIsNotOneDvector(dst)) {
			size = height * (width >> 3);
			mlib_ImageCopy_na(sa, da, size);
		} else {
/* in byte */
			s_stride = mlib_ImageGetStride(src);
/* in byte */
			d_stride = mlib_ImageGetStride(dst);
/* in bits */
			s_offset = mlib_ImageGetBitOffset(src);
/* in bits */
			d_offset = mlib_ImageGetBitOffset(dst);

			if (s_offset == d_offset) {
				for (j = 0; j < height; j++) {
					mlib_ImageCopy_bit_al(sa, da, width,
					    s_offset);
					sa += s_stride;
					da += d_stride;
				}
			} else {
				for (j = 0; j < height; j++) {
					mlib_ImageCopy_bit_na(sa, da, width,
					    s_offset, d_offset);
					sa += s_stride;
mlib_status FUNC(
    MxN) (
    mlib_image *dst,
    const mlib_image *src,
    const mlib_s32 **dmask,
    mlib_s32 m,
    mlib_s32 n,
    mlib_s32 scale,
    const void *colormap)
{
	mlib_type stype, dtype;
	const mlib_s32 *dmask0 = dmask[0], *dmask1 = dmask[1], *dmask2 =
	    dmask[2];
	mlib_s32 method = mlib_ImageGetMethod(colormap);
	mlib_u8 *sl, *dl;
	mlib_s32 schan, dchan, sll, dll, sw, sh, dw, dh, num_blk;
	mlib_s32 off, off1, kw, mstep, line_size, kern_size, xsize8, i, j, k;
	mlib_d64 *pbuff;
	mlib_u8 *p_dim;
	mlib_s16 *kern, *pkern;
	mlib_d64 *dkern;
	mlib_d64 dscale, dscale0, dscale1, dscale2;
	mlib_d64 ss, d0, d1;
	mlib_f32 fzeros = vis_fzeros();
	mlib_s32 step0, half_step0, v0;
	mlib_s32 bit_offset = mlib_ImageGetBitOffset(dst);
	mlib_u8 *p_lut;

	MLIB_IMAGE_GET_ALL_PARAMS(dst, dtype, dchan, dw, dh, dll, dl);
	MLIB_IMAGE_GET_ALL_PARAMS(src, stype, schan, sw, sh, sll, sl);

	p_lut = (mlib_u8 *)mlib_ImageGetLutInversTable(colormap);
	step0 = abs(p_lut[1] - p_lut[0]);

	num_blk = (sw + (m - 1)) / m;
	mstep = m * NCHAN;
	line_size = (mstep * num_blk + 7) & ~7;
	xsize8 = (NCHAN * sw + 7) / 8;

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

	dscale /= (1 << scale);

	dscale0 = dscale * step0;
	half_step0 = (step0 - 1) >> 1;

	kern_size = n * line_size;
	kern = __mlib_malloc(kern_size * sizeof (mlib_s16));

	if (kern == NULL)
		return (MLIB_FAILURE);

	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			pkern = kern + j * line_size + i;
			v0 = half_step0 - (mlib_s32)(dmask0[j * m +
			    i] * dscale0);
			for (k = 0; k < num_blk; k++) {
				pkern[k * mstep] = v0;
			}
		}
	}

	pbuff = __mlib_malloc(xsize8 * sizeof (mlib_d64) + 16);

	if (pbuff == NULL) {
		__mlib_free(kern);
		return (MLIB_FAILURE);
	}

	pkern = kern;

	vis_write_gsr(7 << 3);

	for (j = 0; j < sh; j++) {
		dkern = (mlib_d64 *)pkern;

		if ((mlib_s32)sl & 7) {
			mlib_u8 *sp = sl;

#pragma pipeloop(0)
			for (i = 0; i < xsize8; i++) {
				LOAD_NA_NF(ss, sp);
				d0 = vis_fpadd16(vis_fpmerge(vis_fzeros(),
				    vis_read_hi(ss)), dkern[2 * i]);
				d1 = vis_fpadd16(vis_fpmerge(vis_fzeros(),
				    vis_read_lo(ss)), dkern[2 * i + 1]);
				pbuff[i] = vis_fpack16_pair(d0, d1);
				sp += 8;
			}

		} else {
			mlib_d64 *sp = (mlib_d64 *)sl;

#pragma pipeloop(0)
			for (i = 0; i < xsize8; i++) {
				ss = sp[i];
				d0 = vis_fpadd16(vis_fpmerge(vis_fzeros(),
				    vis_read_hi(ss)), dkern[2 * i]);
				d1 = vis_fpadd16(vis_fpmerge(vis_fzeros(),
				    vis_read_lo(ss)), dkern[2 * i + 1]);
				pbuff[i] = vis_fpack16_pair(d0, d1);
			}
		}

		pkern += line_size;

		if (pkern >= kern + kern_size)
			pkern = kern;

		mlib_ImageColorTrue2IndexLine_U8_BIT_1((mlib_u8 *)pbuff, dl,
		    bit_offset, sw, colormap);

		sl += sll;
		dl += dll;
	}

	__mlib_free(pbuff);
	__mlib_free(kern);

	return (MLIB_SUCCESS);
}