static void fdct_clamp(float *buf, JCOEFPTR coef, UINT16 *quantval) {
	int x, y, n = DCTSIZE;
	(void)x; (void)y;

	fdct_float(buf, buf);
#if 1 && defined(USE_NEON)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y++) {
		int16x8_t v0, v1, v2, v3; float32x4_t f0, f1, f2, f3, f4, f5; int32x4_t v4;
		v1 = vld1q_s16((int16_t*)&quantval[y * n]);
		v0 = vld1q_s16((int16_t*)&coef[y * n]); v3 = vshrq_n_s16(v0, 15);
		v2 = veorq_s16(vaddq_s16(vshrq_n_s16(v1, 1), v3), v3);
		v0 = vaddq_s16(v0, v2); f3 = vdupq_n_f32(0.5f); f5 = vnegq_f32(f3);
#define M1(low, f0, f1, x) \
	f4 = vld1q_f32(&buf[y * n + x]); \
	v4 = vmovl_s16(vget_##low##_s16(v0)); \
	f0 = vaddq_f32(f4, vbslq_f32(vcltq_f32(f4, vdupq_n_f32(0)), f5, f3)); \
	/* correction for imprecise divide */ \
	f1 = vbslq_f32(vreinterpretq_u32_s32(vshrq_n_s32(v4, 31)), f5, f3); \
	f4 = vcvtq_f32_s32(vmovl_s16(vget_##low##_s16(v1))); \
	f1 = vdivq_f32(vaddq_f32(vcvtq_f32_s32(v4), f1), f4);
		M1(low, f0, f1, 0) M1(high, f2, f3, 4)
#undef M1
		v2 = vcombine_s16(vmovn_s32(vcvtq_s32_f32(f0)), vmovn_s32(vcvtq_s32_f32(f2)));
		v0 = vcombine_s16(vmovn_s32(vcvtq_s32_f32(f1)), vmovn_s32(vcvtq_s32_f32(f3)));
		v0 = vmulq_s16(v0, v1); /* v0 = a0, v1 = div, v2 = add */
		v3 = vaddq_s16(v1, vreinterpretq_s16_u16(vcgeq_s16(v0, vdupq_n_s16(0))));
		v2 = vminq_s16(v2, vaddq_s16(v0, vshrq_n_s16(v3, 1)));
		v3 = vaddq_s16(v1, vreinterpretq_s16_u16(vcleq_s16(v0, vdupq_n_s16(0))));
		v2 = vmaxq_s16(v2, vsubq_s16(v0, vshrq_n_s16(v3, 1)));
		vst1q_s16((int16_t*)&coef[y * n], v2);
	} else
#elif 1 && defined(USE_AVX512)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y += 2) {
		__m256i v0, v1, v2, v3; __m512 f0, f1;
		v1 = _mm256_loadu_si256((__m256i*)&quantval[y * n]);
		v0 = _mm256_loadu_si256((__m256i*)&coef[y * n]);
		v2 = _mm256_srli_epi16(v1, 1); v3 = _mm256_srai_epi16(v0, 15);
		v2 = _mm256_xor_si256(_mm256_add_epi16(v2, v3), v3);
		v0 = _mm256_add_epi16(v0, v2);
		f0 = _mm512_loadu_ps(&buf[y * n]);
		/* vpmovd2m, and+or (need AVX512DQ) */
		f1 = _mm512_mask_blend_ps(_mm512_cmp_ps_mask(f0, _mm512_setzero_ps(), 1),
				_mm512_set1_ps(0.5f), _mm512_set1_ps(-0.5f));
		f0 = _mm512_add_ps(f0, f1);
		f1 = _mm512_cvtepi32_ps(_mm512_cvtepi16_epi32(v0));
		f1 = _mm512_div_ps(f1, _mm512_cvtepi32_ps(_mm512_cvtepi16_epi32(v1)));
		v2 = _mm512_cvtepi32_epi16(_mm512_cvttps_epi32(f0));
		v0 = _mm512_cvtepi32_epi16(_mm512_cvttps_epi32(f1));
		v0 = _mm256_mullo_epi16(v0, v1); /* v0 = a0, v1 = div, v2 = add */
		v1 = _mm256_add_epi16(v1, _mm256_set1_epi16(-1));
		v3 = _mm256_sub_epi16(v1, _mm256_srai_epi16(v0, 15));
		v2 = _mm256_min_epi16(v2, _mm256_add_epi16(v0, _mm256_srai_epi16(v3, 1)));
		v3 = _mm256_sub_epi16(v1, _mm256_cmpgt_epi16(v0, _mm256_setzero_si256()));
		v2 = _mm256_max_epi16(v2, _mm256_sub_epi16(v0, _mm256_srai_epi16(v3, 1)));
		_mm256_storeu_si256((__m256i*)&coef[y * n], v2);
	} else
#elif 1 && defined(USE_AVX2)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y++) {
		__m128i v0, v1, v2, v3; __m256i v4, v5; __m256 f0, f1;
		v1 = _mm_loadu_si128((__m128i*)&quantval[y * n]);
		v0 = _mm_loadu_si128((__m128i*)&coef[y * n]);
		v2 = _mm_srli_epi16(v1, 1); v3 = _mm_srai_epi16(v0, 15);
		v2 = _mm_xor_si128(_mm_add_epi16(v2, v3), v3);
		v0 = _mm_add_epi16(v0, v2);
		f0 = _mm256_loadu_ps(&buf[y * n]);
		f1 = _mm256_blendv_ps(_mm256_set1_ps(0.5f), _mm256_set1_ps(-0.5f), f0);
		f0 = _mm256_add_ps(f0, f1);
		f1 = _mm256_cvtepi32_ps(_mm256_cvtepi16_epi32(v0));
		f1 = _mm256_div_ps(f1, _mm256_cvtepi32_ps(_mm256_cvtepi16_epi32(v1)));
		v4 = _mm256_cvttps_epi32(f0); v5 = _mm256_cvttps_epi32(f1);
		v4 = _mm256_permute4x64_epi64(_mm256_packs_epi32(v5, v4), 0xd8);
		v0 = _mm256_castsi256_si128(v4); v2 = _mm256_extracti128_si256(v4, 1);
		v0 = _mm_mullo_epi16(v0, v1); /* v0 = a0, v1 = div, v2 = add */
		v1 = _mm_add_epi16(v1, _mm_set1_epi16(-1));
		v3 = _mm_sub_epi16(v1, _mm_srai_epi16(v0, 15));
		v2 = _mm_min_epi16(v2, _mm_add_epi16(v0, _mm_srai_epi16(v3, 1)));
		v3 = _mm_sub_epi16(v1, _mm_cmpgt_epi16(v0, _mm_setzero_si128()));
		v2 = _mm_max_epi16(v2, _mm_sub_epi16(v0, _mm_srai_epi16(v3, 1)));
		_mm_storeu_si128((__m128i*)&coef[y * n], v2);
	} else
#elif 1 && defined(USE_SSE2)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y++) {
		__m128i v0, v1, v2, v3; __m128 f0, f1, f2, f3, f4;
		v1 = _mm_loadu_si128((__m128i*)&quantval[y * n]);
		v0 = _mm_loadu_si128((__m128i*)&coef[y * n]);
		v2 = _mm_srli_epi16(v1, 1); v3 = _mm_srai_epi16(v0, 15);
		v2 = _mm_xor_si128(_mm_add_epi16(v2, v3), v3);
		v0 = _mm_add_epi16(v0, v2);
		v2 = _mm_setzero_si128(); v3 = _mm_srai_epi16(v0, 15);
#define M1(lo, f0, f1, x) \
	f0 = _mm_loadu_ps((float*)&buf[y * n + x]); \
	f4 = _mm_cmplt_ps(f0, _mm_setzero_ps()); \
	f4 = _mm_castsi128_ps(_mm_slli_epi32(_mm_castps_si128(f4), 31)); \
	f0 = _mm_add_ps(f0, _mm_or_ps(f4, _mm_set1_ps(0.5f))); \
	f4 = _mm_cvtepi32_ps(_mm_unpack##lo##_epi16(v1, v2)); \
	f1 = _mm_cvtepi32_ps(_mm_unpack##lo##_epi16(v0, v3)); \
	f1 = _mm_div_ps(f1, f4);
		M1(lo, f0, f1, 0) M1(hi, f2, f3, 4)
#undef M1
		v2 = _mm_packs_epi32(_mm_cvttps_epi32(f0), _mm_cvttps_epi32(f2));
		v0 = _mm_packs_epi32(_mm_cvttps_epi32(f1), _mm_cvttps_epi32(f3));
		v0 = _mm_mullo_epi16(v0, v1); /* v0 = a0, v1 = div, v2 = add */
		v1 = _mm_add_epi16(v1, _mm_set1_epi16(-1));
		v3 = _mm_sub_epi16(v1, _mm_srai_epi16(v0, 15));
		v2 = _mm_min_epi16(v2, _mm_add_epi16(v0, _mm_srai_epi16(v3, 1)));
		v3 = _mm_sub_epi16(v1, _mm_cmpgt_epi16(v0, _mm_setzero_si128()));
		v2 = _mm_max_epi16(v2, _mm_sub_epi16(v0, _mm_srai_epi16(v3, 1)));
		_mm_storeu_si128((__m128i*)&coef[y * n], v2);
	} else
#endif
	for (x = 0; x < n * n; x++) {
		int div = quantval[x], coef1 = coef[x], add;
		int dh, dl, d0 = (div - 1) >> 1, d1 = div >> 1;
		int a0 = (coef1 + (coef1 < 0 ? -d1 : d1)) / div * div;
		dh = a0 + (a0 < 0 ? d1 : d0);
		dl = a0 - (a0 > 0 ? d1 : d0);
		add = roundf(buf[x]);
		if (add > dh) add = dh;
		if (add < dl) add = dl;
		coef[x] = add;
	}
}
static void fdct_clamp(float *buf, JCOEFPTR coef, UINT16 *quantval) {
	int x, y, n = DCTSIZE;
	(void)x; (void)y;

	fdct_float(buf, buf);
#if 1 && defined(USE_NEON)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y++) {
		int16x8_t v0, v1, v2, v3; float32x4_t f0, f1, f2, f3, f4, f5; int32x4_t v4;
		v1 = vld1q_s16((int16_t*)&quantval[y * n]);
		v0 = vld1q_s16((int16_t*)&coef[y * n]); v3 = vshrq_n_s16(v0, 15);
		v2 = veorq_s16(vaddq_s16(vshrq_n_s16(v1, 1), v3), v3);
		v0 = vaddq_s16(v0, v2); f3 = vdupq_n_f32(0.5f); f5 = vnegq_f32(f3);
#define M1(low, f0, f1, x) \
	f4 = vld1q_f32(&buf[y * n + x]); \
	v4 = vmovl_s16(vget_##low##_s16(v0)); \
	f0 = vaddq_f32(f4, vbslq_f32(vcltq_f32(f4, vdupq_n_f32(0)), f5, f3)); \
	  \
	f1 = vbslq_f32(vreinterpretq_u32_s32(vshrq_n_s32(v4, 31)), f5, f3); \
	f4 = vcvtq_f32_s32(vmovl_s16(vget_##low##_s16(v1))); \
	f1 = vdivq_f32(vaddq_f32(vcvtq_f32_s32(v4), f1), f4);
		M1(low, f0, f1, 0) M1(high, f2, f3, 4)
#undef M1
		v2 = vcombine_s16(vmovn_s32(vcvtq_s32_f32(f0)), vmovn_s32(vcvtq_s32_f32(f2)));
		v0 = vcombine_s16(vmovn_s32(vcvtq_s32_f32(f1)), vmovn_s32(vcvtq_s32_f32(f3)));
		v0 = vmulq_s16(v0, v1);  
		v3 = vaddq_s16(v1, vreinterpretq_s16_u16(vcgeq_s16(v0, vdupq_n_s16(0))));
		v2 = vminq_s16(v2, vaddq_s16(v0, vshrq_n_s16(v3, 1)));
		v3 = vaddq_s16(v1, vreinterpretq_s16_u16(vcleq_s16(v0, vdupq_n_s16(0))));
		v2 = vmaxq_s16(v2, vsubq_s16(v0, vshrq_n_s16(v3, 1)));
		vst1q_s16((int16_t*)&coef[y * n], v2);
	} else
#elif 1 && defined(USE_AVX512)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y += 2) {
		__m256i v0, v1, v2, v3; __m512 f0, f1;
		v1 = _mm256_loadu_si256((__m256i*)&quantval[y * n]);
		v0 = _mm256_loadu_si256((__m256i*)&coef[y * n]);
		v2 = _mm256_srli_epi16(v1, 1); v3 = _mm256_srai_epi16(v0, 15);
		v2 = _mm256_xor_si256(_mm256_add_epi16(v2, v3), v3);
		v0 = _mm256_add_epi16(v0, v2);
		f0 = _mm512_loadu_ps(&buf[y * n]);
		 
		f1 = _mm512_mask_blend_ps(_mm512_cmp_ps_mask(f0, _mm512_setzero_ps(), 1),
				_mm512_set1_ps(0.5f), _mm512_set1_ps(-0.5f));
		f0 = _mm512_add_ps(f0, f1);
		f1 = _mm512_cvtepi32_ps(_mm512_cvtepi16_epi32(v0));
		f1 = _mm512_div_ps(f1, _mm512_cvtepi32_ps(_mm512_cvtepi16_epi32(v1)));
		v2 = _mm512_cvtepi32_epi16(_mm512_cvttps_epi32(f0));
		v0 = _mm512_cvtepi32_epi16(_mm512_cvttps_epi32(f1));
		v0 = _mm256_mullo_epi16(v0, v1);  
		v1 = _mm256_add_epi16(v1, _mm256_set1_epi16(-1));
		v3 = _mm256_sub_epi16(v1, _mm256_srai_epi16(v0, 15));
		v2 = _mm256_min_epi16(v2, _mm256_add_epi16(v0, _mm256_srai_epi16(v3, 1)));
		v3 = _mm256_sub_epi16(v1, _mm256_cmpgt_epi16(v0, _mm256_setzero_si256()));
		v2 = _mm256_max_epi16(v2, _mm256_sub_epi16(v0, _mm256_srai_epi16(v3, 1)));
		_mm256_storeu_si256((__m256i*)&coef[y * n], v2);
	} else
#elif 1 && defined(USE_AVX2)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y++) {
		__m128i v0, v1, v2, v3; __m256i v4, v5; __m256 f0, f1;
		v1 = _mm_loadu_si128((__m128i*)&quantval[y * n]);
		v0 = _mm_loadu_si128((__m128i*)&coef[y * n]);
		v2 = _mm_srli_epi16(v1, 1); v3 = _mm_srai_epi16(v0, 15);
		v2 = _mm_xor_si128(_mm_add_epi16(v2, v3), v3);
		v0 = _mm_add_epi16(v0, v2);
		f0 = _mm256_loadu_ps(&buf[y * n]);
		f1 = _mm256_blendv_ps(_mm256_set1_ps(0.5f), _mm256_set1_ps(-0.5f), f0);
		f0 = _mm256_add_ps(f0, f1);
		f1 = _mm256_cvtepi32_ps(_mm256_cvtepi16_epi32(v0));
		f1 = _mm256_div_ps(f1, _mm256_cvtepi32_ps(_mm256_cvtepi16_epi32(v1)));
		v4 = _mm256_cvttps_epi32(f0); v5 = _mm256_cvttps_epi32(f1);
		v4 = _mm256_permute4x64_epi64(_mm256_packs_epi32(v5, v4), 0xd8);
		v0 = _mm256_castsi256_si128(v4); v2 = _mm256_extracti128_si256(v4, 1);
		v0 = _mm_mullo_epi16(v0, v1);  
		v1 = _mm_add_epi16(v1, _mm_set1_epi16(-1));
		v3 = _mm_sub_epi16(v1, _mm_srai_epi16(v0, 15));
		v2 = _mm_min_epi16(v2, _mm_add_epi16(v0, _mm_srai_epi16(v3, 1)));
		v3 = _mm_sub_epi16(v1, _mm_cmpgt_epi16(v0, _mm_setzero_si128()));
		v2 = _mm_max_epi16(v2, _mm_sub_epi16(v0, _mm_srai_epi16(v3, 1)));
		_mm_storeu_si128((__m128i*)&coef[y * n], v2);
	} else
#elif 1 && defined(USE_SSE2)
	if (sizeof(quantval[0]) == 2 && sizeof(quantval[0]) == sizeof(coef[0]))
	for (y = 0; y < n; y++) {
		__m128i v0, v1, v2, v3; __m128 f0, f1, f2, f3, f4;
		v1 = _mm_loadu_si128((__m128i*)&quantval[y * n]);
		v0 = _mm_loadu_si128((__m128i*)&coef[y * n]);
		v2 = _mm_srli_epi16(v1, 1); v3 = _mm_srai_epi16(v0, 15);
		v2 = _mm_xor_si128(_mm_add_epi16(v2, v3), v3);
		v0 = _mm_add_epi16(v0, v2);
		v2 = _mm_setzero_si128(); v3 = _mm_srai_epi16(v0, 15);
#define M1(lo, f0, f1, x) \
	f0 = _mm_loadu_ps((float*)&buf[y * n + x]); \
	f4 = _mm_cmplt_ps(f0, _mm_setzero_ps()); \
	f4 = _mm_castsi128_ps(_mm_slli_epi32(_mm_castps_si128(f4), 31)); \
	f0 = _mm_add_ps(f0, _mm_or_ps(f4, _mm_set1_ps(0.5f))); \
	f4 = _mm_cvtepi32_ps(_mm_unpack##lo##_epi16(v1, v2)); \
	f1 = _mm_cvtepi32_ps(_mm_unpack##lo##_epi16(v0, v3)); \
	f1 = _mm_div_ps(f1, f4);
		M1(lo, f0, f1, 0) M1(hi, f2, f3, 4)
#undef M1
		v2 = _mm_packs_epi32(_mm_cvttps_epi32(f0), _mm_cvttps_epi32(f2));
		v0 = _mm_packs_epi32(_mm_cvttps_epi32(f1), _mm_cvttps_epi32(f3));
		v0 = _mm_mullo_epi16(v0, v1);  
		v1 = _mm_add_epi16(v1, _mm_set1_epi16(-1));
		v3 = _mm_sub_epi16(v1, _mm_srai_epi16(v0, 15));
		v2 = _mm_min_epi16(v2, _mm_add_epi16(v0, _mm_srai_epi16(v3, 1)));
		v3 = _mm_sub_epi16(v1, _mm_cmpgt_epi16(v0, _mm_setzero_si128()));
		v2 = _mm_max_epi16(v2, _mm_sub_epi16(v0, _mm_srai_epi16(v3, 1)));
		_mm_storeu_si128((__m128i*)&coef[y * n], v2);
	} else
#endif
	for (x = 0; x < n * n; x++) {
		int div = quantval[x], coef1 = coef[x], add;
		int dh, dl, d0 = (div - 1) >> 1, d1 = div >> 1;
		int a0 = (coef1 + (coef1 < 0 ? -d1 : d1)) / div * div;
		dh = a0 + (a0 < 0 ? d1 : d0);
		dl = a0 - (a0 > 0 ? d1 : d0);
		add = roundf(buf[x]);
		if (add > dh) add = dh;
		if (add < dl) add = dl;
		coef[x] = add;
	}
}