static int qt_ima_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int initial_predictor[2] = {0}; int initial_index[2] = {0}; int i; if (channels != 1) channels = 2; if (block_size < channels * QT_IMA_ADPCM_BLOCK_SIZE) return -1; for (i = 0; i < channels; i++) { initial_index[i] = initial_predictor[i] = (int16_t)AV_RB16(&input[i * QT_IMA_ADPCM_BLOCK_SIZE]); // mask, sign-extend, and clamp the predictor portion initial_predictor[i] &= ~0x7F; CLAMP_S16(initial_predictor[i]); // mask and clamp the index portion initial_index[i] &= 0x7F; CLAMP_0_TO_88(initial_index[i]); } // break apart all of the nibbles in the block if (channels == 1) for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) { output[i * 2 + 0] = input[2 + i] & 0x0F; output[i * 2 + 1] = input[2 + i] >> 4; } else for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++)
int qt_ima_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels) { int initial_predictor_l = 0; int initial_predictor_r = 0; int initial_index_l = 0; int initial_index_r = 0; int i; initial_predictor_l = BE_16(&input[0]); initial_index_l = initial_predictor_l; // mask, sign-extend, and clamp the predictor portion initial_predictor_l &= 0xFF80; SE_16BIT(initial_predictor_l); CLAMP_S16(initial_predictor_l); // mask and clamp the index portion initial_index_l &= 0x7F; CLAMP_0_TO_88(initial_index_l); // handle stereo if (channels > 1) { initial_predictor_r = BE_16(&input[QT_IMA_ADPCM_BLOCK_SIZE]); initial_index_r = initial_predictor_r; // mask, sign-extend, and clamp the predictor portion initial_predictor_r &= 0xFF80; SE_16BIT(initial_predictor_r); CLAMP_S16(initial_predictor_r); // mask and clamp the index portion initial_index_r &= 0x7F; CLAMP_0_TO_88(initial_index_r); } // break apart all of the nibbles in the block if (channels == 1) for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) { output[i * 2 + 0] = input[2 + i] & 0x0F; output[i * 2 + 1] = input[2 + i] >> 4; } else for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2 * 2; i++)
static void decode_nibbles(unsigned short *output, int output_size, int channels, int predictor_l, int index_l, int predictor_r, int index_r) { int step[2]; int predictor[2]; int index[2]; int diff; int i; int sign; int delta; int channel_number = 0; step[0] = adpcm_step[index_l]; step[1] = adpcm_step[index_r]; predictor[0] = predictor_l; predictor[1] = predictor_r; index[0] = index_l; index[1] = index_r; for (i = 0; i < output_size; i++) { delta = output[i]; index[channel_number] += adpcm_index[delta]; CLAMP_0_TO_88(index[channel_number]); sign = delta & 8; delta = delta & 7; diff = step[channel_number] >> 3; if (delta & 4) diff += step[channel_number]; if (delta & 2) diff += step[channel_number] >> 1; if (delta & 1) diff += step[channel_number] >> 2; if (sign) predictor[channel_number] -= diff; else predictor[channel_number] += diff; CLAMP_S16(predictor[channel_number]); output[i] = predictor[channel_number]; step[channel_number] = adpcm_step[index[channel_number]]; // toggle channel channel_number ^= channels - 1; } }
void mlib_SignalFIR_d64_to_s16( mlib_s16 *pdst, mlib_d64 *psrc, mlib_s32 n) { mlib_s32 i; #ifndef MLIB_USE_FTOI_CLAMPING for (i = 0; i < n; i++) { CLAMP_S16(pdst[i], psrc[i]); } #else /* MLIB_USE_FTOI_CLAMPING */ #ifdef _NO_LONGLONG mlib_u32 data; if (((mlib_addr)pdst & 3) != 0) { (*pdst++) = ((mlib_s32)(*psrc++)) >> 16; n--; }
static void decode_nibbles(unsigned short *output, int output_size, int channels, int predictor[2], int index[2]) { int step[2]; int i; int sign; int delta; int channel_number = 0; step[0] = adpcm_step[index[0]]; step[1] = adpcm_step[index[1]]; for (i = 0; i < output_size; i++) { delta = output[i]; sign = delta & 8; delta = delta & 7; index[channel_number] += adpcm_index[delta]; CLAMP_0_TO_88(index[channel_number]); delta = 2 * delta + 1; if (sign) delta = -delta; predictor[channel_number] += (delta * step[channel_number]) >> 3; CLAMP_S16(predictor[channel_number]); output[i] = predictor[channel_number]; step[channel_number] = adpcm_step[index[channel_number]]; // toggle channel channel_number ^= channels - 1; } }
static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int current_channel = 0; int idelta[2]; int sample1[2]; int sample2[2]; int coeff1[2]; int coeff2[2]; int stream_ptr = 0; int out_ptr = 0; int upper_nibble = 1; int nibble; int snibble; // signed nibble int predictor; // fetch the header information, in stereo if both channels are present if (input[stream_ptr] > 6) mp_msg(MSGT_DECAUDIO, MSGL_WARN, "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", input[stream_ptr]); coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; stream_ptr++; if (channels == 2) { if (input[stream_ptr] > 6) mp_msg(MSGT_DECAUDIO, MSGL_WARN, "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", input[stream_ptr]); coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; stream_ptr++; } idelta[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(idelta[0]); if (channels == 2) { idelta[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(idelta[1]); } sample1[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample1[0]); if (channels == 2) { sample1[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample1[1]); } sample2[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample2[0]); if (channels == 2) { sample2[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample2[1]); } if (channels == 1) { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample1[0]; } else { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample2[1]; output[out_ptr++] = sample1[0]; output[out_ptr++] = sample1[1]; } while (stream_ptr < block_size) { // get the next nibble if (upper_nibble) nibble = snibble = input[stream_ptr] >> 4; else nibble = snibble = input[stream_ptr++] & 0x0F; upper_nibble ^= 1; SE_4BIT(snibble); predictor = ( ((sample1[current_channel] * coeff1[current_channel]) + (sample2[current_channel] * coeff2[current_channel])) / 256) + (snibble * idelta[current_channel]); CLAMP_S16(predictor); sample2[current_channel] = sample1[current_channel]; sample1[current_channel] = predictor; output[out_ptr++] = predictor; // compute the next adaptive scale factor (a.k.a. the variable idelta) idelta[current_channel] = (ms_adapt_table[nibble] * idelta[current_channel]) / 256; CLAMP_ABOVE_16(idelta[current_channel]); // toggle the channel current_channel ^= channels - 1; }
static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int current_channel = 0; int coeff_idx; int idelta[2]; int sample1[2]; int sample2[2]; int coeff1[2]; int coeff2[2]; int stream_ptr = 0; int out_ptr = 0; int upper_nibble = 1; int nibble; int snibble; // signed nibble int predictor; if (channels != 1) channels = 2; if (block_size < 7 * channels) return -1; // fetch the header information, in stereo if both channels are present coeff_idx = check_coeff(input[stream_ptr]); coeff1[0] = ms_adapt_coeff1[coeff_idx]; coeff2[0] = ms_adapt_coeff2[coeff_idx]; stream_ptr++; if (channels == 2) { coeff_idx = check_coeff(input[stream_ptr]); coeff1[1] = ms_adapt_coeff1[coeff_idx]; coeff2[1] = ms_adapt_coeff2[coeff_idx]; stream_ptr++; } idelta[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; if (channels == 2) { idelta[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; } sample1[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; if (channels == 2) { sample1[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; } sample2[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; if (channels == 2) { sample2[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; } if (channels == 1) { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample1[0]; } else { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample2[1]; output[out_ptr++] = sample1[0]; output[out_ptr++] = sample1[1]; } while (stream_ptr < block_size) { // get the next nibble if (upper_nibble) nibble = snibble = input[stream_ptr] >> 4; else nibble = snibble = input[stream_ptr++] & 0x0F; upper_nibble ^= 1; SE_4BIT(snibble); // should this really be a division and not a shift? // coefficients were originally scaled by for, which might have // been an optimization for 8-bit CPUs _if_ a shift is correct predictor = ( ((sample1[current_channel] * coeff1[current_channel]) + (sample2[current_channel] * coeff2[current_channel])) / 64) + (snibble * idelta[current_channel]); CLAMP_S16(predictor); sample2[current_channel] = sample1[current_channel]; sample1[current_channel] = predictor; output[out_ptr++] = predictor; // compute the next adaptive scale factor (a.k.a. the variable idelta) idelta[current_channel] = (ms_adapt_table[nibble] * idelta[current_channel]) / 256; CLAMP_ABOVE_16(idelta[current_channel]); // toggle the channel current_channel ^= channels - 1; }
// note: This decoder assumes the format 0x62 data always comes in // stereo flavor static int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input, int block_size) { int sum_pred; int diff_pred; int sum_index; int diff_index; int diff_channel; int in_ptr = 0x10; int out_ptr = 0; unsigned char last_byte = 0; unsigned char nibble; int decode_top_nibble_next = 0; // ADPCM work variables int sign; int delta; int step; int diff; sum_pred = LE_16(&input[10]); diff_pred = LE_16(&input[12]); SE_16BIT(sum_pred); SE_16BIT(diff_pred); diff_channel = diff_pred; sum_index = input[14]; diff_index = input[15]; while (in_ptr < block_size - !decode_top_nibble_next) // while (in_ptr < 2048) { // process the first predictor of the sum channel DK3_GET_NEXT_NIBBLE(); step = adpcm_step[sum_index]; sign = nibble & 8; delta = nibble & 7; diff = step >> 3; if (delta & 4) diff += step; if (delta & 2) diff += step >> 1; if (delta & 1) diff += step >> 2; if (sign) sum_pred -= diff; else sum_pred += diff; CLAMP_S16(sum_pred); sum_index += adpcm_index[nibble]; CLAMP_0_TO_88(sum_index); // process the diff channel predictor DK3_GET_NEXT_NIBBLE(); step = adpcm_step[diff_index]; sign = nibble & 8; delta = nibble & 7; diff = step >> 3; if (delta & 4) diff += step; if (delta & 2) diff += step >> 1; if (delta & 1) diff += step >> 2; if (sign) diff_pred -= diff; else diff_pred += diff; CLAMP_S16(diff_pred); diff_index += adpcm_index[nibble]; CLAMP_0_TO_88(diff_index); // output the first pair of stereo PCM samples diff_channel = (diff_channel + diff_pred) / 2; output[out_ptr++] = sum_pred + diff_channel; output[out_ptr++] = sum_pred - diff_channel; // process the second predictor of the sum channel DK3_GET_NEXT_NIBBLE(); step = adpcm_step[sum_index]; sign = nibble & 8; delta = nibble & 7; diff = step >> 3; if (delta & 4) diff += step; if (delta & 2) diff += step >> 1; if (delta & 1) diff += step >> 2; if (sign) sum_pred -= diff; else sum_pred += diff; CLAMP_S16(sum_pred); sum_index += adpcm_index[nibble]; CLAMP_0_TO_88(sum_index); // output the second pair of stereo PCM samples output[out_ptr++] = sum_pred + diff_channel; output[out_ptr++] = sum_pred - diff_channel; } return out_ptr; }
mlib_status __mlib_ImageThresh1( mlib_image *dst, const mlib_image *src, const mlib_s32 *thresh, const mlib_s32 *ghigh, const mlib_s32 *glow) { mlib_s32 nchan, width, height, sstride, dstride; void *sdata, *ddata; mlib_type type; mlib_d64 cnst[6]; mlib_s32 i, t_sh, algn; MLIB_IMAGE_CHECK(src); MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_SIZE_EQUAL(src, dst); MLIB_IMAGE_CHAN_EQUAL(src, dst); MLIB_IMAGE_TYPE_DSTBIT_OR_EQ(src, dst); if (thresh == NULL) return (MLIB_NULLPOINTER); if (ghigh == NULL) return (MLIB_NULLPOINTER); if (glow == NULL) return (MLIB_NULLPOINTER); MLIB_IMAGE_GET_ALL_PARAMS(dst, type, nchan, width, height, dstride, ddata); sstride = mlib_ImageGetStride(src); sdata = mlib_ImageGetData(src); if (type == MLIB_BIT) { return (mlib_ImageThresh1B(dst, src, thresh, ghigh, glow)); } else if (type == MLIB_BYTE) { mlib_u8 *pcol1 = (void *)cnst; mlib_u8 *pcol2 = (void *)(cnst + 2); mlib_u8 *pcol3 = (void *)(cnst + 4); t_sh = 0; for (i = 0; i < nchan; i++) { pcol1[i] = CLAMP_U8(thresh[i]); pcol2[i] = ghigh[i]; pcol3[i] = glow[i]; if (thresh[i] < MLIB_U8_MIN) pcol3[i] = pcol2[i]; } for (i = nchan; i < 16; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; pcol3[i] = pcol3[i - nchan]; } } else if (type == MLIB_SHORT) { mlib_s16 *pcol1 = (void *)cnst; mlib_s16 *pcol2 = (void *)(cnst + 2); mlib_s16 *pcol3 = (void *)(cnst + 4); t_sh = 1; for (i = 0; i < nchan; i++) { pcol1[i] = CLAMP_S16(thresh[i]); pcol2[i] = ghigh[i]; pcol3[i] = glow[i]; if (thresh[i] < MLIB_S16_MIN) pcol3[i] = pcol2[i]; } for (i = nchan; i < 8; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; pcol3[i] = pcol3[i - nchan]; } } else if (type == MLIB_USHORT) { mlib_s16 *pcol1 = (void *)cnst; mlib_s16 *pcol2 = (void *)(cnst + 2); mlib_s16 *pcol3 = (void *)(cnst + 4); t_sh = 1; for (i = 0; i < nchan; i++) { pcol1[i] = CLAMP_U16(thresh[i]); pcol2[i] = ghigh[i]; pcol3[i] = glow[i]; if (thresh[i] < MLIB_U16_MIN) pcol3[i] = pcol2[i]; } for (i = nchan; i < 8; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; pcol3[i] = pcol3[i - nchan]; } } else { mlib_s32 *pcol1 = (void *)cnst; mlib_s32 *pcol2 = (void *)(cnst + 2); mlib_s32 *pcol3 = (void *)(cnst + 4); t_sh = 2; for (i = 0; i < nchan; i++) { pcol1[i] = thresh[i]; pcol2[i] = ghigh[i]; pcol3[i] = glow[i]; } for (i = nchan; i < 4; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; pcol3[i] = pcol3[i - nchan]; } } if (sstride == dstride && sstride == ((nchan * width) << t_sh)) { width *= height; height = 1; } algn = (int)sdata | (int)ddata; if (height > 1) algn |= (sstride | dstride); algn &= 7; if (nchan == 3) algn = 1; sstride >>= t_sh; dstride >>= t_sh; switch (type) { case MLIB_BYTE: return mlib_v_ImageThresh1_U8_3(sdata, ddata, sstride, dstride, width, height, nchan, cnst); case MLIB_SHORT: if (algn == 0) { return mlib_v_ImageThresh1_S16_A(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } else { return mlib_v_ImageThresh1_S16_3(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } case MLIB_USHORT: if (algn == 0) { return mlib_v_ImageThresh1_U16_A(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } else { return mlib_v_ImageThresh1_U16_3(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } case MLIB_INT: if (nchan == 4) { return mlib_v_ImageThresh1_S32_2(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } if (algn == 0) { return mlib_v_ImageThresh1_S32_A(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } else { return mlib_v_ImageThresh1_S32_3(sdata, ddata, sstride, dstride, width, height, nchan, cnst); } default: return (MLIB_FAILURE); } }
mlib_status __mlib_ImageReplaceColor( mlib_image *dst, const mlib_image *src, const mlib_s32 *color1, const mlib_s32 *color2) { mlib_s32 nchan, width, height, sstride, dstride; void *sdata, *ddata; mlib_type type; __m128i cnst[6]; mlib_s32 i, t_sh; MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_CHECK(src); MLIB_IMAGE_FULL_EQUAL(dst, src); if (color1 == NULL) return (MLIB_NULLPOINTER); if (color2 == NULL) return (MLIB_NULLPOINTER); MLIB_IMAGE_GET_ALL_PARAMS( dst, type, nchan, width, height, dstride, ddata); sstride = mlib_ImageGetStride(src); sdata = mlib_ImageGetData(src); if (type == MLIB_BYTE) { mlib_u8 *pcol1 = (void *)cnst; mlib_u8 *pcol2 = (void *)(cnst + 3); t_sh = 0; for (i = 0; i < nchan; i++) { pcol1[i] = CLAMP_U8(color1[i]); pcol2[i] = color2[i]; if (pcol1[i] != color1[i]) pcol2[i] = pcol1[i]; } for (i = nchan; i < 48; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; } } else if (type == MLIB_SHORT) { mlib_s16 *pcol1 = (void *)cnst; mlib_s16 *pcol2 = (void *)(cnst + 3); t_sh = 1; for (i = 0; i < nchan; i++) { pcol1[i] = CLAMP_S16(color1[i]); pcol2[i] = color2[i]; if (pcol1[i] != color1[i]) pcol2[i] = pcol1[i]; } for (i = nchan; i < 24; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; } } else if (type == MLIB_USHORT) { mlib_u16 *pcol1 = (void *)cnst; mlib_u16 *pcol2 = (void *)(cnst + 3); t_sh = 1; for (i = 0; i < nchan; i++) { pcol1[i] = CLAMP_U16(color1[i]); pcol2[i] = color2[i]; if (pcol1[i] != color1[i]) pcol2[i] = pcol1[i]; } for (i = nchan; i < 24; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; } } else { mlib_s32 *pcol1 = (void *)cnst; mlib_s32 *pcol2 = (void *)(cnst + 3); t_sh = 2; for (i = 0; i < nchan; i++) { pcol1[i] = color1[i]; pcol2[i] = color2[i]; } for (i = nchan; i < 12; i++) { pcol1[i] = pcol1[i - nchan]; pcol2[i] = pcol2[i - nchan]; } } if (sstride == dstride && sstride == ((nchan * width) << t_sh)) { width *= height; height = 1; } sstride >>= t_sh; dstride >>= t_sh; switch (type) { case MLIB_BYTE: if (nchan == 3) { return mlib_s_ImageReplaceColor_U8_3( sdata, ddata, sstride, dstride, width, height, nchan, cnst); } else { return mlib_s_ImageReplaceColor_U8_124( sdata, ddata, sstride, dstride, width, height, nchan, cnst); } case MLIB_SHORT: case MLIB_USHORT: if (nchan == 3) { return mlib_s_ImageReplaceColor_S16_3( sdata, ddata, sstride, dstride, width, height, nchan, cnst); } else { return mlib_s_ImageReplaceColor_S16_124( sdata, ddata, sstride, dstride, width, height, nchan, cnst); } case MLIB_INT: if (nchan == 3) { return mlib_s_ImageReplaceColor_S32_3( sdata, ddata, sstride, dstride, width, height, nchan, cnst); } else { return mlib_s_ImageReplaceColor_S32_124( sdata, ddata, sstride, dstride, width, height, nchan, cnst); } default: return (MLIB_FAILURE); } }