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 = ¤t; 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); }
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); }
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 = ¤t; 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); }
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); }