static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant) { int32_t peak; int our_nscale, try_remove; softfloat our_quant; av_assert0(peak_cb <= 0); av_assert0(peak_cb >= -2047); our_nscale = 127; peak = cb_to_level[-peak_cb]; for (try_remove = 64; try_remove > 0; try_remove >>= 1) { if (scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e <= 17) continue; our_quant.m = mul32(scalefactor_inv[our_nscale - try_remove].m, stepsize_inv[abits].m); our_quant.e = scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e - 17; if ((quant_levels[abits] - 1) / 2 < quantize_value(peak, our_quant)) continue; our_nscale -= try_remove; } if (our_nscale >= 125) our_nscale = 124; quant->m = mul32(scalefactor_inv[our_nscale].m, stepsize_inv[abits].m); quant->e = scalefactor_inv[our_nscale].e + stepsize_inv[abits].e - 17; av_assert0((quant_levels[abits] - 1) / 2 >= quantize_value(peak, *quant)); return our_nscale; }
static void process_row_resilient (GeglBufferIterator *gi, guint channel_mask [4], guint channel_bits [4], gint y, GeglRandom *rand) { guint16 *data_in = (guint16*) gi->data [0]; guint16 *data_out = (guint16*) gi->data [1]; guint x; for (x = 0; x < gi->roi->width; x++) { guint pixel = 4 * (gi->roi->width * y + x); guint ch; for (ch = 0; ch < 4; ch++) { gdouble value; gdouble value_clamped; gdouble quantized; gint r = REDUCE_16B (gegl_random_int (rand, gi->roi->x + x, gi->roi->y + y, 0, ch)); value = data_in [pixel + ch]; value = value + ((65535.0 / (8 * value + 48 * 65535)) + 1.2) * (r / (1 << channel_bits [ch])); value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); data_out [pixel + ch] = (guint16) quantized; } } }
static void process_row_bayer (GeglBufferIterator *gi, guint channel_mask [4], guint channel_bits [4], gint y) { guint16 *data_in = (guint16*) gi->data [0]; guint16 *data_out = (guint16*) gi->data [1]; guint x; for (x = 0; x < gi->roi->width; x++) { guint pixel = 4 * (gi->roi->width * y + x); guint ch; for (ch = 0; ch < 4; ch++) { gdouble bayer; gdouble value; gdouble value_clamped; gdouble quantized; bayer = bayer_matrix_8x8 [((gi->roi->y + y) % 8) * 8 + ((gi->roi->x + x) % 8)]; bayer = ((bayer - 32) * 65536.0 / 65.0) / (1 << (channel_bits [ch] - 1)); value = data_in [pixel + ch] + bayer; value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); data_out [pixel + ch] = (guint16) quantized; } } }
static void inline process_row_random_covariant (GeglBufferIterator *gi, guint channel_mask [4], guint channel_bits [4], gint y, GeglRandom *rand) { guint16 *data_in = (guint16*) gi->data [0]; guint16 *data_out = (guint16*) gi->data [1]; guint x; for (x = 0; x < gi->roi->width; x++) { guint pixel = 4 * (gi->roi->width * y + x); guint ch; gint r = REDUCE_16B (gegl_random_int (rand, gi->roi->x + x, gi->roi->y + y, 0, 0)); for (ch = 0; ch < 4; ch++) { gfloat value; gfloat value_clamped; gfloat quantized; value = data_in [pixel + ch] + (r / (1 << channel_bits [ch])); value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); data_out [pixel + ch] = (guint16) quantized; } } }
static void inline process_row_arithmetic_xor_covariant (GeglBufferIterator *gi, guint channel_mask [4], guint channel_bits [4], gint y) { guint16 *data_in = (guint16*) gi->data [0]; guint16 *data_out = (guint16*) gi->data [1]; guint x; for (x = 0; x < gi->roi->width; x++) { guint pixel = 4 * (gi->roi->width * y + x); guint ch; for (ch = 0; ch < 4; ch++) { gint u = gi->roi->x + x; gint v = gi->roi->y + y; gfloat mask; gfloat value; gfloat value_clamped; gfloat quantized; mask = ((u ^ v * 149) * 1234) & 511; mask = ((mask - 257) * 65536.0 / 512.0) / (1 << (channel_bits [ch] - 1)); value = data_in [pixel + ch] + mask; value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); data_out [pixel + ch] = (guint16) quantized; } } }
static void quantize_all(DCAContext *c) { int sample, band, ch; for (sample = 0; sample < SUBBAND_SAMPLES; sample++) for (band = 0; band < 32; band++) for (ch = 0; ch < c->fullband_channels; ch++) c->quantized[sample][band][ch] = quantize_value(c->subband[sample][band][ch], c->quant[band][ch]); }
static void put_subframe(DCAContext *c, int subframe) { int i, band, ss, ch; /* Subsubframes count */ put_bits(&c->pb, 2, SUBSUBFRAMES -1); /* Partial subsubframe sample count: dummy */ put_bits(&c->pb, 3, 0); /* Prediction mode: no ADPCM, in each channel and subband */ for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCA_SUBBANDS; band++) put_bits(&c->pb, 1, 0); /* Prediction VQ address: not transmitted */ /* Bit allocation index */ for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCA_SUBBANDS; band++) put_bits(&c->pb, 5, c->abits[band][ch]); if (SUBSUBFRAMES > 1) { /* Transition mode: none for each channel and subband */ for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCA_SUBBANDS; band++) put_bits(&c->pb, 1, 0); /* codebook A4 */ } /* Scale factors */ for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCA_SUBBANDS; band++) put_bits(&c->pb, 7, c->scale_factor[band][ch]); /* Joint subband scale factor codebook select: not transmitted */ /* Scale factors for joint subband coding: not transmitted */ /* Stereo down-mix coefficients: not transmitted */ /* Dynamic range coefficient: not transmitted */ /* Stde information CRC check word: not transmitted */ /* VQ encoded high frequency subbands: not transmitted */ /* LFE data: 8 samples and scalefactor */ if (c->lfe_channel) { for (i = 0; i < DCA_LFE_SAMPLES; i++) put_bits(&c->pb, 8, quantize_value(c->downsampled_lfe[i], c->lfe_quant) & 0xff); put_bits(&c->pb, 8, c->lfe_scale_factor); } /* Audio data (subsubframes) */ for (ss = 0; ss < SUBSUBFRAMES ; ss++) for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCA_SUBBANDS; band++) put_subframe_samples(c, ss, band, ch); /* DSYNC */ put_bits(&c->pb, 16, 0xffff); }
static void process_random_covariant (GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, guint *channel_bits) { GeglRectangle line_rect; guint16 *line_buf; guint channel_mask [4]; guint y; line_rect.x = result->x; line_rect.y = result->y; line_rect.width = result->width; line_rect.height = 1; line_buf = g_new (guint16, line_rect.width * 4); generate_channel_masks (channel_bits, channel_mask); for (y = 0; y < result->height; y++) { guint x; gegl_buffer_get (input, &line_rect, 1.0, babl_format ("RGBA u16"), line_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); for (x = 0; x < result->width; x++) { guint16 *pixel = &line_buf [x * 4]; guint ch; gint r = g_random_int_range (-65536, 65536); for (ch = 0; ch < 4; ch++) { gdouble value; gdouble value_clamped; gdouble quantized; value = pixel [ch] + (r / (1 << channel_bits [ch])); value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); pixel [ch] = (guint16) quantized; } } gegl_buffer_set (output, &line_rect, 0, babl_format ("RGBA u16"), line_buf, GEGL_AUTO_ROWSTRIDE); line_rect.y++; } g_free (line_buf); }
static void process_bayer (GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, guint *channel_bits) { GeglRectangle line_rect; guint16 *line_buf; guint channel_mask [4]; guint y; line_rect.x = result->x; line_rect.y = result->y; line_rect.width = result->width; line_rect.height = 1; line_buf = g_new (guint16, line_rect.width * 4); generate_channel_masks (channel_bits, channel_mask); for (y = 0; y < result->height; y++) { guint x; gegl_buffer_get (input, 1.0, &line_rect, babl_format ("RGBA u16"), line_buf, GEGL_AUTO_ROWSTRIDE); for (x = 0; x < result->width; x++) { guint16 *pixel = &line_buf [x * 4]; guint ch; for (ch = 0; ch < 4; ch++) { gdouble value; gdouble value_clamped; gdouble quantized; value = pixel [ch] + ((bayer_matrix_8x8 [(y % 8) * 8 + (x % 8)] - 32) * 65536.0 / 65.0) / (1 << (channel_bits [ch] - 1)); value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); pixel [ch] = (guint16) quantized; } } gegl_buffer_set (output, &line_rect, babl_format ("RGBA u16"), line_buf, GEGL_AUTO_ROWSTRIDE); line_rect.y++; } g_free (line_buf); }
static void process_no_dither (GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, guint *channel_bits) { GeglRectangle line_rect; guint16 *line_buf; guint channel_mask [4]; guint y; line_rect.x = result->x; line_rect.y = result->y; line_rect.width = result->width; line_rect.height = 1; line_buf = g_new (guint16, line_rect.width * 4); generate_channel_masks (channel_bits, channel_mask); for (y = 0; y < result->height; y++) { guint x; gegl_buffer_get (input, &line_rect, 1.0, babl_format ("RGBA u16"), line_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); for (x = 0; x < result->width; x++) { guint16 *pixel = &line_buf [x * 4]; guint ch; for (ch = 0; ch < 4; ch++) { pixel [ch] = quantize_value (pixel [ch], channel_bits [ch], channel_mask [ch]); } } gegl_buffer_set (output, &line_rect, 0, babl_format ("RGBA u16"), line_buf, GEGL_AUTO_ROWSTRIDE); line_rect.y++; } g_free (line_buf); }
static void process_row_no_dither (GeglBufferIterator *gi, guint channel_mask [4], guint channel_bits [4], guint y) { guint16 *data_in = (guint16*) gi->data [0]; guint16 *data_out = (guint16*) gi->data [1]; guint x; for (x = 0; x < gi->roi->width; x++) { guint pixel = 4 * (gi->roi->width * y + x); guint ch; for (ch = 0; ch < 4; ch++) { data_out [pixel + ch] = (guint16) quantize_value (data_in [pixel + ch], channel_bits [ch], channel_mask [ch]); } } }
static void process_floyd_steinberg (GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, guint *channel_bits) { GeglRectangle line_rect; guint16 *line_buf; gdouble *error_buf [2]; guint channel_mask [4]; gint y; line_rect.x = result->x; line_rect.y = result->y; line_rect.width = result->width; line_rect.height = 1; line_buf = g_new (guint16, line_rect.width * 4); error_buf [0] = g_new0 (gdouble, line_rect.width * 4); error_buf [1] = g_new0 (gdouble, line_rect.width * 4); generate_channel_masks (channel_bits, channel_mask); for (y = 0; y < result->height; y++) { gdouble *error_buf_swap; gint step; gint start_x; gint end_x; gint x; /* Serpentine scanning; reverse direction every row */ if (y & 1) { start_x = result->width - 1; end_x = -1; step = -1; } else { start_x = 0; end_x = result->width; step = 1; } /* Pull input row */ gegl_buffer_get (input, &line_rect, 1.0, babl_format ("R'G'B'A u16"), line_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); /* Process the row */ for (x = start_x; x != end_x; x += step) { guint16 *pixel = &line_buf [x * 4]; guint ch; for (ch = 0; ch < 4; ch++) { gdouble value; gdouble value_clamped; gdouble quantized; gdouble qerror; value = pixel [ch] + error_buf [0] [x * 4 + ch]; value_clamped = CLAMP (value, 0.0, 65535.0); quantized = quantize_value ((guint) (value_clamped + 0.5), channel_bits [ch], channel_mask [ch]); qerror = value - quantized; pixel [ch] = (guint16) quantized; /* Distribute the error */ error_buf [1] [x * 4 + ch] += qerror * 5.0 / 16.0; /* Down */ if (x + step >= 0 && x + step < result->width) { error_buf [0] [(x + step) * 4 + ch] += qerror * 6.0 / 16.0; /* Ahead */ error_buf [1] [(x + step) * 4 + ch] += qerror * 1.0 / 16.0; /* Down, ahead */ } if (x - step >= 0 && x - step < result->width) { error_buf [1] [(x - step) * 4 + ch] += qerror * 3.0 / 16.0; /* Down, behind */ } } } /* Swap error accumulation rows */ error_buf_swap = error_buf [0]; error_buf [0] = error_buf [1]; error_buf [1] = error_buf_swap; /* Clear error buffer for next-plus-one line */ memset (error_buf [1], 0, line_rect.width * 4 * sizeof (gdouble)); /* Push output row */ gegl_buffer_set (output, &line_rect, 0, babl_format ("R'G'B'A u16"), line_buf, GEGL_AUTO_ROWSTRIDE); line_rect.y++; } g_free (line_buf); g_free (error_buf [0]); g_free (error_buf [1]); }