mlib_status __mlib_ImageFilteredSubsample( ARGS) { mlib_type type; mlib_d64 fhkernel[16], fvkernel[16]; mlib_s32 kw = 2 * hSize - hParity; mlib_s32 kh = 2 * vSize - vParity; mlib_s32 i, j, iscale; mlib_d64 sum_p, sum_n, sum; MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_CHECK(src); MLIB_IMAGE_TYPE_EQUAL(dst, src); MLIB_IMAGE_CHAN_EQUAL(dst, src); if (edge != MLIB_EDGE_DST_NO_WRITE) return (MLIB_FAILURE); type = mlib_ImageGetType(dst); /* MMX version */ if (type == MLIB_BYTE) { for (i = 0; i < hSize; i++) { fhkernel[i] = fhkernel[kw - 1 - i] = hKernel[hSize - 1 - i]; } for (i = 0; i < vSize; i++) { fvkernel[i] = fvkernel[kh - 1 - i] = vKernel[vSize - 1 - i]; } sum_p = 0; sum_n = 0; for (j = 0; j < kh; j++) { for (i = 0; i < kw; i++) { mlib_d64 kk = fvkernel[j] * fhkernel[i]; if (kk > 0) sum_p += kk; else sum_n -= kk; } } sum = (sum_p > sum_n) ? sum_p : sum_n; iscale = 1 + mlib_ilogb((128.0 / 127.) * sum); if (iscale < 0) iscale = 0; if (iscale < 7) return (mlib_m_ImageFilteredSubsample_8nw_1( PARAMS_MMX)); } if (kh > 2 * scaleY || (kh == 2 * scaleY && scaleY > 1)) { switch (type) { case MLIB_BYTE: return (mlib_ImageFilteredSubsample_8nw_2(PARAMS)); case MLIB_SHORT: return (mlib_ImageFilteredSubsample_16nw_2(PARAMS)); case MLIB_USHORT: return (mlib_ImageFilteredSubsample_u16nw_2(PARAMS)); case MLIB_INT: return (mlib_ImageFilteredSubsample_32nw_2(PARAMS)); default: return (MLIB_FAILURE); } } else { switch (type) { case MLIB_BYTE: return (mlib_ImageFilteredSubsample_8nw_1(PARAMS)); case MLIB_SHORT: return (mlib_ImageFilteredSubsample_16nw_1(PARAMS)); case MLIB_USHORT: return (mlib_ImageFilteredSubsample_u16nw_1(PARAMS)); case MLIB_INT: return (mlib_ImageFilteredSubsample_32nw_1(PARAMS)); default: return (MLIB_FAILURE); } } }
mlib_status mlib_ImageGridWarpTable_alltypes( mlib_image *dst, const mlib_image *src, const mlib_f32 *xWarpPos, const mlib_f32 *yWarpPos, mlib_d64 postShiftX, mlib_d64 postShiftY, mlib_s32 xStart, mlib_s32 xStep, mlib_s32 xNumCells, mlib_s32 yStart, mlib_s32 yStep, mlib_s32 yNumCells, const void *table, mlib_edge edge) { mlib_type type; mlib_u8 *srcLinePtr, *srcData, *dstData; mlib_s32 srcWidth, dstWidth, srcHeight, dstHeight; mlib_s32 srcStride, dstStride, nchan; mlib_s32 *leftEdges, *rightEdges, *xStarts, *yStarts, *sides; mlib_affine_workspace ws[1]; mlib_d64 buff_local[BUFF_SIZE / sizeof (mlib_d64)]; void *buffer = buff_local; const mlib_u8 **lineAddr; mlib_u8 *pbuff; mlib_s32 kw, kh, kw1, kh1, kw2, kh2, bsize, bsize0, bsize1; mlib_status status; fun_type_nw fun_nw = NULL; mlib_interp_table *tbl = (mlib_interp_table *) table; mlib_u8 *paddings; mlib_s32 i, x_shift, y_shift; mlib_s32 xFirst, xLast, xSkip, xRest; mlib_s32 yFirst, yLast, ySkip, yRest; mlib_s32 elt_size = 1; mlib_d64 minX, minY, maxX, maxY; mlib_d64 dx_shift, dy_shift; mlib_s32 xBeg, xEnd; mlib_s32 yBeg, yEnd; mlib_s32 yskip, xskip, yrest, xrest; mlib_s32 x, y, cx, cy; mlib_d64 px0, py0, px1, py1, px3, py3; mlib_d64 dx0, dx1, dy0, dy1, cx0, cx1, cy0, cy1, dx, dy, cx2, cy2, cx3, cy3; mlib_d64 delta_x, delta_y; mlib_d64 xs, ys; mlib_d64 xNum, yNum; mlib_d64 xStep1 = 1.0 / xStep, yStep1 = 1.0 / yStep; mlib_s32 is_clip, is_clip1, is_clip2, is_clip3, is_clip4; mlib_d64 tE, tL, tmp_x0, tmp_y0, tmp_dx, tmp_dy, num, denom, t; mlib_d64 d_rdx, d_rdy, x0, y0, x1, y1; mlib_s32 shift_left, shift_right, max_xsize; /* check for obvious errors */ MLIB_IMAGE_CHECK(src); MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_TYPE_EQUAL(src, dst); MLIB_IMAGE_CHAN_EQUAL(src, dst); MLIB_IMAGE_GET_ALL_PARAMS(src, type, nchan, srcWidth, srcHeight, srcStride, srcData); MLIB_IMAGE_GET_ALL_PARAMS(dst, type, nchan, dstWidth, dstHeight, dstStride, dstData); paddings = mlib_ImageGetPaddings(src); if (srcWidth >= (1 << 15) || srcHeight >= (1 << 15)) { return (MLIB_FAILURE); } for (xFirst = 0; ; xFirst++) { if ((xStart + xFirst * xStep + xStep - 1) >= 0) break; } for (yFirst = 0; ; yFirst++) { if ((yStart + yFirst * yStep + yStep - 1) >= 0) break; } for (xLast = xNumCells - 1; xLast >= xFirst; xLast--) { if ((xStart + xLast * xStep) <= (dstWidth - 1)) break; } for (yLast = yNumCells - 1; yLast >= yFirst; yLast--) { if ((yStart + yLast * yStep) <= (dstHeight - 1)) break; } if ((xStart + xFirst * xStep) < 0) xSkip = -(xStart + xFirst * xStep); else xSkip = 0; if ((yStart + yFirst * yStep) < 0) ySkip = -(yStart + yFirst * yStep); else ySkip = 0; if ((xStart + xLast * xStep + xStep) > (dstWidth)) xRest = (xStart + xLast * xStep + xStep) - (dstWidth); else xRest = 0; if ((yStart + yLast * yStep + yStep) > (dstHeight)) yRest = (yStart + yLast * yStep + yStep) - (dstHeight); else yRest = 0; kw = tbl->width; kh = tbl->height; kw1 = tbl->leftPadding; kh1 = tbl->topPadding; kw2 = kw - kw1 - 1; kh2 = kh - kh1 - 1; x_shift = INT_BITS - mlib_ilogb(srcWidth + kw); y_shift = INT_BITS - mlib_ilogb(srcHeight + kh); dx_shift = (mlib_d64)(1 << x_shift); dy_shift = (mlib_d64)(1 << y_shift); if (type == MLIB_BYTE) elt_size = 1; else if (type == MLIB_SHORT) elt_size = 2; else if (type == MLIB_INT) elt_size = 3; else if (type == MLIB_FLOAT) elt_size = 4; else if (type == MLIB_DOUBLE) elt_size = 5; else if (type == MLIB_USHORT) elt_size = 0; ws->type = elt_size; ws->srcData = srcData; ws->dstData = dstData; ws->srcWidth = srcWidth; ws->srcHeight = srcHeight; ws->srcStride = srcStride; ws->dstStride = dstStride; ws->nchan = nchan; ws->x_shift0 = x_shift; ws->y_shift = y_shift; ws->x_move = (kw1 << x_shift); ws->y_move = (kh1 << y_shift); ws->affine_mask = 1; if (!elt_size) elt_size = 6; /* VIS version of non NULL */ fun_nw = mlib_ImageAffine_GetFunc(ws, tbl); if (fun_nw == NULL) /* for U8 via F32 */ fun_nw = mlib_ImageAffine_ConvertImage(src, ws, tbl); if (fun_nw == NULL) { if (nchan == 3) { fun_nw = fun_array_nw[2 * elt_size - 1]; } else { fun_nw = fun_array_nw[2 * elt_size - 2]; } } bsize0 = (srcHeight * sizeof (mlib_u8 *) + 7) & ~7; bsize1 = 6 * dstHeight * sizeof (mlib_s32) + 8; bsize = bsize0 + bsize1; if (bsize > BUFF_SIZE) { buffer = __mlib_malloc(bsize); if (buffer == NULL) return (MLIB_FAILURE); } pbuff = buffer; lineAddr = (mlib_u8 const **)pbuff; pbuff += bsize0; srcLinePtr = (mlib_u8 *)(ws->srcData); srcStride = ws->srcStride; for (i = 0; i < srcHeight; i++) { lineAddr[i] = srcLinePtr; srcLinePtr += srcStride; } leftEdges = (mlib_s32 *)pbuff; rightEdges = (mlib_s32 *)pbuff + dstHeight; xStarts = (mlib_s32 *)pbuff + 2 * dstHeight; yStarts = (mlib_s32 *)pbuff + 3 * dstHeight; sides = (mlib_s32 *)pbuff + 4 * dstHeight; ws->sides = sides; minX = kw1 + 0.5; minY = kh1 + 0.5; maxX = srcWidth - kw2 + 0.5; maxY = srcHeight - kh2 + 0.5; if (edge == MLIB_EDGE_SRC_PADDED) { if (minX < paddings[0]) minX = paddings[0]; if (minY < paddings[1]) minY = paddings[1]; if (maxX > (srcWidth - paddings[2])) maxX = srcWidth - paddings[2]; if (maxY > (srcHeight - paddings[3])) maxY = srcHeight - paddings[3]; } if ((minX >= maxX) || (minY >= maxY)) { if (ws->srcData != srcData) __mlib_free(ws->srcData); if (buffer != (mlib_s32 *)buff_local) __mlib_free(buffer); return (MLIB_SUCCESS); } for (y = yFirst, cy = yStart + yFirst * yStep; y <= yLast; y++, cy += yStep) { yskip = (y == yFirst) ? ySkip : 0; yrest = (y == yLast) ? yRest : 0; yBeg = cy + yskip; yEnd = cy + (yStep - 1) - yrest; yNum = yEnd - yBeg; ys = yskip + 0.5; INIT_GRID_ROW(xFirst, y); for (x = xFirst, cx = xStart + xFirst * xStep; x <= xLast; x++, cx += xStep) { xskip = (x == xFirst) ? xSkip : 0; xrest = (x == xLast) ? xRest : 0; xBeg = cx + xskip; xEnd = cx + (xStep - 1) - xrest; xNum = xEnd - xBeg; xs = xskip + 0.5; INCR_GRID_ROW(x, y, xs, ys); ws->yStart = yBeg; ws->yFinish = yEnd; max_xsize = 0; if (IS_CELL_CLIP()) { for (i = yBeg; i <= yEnd; i++) { tE = 0; tL = xNum; tmp_x0 = cx0 + (i - yBeg) * dx0; tmp_y0 = cy0 + (i - yBeg) * dy0; tmp_dx = dx + (i - yBeg) * delta_x; tmp_dy = dy + (i - yBeg) * delta_y; if (tmp_dx) { d_rdx = 1.0 / tmp_dx; MLIB_CLIP(d_rdx, -tmp_x0 + minX); MLIB_CLIP(-d_rdx, tmp_x0 - maxX); } else if ((tmp_x0 < minX) || (tmp_x0 >= maxX)) { leftEdges[i] = 1; rightEdges[i] = 0; continue; } if (tmp_dy) { d_rdy = 1.0 / tmp_dy; MLIB_CLIP(d_rdy, -tmp_y0 + minY); MLIB_CLIP(-d_rdy, tmp_y0 - maxY); } else if ((tmp_y0 < minY) || (tmp_y0 >= maxY)) { leftEdges[i] = 1; rightEdges[i] = 0; continue; } if (tE > tL) { leftEdges[i] = 1; rightEdges[i] = 0; continue; } shift_left = (mlib_s32)tE; if ((mlib_d64)shift_left != tE) shift_left++; shift_right = (mlib_s32)tL; if ((mlib_d64)shift_right != tL) shift_right++; x0 = tmp_x0 + shift_left * tmp_dx; x1 = tmp_x0 + shift_right * tmp_dx; if (tmp_dx >= 0) { if (x0 < minX) shift_left++; if (x1 >= maxX) shift_right--; } else { if (x0 >= maxX) shift_left++; if (x1 < minX) shift_right--; } y0 = tmp_y0 + shift_left * tmp_dy; y1 = tmp_y0 + shift_right * tmp_dy; if (tmp_dy >= 0) { if (y0 < minY) shift_left++; if (y1 >= maxY) shift_right--; } else { if (y0 >= maxY) shift_left++; if (y1 < minY) shift_right--; } x0 = tmp_x0 + shift_left * tmp_dx; y0 = tmp_y0 + shift_left * tmp_dy; leftEdges[i] = xBeg + shift_left; rightEdges[i] = xBeg + shift_right; if ((shift_right - shift_left + 1) > max_xsize) max_xsize = (shift_right - shift_left + 1); xStarts[i] = (mlib_s32)((x0 - 0.5) * dx_shift); yStarts[i] = (mlib_s32)((y0 - 0.5) * dy_shift); sides[i * 2 + 2] = (mlib_s32)(tmp_dx * dx_shift); sides[i * 2 + 3] = (mlib_s32)(tmp_dy * dy_shift); } } else { if ((xEnd - xBeg + 1) > max_xsize) max_xsize = (xEnd - xBeg + 1); #ifdef __SUNPRO_C #pragma pipeloop(0) #endif /* __SUNPRO_C */ for (i = yBeg; i <= yEnd; i++) { tmp_x0 = cx0 + (i - yBeg) * dx0; tmp_y0 = cy0 + (i - yBeg) * dy0; tmp_dx = dx + (i - yBeg) * delta_x; tmp_dy = dy + (i - yBeg) * delta_y; leftEdges[i] = xBeg; rightEdges[i] = xEnd; xStarts[i] = (mlib_s32)((tmp_x0 - 0.5) * dx_shift); yStarts[i] = (mlib_s32)((tmp_y0 - 0.5) * dy_shift); sides[i * 2 + 2] = (mlib_s32)(tmp_dx * dx_shift); sides[i * 2 + 3] = (mlib_s32)(tmp_dy * dy_shift); } } if (max_xsize > 0) { ws->max_xsize = max_xsize; status = fun_nw(dstData + (yBeg - 1) * dstStride, lineAddr, leftEdges, rightEdges, xStarts, yStarts, ws, tbl); if (status != MLIB_SUCCESS) { if (ws->srcData != srcData) __mlib_free(ws->srcData); if (buffer != (mlib_s32 *)buff_local) __mlib_free(buffer); return (MLIB_FAILURE); } } } } if (ws->srcData != srcData) __mlib_free(ws->srcData); if (buffer != (mlib_s32 *)buff_local) __mlib_free(buffer); 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 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; } }
mlib_status __mlib_SignalCepstral_S16_Adp( mlib_s16 *cepst, mlib_s32 *cscale, const mlib_s16 *signal, void *state) { mlib_s32 i, len, itmp; mlib_f32 fscale; mlib_cepstral *str_cepst = state; mlib_s32 order = str_cepst->order; deal_t *buffer = str_cepst->buffer; deal_t *coeff = str_cepst->coeff; deal_t *coeff_s = str_cepst->coeff_s; mlib_s32 len_full = 1 << order; deal_t tmp, fmax, scale; #if REAL_IFFT_NEEDWASTE len = len_full; #else /* REAL_IFFT_NEEDWASTE */ len = len_full / 2 + 1; #endif /* REAL_IFFT_NEEDWASTE */ #ifdef __SUNPRO_C #pragma nomemorydepend #pragma pipeloop(0) #endif /* __SUNPRO_C */ for (i = 0; i < len_full; i++) buffer[i] = signal[i] / (deal_t)32768; mlib_fft_r2c(buffer, order); mlib_SignalCepstral_S16_Middle(buffer, coeff, buffer, coeff_s, 0, len); mlib_fft_r2r(coeff, order - 1); fmax = 0; #ifdef __SUNPRO_C #pragma nomemorydepend #endif /* __SUNPRO_C */ for (i = 0; i < len; i++) { tmp = mlib_fabsf(coeff[i]); if (tmp > fmax) fmax = tmp; } itmp = 14 - mlib_ilogb(fmax); SET_FLOAT_ORDER(fscale, itmp); scale = fscale; #if ICOS_FFT_NEEDWASTE #ifdef __SUNPRO_C #pragma nomemorydepend #pragma pipeloop(0) #endif /* __SUNPRO_C */ for (i = 0; i < len_full; i++) cepst[i] = coeff[i] * scale; #else /* ICOS_FFT_NEEDWASTE */ cepst[0] = coeff[0] * scale; cepst[len] = coeff[len] * scale; #ifdef __SUNPRO_C #pragma nomemorydepend #pragma pipeloop(0) #endif /* __SUNPRO_C */ for (i = 1; i < len; i++) { cepst[i] = cepst[len_full - i] = coeff[i] * scale; } #endif /* ICOS_FFT_NEEDWASTE */ *cscale = itmp + order; return (MLIB_SUCCESS); }
mlib_status __mlib_ImageZoomTranslateTableBlend( mlib_image *dst, const mlib_image *src, mlib_d64 zoomx, mlib_d64 zoomy, mlib_d64 tx, mlib_d64 ty, const void *table, mlib_edge edge, mlib_blend blend, mlib_s32 cmask) { mlib_affine_param param[1]; mlib_affine_param *cur_param; mlib_zoom_workspace ws[1]; mlib_d64 buff_lcl[BUFF_SIZE / 8]; mlib_type type; mlib_u8 *srcData, *dstData; mlib_s32 srcWidth, dstWidth, srcHeight, dstHeight; mlib_s32 srcStride, dstStride, schan, dchan; mlib_s32 *leftEdges, *rightEdges, *xStarts, *yStarts; mlib_s32 *p_x_ind = NULL, *x_ind, *x_tab = NULL, xpos; mlib_u8 **lineAddr = NULL; mlib_s32 kw, kh, kw1, kh1; mlib_status res = MLIB_SUCCESS; fun_type_nw fun_nw = NULL; mlib_interp_table *tbl = (mlib_interp_table *) table; mlib_d64 mtx[6], dxs, tmp_dxs, div; mlib_s32 i, x_shift, y_shift; mlib_s32 affine = 0, yStart; mlib_s32 xLeft_e, xRight_e, xLeft, xRight, dx; mtx[0] = zoomx; mtx[1] = 0; mtx[2] = tx; mtx[3] = 0; mtx[4] = zoomy; mtx[5] = ty; ws->zoomx = zoomx; ws->zoomy = zoomy; /* check for obvious errors */ MLIB_IMAGE_CHECK(src); MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_TYPE_EQUAL(src, dst); MLIB_IMAGE_HAVE_TYPE(src, MLIB_BYTE); if (zoomx <= 0 || zoomy <= 0) return (MLIB_OUTOFRANGE); if (mlib_ImageGetWidth(src) >= (1 << 15) || mlib_ImageGetHeight(src) >= (1 << 15)) { return (MLIB_FAILURE); } MLIB_IMAGE_GET_ALL_PARAMS(src, type, schan, srcWidth, srcHeight, srcStride, srcData); MLIB_IMAGE_GET_ALL_PARAMS(dst, type, dchan, dstWidth, dstHeight, dstStride, dstData); if ((schan == 4 || dchan == 4) && cmask != 1 && cmask != 8) return (MLIB_OUTOFRANGE); if (schan < 3 || schan > 4 || dchan < 3 || dchan > 4) { return (MLIB_FAILURE); } if ((blend == MLIB_BLEND_GTK_SRC) && (schan == 3) && (dchan == 3)) return __mlib_ImageZoomTranslateTable(dst, src, zoomx, zoomy, tx, ty, table, edge); kw = tbl->width; kh = tbl->height; kw1 = tbl->leftPadding; kh1 = tbl->topPadding; x_shift = INT_BITS - mlib_ilogb(srcWidth + kw); y_shift = INT_BITS - mlib_ilogb(srcHeight + kh); ws->type = type; ws->srcData = srcData; ws->dstData = dstData; ws->srcWidth = srcWidth; ws->srcHeight = srcHeight; ws->srcStride = srcStride; ws->dstStride = dstStride; ws->nchan = schan; ws->dchan = dchan; ws->blend = blend; ws->alpha_shift = 1; ws->edge = edge; ws->x_shift = x_shift; ws->y_shift = y_shift; ws->x_move = (kw1 << x_shift); ws->y_move = (kh1 << y_shift); if (cmask == 1) ws->alpha_shift = -3; /* VIS version of non NULL */ fun_nw = mlib_ImageZoomTranslate_GetFunc(ws, table); if (fun_nw == NULL) { fun_nw = mlib_ImageZoomTranslateTableBlend_8nw; } /* NULL */ STORE_PARAM(param, affine); STORE_PARAM(param, lineAddr); param->buff_malloc = NULL; /* process internal pixels */ res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE, kw, kh, kw1, kh1, edge, mtx, x_shift, y_shift); if (res != MLIB_SUCCESS) return (res); ws->yStart = param->yStart; ws->yFinish = param->yFinish; ws->max_xsize = param->max_xsize; ws->dx = param->dX; ws->dy = param->dY; LOAD_PARAM(param, lineAddr); LOAD_PARAM(param, leftEdges); LOAD_PARAM(param, rightEdges); LOAD_PARAM(param, xStarts); LOAD_PARAM(param, yStarts); if (edge == MLIB_EDGE_SRC_EXTEND) ws->y_move += (1 << (y_shift - 1)); if ((ws->max_xsize) > 0) { /* RTC */ yStarts[(ws->yFinish) + 1] = 0; res = fun_nw(param->dstData, lineAddr, leftEdges, rightEdges, xStarts, yStarts, ws, tbl); if (res != MLIB_SUCCESS) { if (param->buff_malloc != NULL) __mlib_free(param->buff_malloc); return (res); } } /* process edge pixels */ if (edge != MLIB_EDGE_DST_NO_WRITE && edge != MLIB_EDGE_SRC_PADDED) { mlib_affine_param param_e[1]; param_e->buff_malloc = NULL; if (edge == MLIB_EDGE_DST_FILL_ZERO || edge == MLIB_EDGE_OP_NEAREST) { x_shift = 16; y_shift = 16; } STORE_PARAM(param_e, lineAddr); if (edge != MLIB_EDGE_SRC_EXTEND_INDEF) { res = mlib_AffineEdges(param_e, dst, src, NULL, 0, kw, kh, kw1, kh1, -1, mtx, x_shift, y_shift); } if (res == MLIB_SUCCESS) switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: mlib_ImageZoomTranslateTableBlendEdgeZero (param, param_e, dchan, schan, ws->alpha_shift, blend); break; case MLIB_EDGE_OP_NEAREST: mlib_ImageZoomTranslateTableBlendEdgeNearest (param, param_e, dchan, schan, ws->alpha_shift, blend); break; case MLIB_EDGE_SRC_EXTEND: case MLIB_EDGE_SRC_EXTEND_INDEF: ws->x_shift = x_shift; ws->x_move += (1 << (x_shift - 1)); if (edge == MLIB_EDGE_SRC_EXTEND) { ws->yStart = param_e->yStart; ws->yFinish = param_e->yFinish; yStart = ws->yStart; ws->dx = param_e->dX; xLeft_e = param_e->leftEdges[yStart]; xRight_e = param_e->rightEdges[yStart]; cur_param = param_e; } else { cur_param = param; ws->yStart = param->yStart; yStart = ws->yStart; xLeft_e = 0; xRight_e = dstWidth - 1; } xLeft = param->leftEdges[param->yStart]; xRight = param->rightEdges[param->yStart]; if ((xLeft > xRight) || (param->yStart > param->yFinish)) { xLeft = xRight_e + 1; xRight = xRight_e; } if (((xRight_e - xLeft_e + 1) > 0) && (ws->yStart <= ws->yFinish)) { CREATE_X_IND(); LOAD_PARAM(cur_param, lineAddr); LOAD_PARAM(cur_param, leftEdges); LOAD_PARAM(cur_param, xStarts); LOAD_PARAM(cur_param, yStarts); /* RTC */ yStarts[(ws->yFinish) + 1] = 0; if (edge == MLIB_EDGE_SRC_EXTEND) { CREATE_X_EXT() } ws->max_xsize = xLeft - xLeft_e; if ((ws->max_xsize) > 0) { if (edge != MLIB_EDGE_SRC_EXTEND) { CREATE_X(xLeft_e, xLeft - 1); } leftEdges[0] = ws->max_xsize; leftEdges[1] = xLeft_e; res = FUNCNAME_EXT (cur_param->dstData, lineAddr, x_ind, leftEdges, x_tab, xStarts, yStarts, ws, tbl); } ws->max_xsize = xRight_e - xRight; if ((ws->max_xsize) > 0) { mlib_s32 shift = 0; if (edge != MLIB_EDGE_SRC_EXTEND) { CREATE_X(xRight + 1, xRight_e); } else { shift = xRight + 1 - xLeft_e; } leftEdges[0] = ws->max_xsize; leftEdges[1] = xRight + 1; res = FUNCNAME_EXT (cur_param->dstData, lineAddr, x_ind, leftEdges, x_tab + shift, xStarts, yStarts, ws, tbl); } __mlib_free(p_x_ind); if (x_tab != NULL) __mlib_free(x_tab); } break; default: res = MLIB_FAILURE; break; }
mlib_status mlib_m_ImageInitInterpTableAffine_S16( mlib_interp_table * table, mlib_s32 nchan) { mlib_s32 width, height, width_bits, height_bits, vis_width_bits, vis_height_bits; mlib_s32 subsampleBitsH, subsampleBitsV; mlib_s32 i, j, c, scale, num_copy, num_copy_old; mlib_s32 isum; mlib_s32 max_scale, min_scale, scaleh, scalev; mlib_s32 norm_scale_v, norm_scale_h; mlib_d64 dscale, *dataH, *dataV; mlib_d64 **ptr_tablex, *tablex, *tablex_old, *tabley; mlib_d64 max, d; mlib_d64 sumh, sumv, normh, normv; if (!table) return (MLIB_FAILURE); if (table->shift_vis_affine < 0) return (MLIB_FAILURE); if (nchan == 1) { num_copy = 1; ptr_tablex = &(table->dataH_s16_1); } else if (nchan == 2) { num_copy = 2; ptr_tablex = &(table->dataH_s16_3); } else if (nchan == 3 || nchan == 4) { num_copy = 4; ptr_tablex = &(table->dataH_s16_4); } else return (MLIB_FAILURE); if (*ptr_tablex != NULL && table->dataV_s16_1 != NULL) return (MLIB_SUCCESS); dataH = mlib_ImageGetInterpDoubleDataH(table); dataV = mlib_ImageGetInterpDoubleDataV(table); if (!dataH || !dataV) return (MLIB_FAILURE); width = mlib_ImageGetInterpWidth(table); height = mlib_ImageGetInterpHeight(table); width_bits = mlib_ImageGetInterpWidthBits(table); height_bits = mlib_ImageGetInterpHeightBits(table); vis_width_bits = table->vis_width_bits; vis_height_bits = table->vis_height_bits; subsampleBitsH = mlib_ImageGetInterpSubsampleBitsH(table); subsampleBitsV = mlib_ImageGetInterpSubsampleBitsV(table); if (table->dataV_s16_1 != NULL) { if (table->dataH_s16_1 != NULL) { tablex_old = table->dataH_s16_1; num_copy_old = 1; } else if (table->dataH_s16_3 != NULL) { tablex_old = table->dataH_s16_3; num_copy_old = 3; } else { tablex_old = table->dataH_s16_4; num_copy_old = 4; } tablex = mlib_malloc(num_copy * (1 << subsampleBitsH) * (1 << vis_width_bits) * sizeof (mlib_s16)); if (tablex == NULL) return (MLIB_FAILURE); for (j = 0; j < ((width + 1) & ~1); j++) { mlib_s16 *tbl = (mlib_s16 *)tablex + j * num_copy; mlib_s16 *tbl_old = (mlib_s16 *)tablex_old + j * num_copy_old; for (i = 0; i < (1 << subsampleBitsH); i++) { mlib_s16 v = tbl_old[num_copy_old * (i << vis_width_bits)]; for (c = 0; c < num_copy; c++) { tbl[num_copy * (i << vis_width_bits) + c] = v; } } } *ptr_tablex = tablex; return (MLIB_SUCCESS); } sumv = 0; max = 0; for (i = 0; i < (1 << subsampleBitsV); i++) { mlib_d64 s = 0; mlib_s32 ind = (i << height_bits); for (j = 0; j < height; j++) { d = mlib_fabs(dataV[j + ind]); s += d; max = (max > d) ? max : d; } sumv = (sumv > s) ? sumv : s; } /* all fhkernels = 0 */ if (sumv == 0) { dscale = 0; /* X table */ tablex = mlib_malloc(num_copy * (1 << subsampleBitsH) * (1 << vis_width_bits) * sizeof (mlib_s16)); if (tablex == NULL) return (MLIB_FAILURE); INIT_TABLE_16(tablex, (1 << subsampleBitsH), width, width_bits, vis_width_bits, dataH); if ((dataH == dataV) && num_copy == 4) tabley = tablex; else { num_copy = 4; tabley = mlib_malloc(num_copy * (1 << subsampleBitsV) * (1 << vis_height_bits) * sizeof (mlib_s16)); if (tabley == NULL) { mlib_free(tablex); return (MLIB_FAILURE); } INIT_TABLE_16(tabley, (1 << subsampleBitsV), height, height_bits, vis_height_bits, dataV); *ptr_tablex = tablex; table->dataV_s16_1 = tabley; /* Store shift */ table->shift_vis_affine = 43; return (MLIB_SUCCESS); } } normv = 32767.0 / (32768.0 * sumv); scalev = mlib_ilogb(sumv * normv); isum = mlib_ilogb(max * normv); /* all elements must be in the range -32768, 32767 */ if (scalev == isum) norm_scale_v = 14; /* but sumv may be in the range -65576, 65575 */ else norm_scale_v = 15; min_scale = 25; max_scale = 40; normh = 32768.0 * sumv / 32767; if (dataH != dataV) { sumh = 0; max = 0; for (i = 0; i < (1 << subsampleBitsH); i++) { mlib_d64 s = 0; mlib_s32 ind = (i << width_bits); for (j = 0; j < width; j++) { d = mlib_fabs(dataH[j + ind]); s += d; max = (max > d) ? max : d; } sumh = (sumh > s) ? sumh : s; } } else sumh = sumv; isum = mlib_ilogb(max * normh); scaleh = mlib_ilogb(sumh * normh); /* all elements must be in the range -32768, 32767 */ if (scaleh == isum) norm_scale_h = 14; /* but sumh may be in the range -65576, 65575 */ else norm_scale_h = 15; scale = norm_scale_v + norm_scale_h - (scaleh + scalev); if (scale < min_scale) { table->shift_vis_affine = -1; /* koeff. are so large */ return (MLIB_FAILURE); } if (scale > max_scale) { scaleh += (scale - max_scale + 1) >> 1; scalev += (scale - max_scale) >> 1; scale = max_scale; }