Example #1
0
File: pvq.c Project: mbebenita/aom
/* Maps each possible size (n) in the split k-tokenizer to a different value.
   Possible values of n are:
   2, 3, 4, 7, 8, 14, 15, 16, 31, 32, 63, 64, 127, 128
   Since we don't care about the order (even in the bit-stream) the simplest
   ordering (implemented here) is:
   14, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 */
int od_pvq_size_ctx(int n) {
  int logn;
  int odd;
  logn = OD_ILOG(n - 1);
  odd = n & 1;
  return 2*logn - 1 - odd - 7*(n == 14);
}
Example #2
0
int image_init(image *img, jpeg_header *header) {
  int hmax;
  int vmax;
  int i;
  memset(img, 0, sizeof(image));
  img->width = header->width;
  img->height = header->height;
  img->nplanes = header->ncomps;
  hmax = 0;
  vmax = 0;
  for (i = 0; i < img->nplanes; i++) {
    jpeg_component *comp;
    comp = &header->comp[i];
    hmax = OD_MAXI(hmax, comp->hsamp);
    vmax = OD_MAXI(vmax, comp->vsamp);
  }
  for (i = 0; i < img->nplanes; i++) {
    jpeg_component *comp;
    image_plane *plane;
    comp = &header->comp[i];
    plane = &img->plane[i];
    plane->width = comp->hblocks << 3;
    plane->height = comp->vblocks << 3;
    /* TODO support 16-bit images */
    plane->xstride = 1;
    plane->ystride = plane->xstride*plane->width;
    plane->xdec = OD_ILOG(hmax) - OD_ILOG(comp->hsamp);
    plane->ydec = OD_ILOG(vmax) - OD_ILOG(comp->vsamp);
    plane->data = od_aligned_malloc(plane->ystride*plane->height, IMAGE_ALIGN);
    if (plane->data == NULL) {
      image_clear(img);
      return EXIT_FAILURE;
    }
    plane->coef = od_aligned_malloc(plane->width*plane->height*sizeof(short),
     IMAGE_ALIGN);
    if (plane->coef == NULL) {
      image_clear(img);
      return EXIT_FAILURE;
    }
  }
  img->pixels = od_aligned_malloc(img->width*img->height*3, IMAGE_ALIGN);
  if (img->pixels == NULL) {
    image_clear(img);
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
Example #3
0
File: pvq.c Project: mbebenita/aom
/* Computes an upper-bound on the number of bits required to store the L2 norm
   of a vector (excluding sign). */
int od_vector_log_mag(const od_coeff *x, int n) {
  int i;
  int32_t sum;
  sum = 0;
  for (i = 0; i < n; i++) {
    int16_t tmp;
    tmp = x[i] >> 8;
    sum += tmp*(int32_t)tmp;
  }
  /* We add one full bit (instead of rounding OD_ILOG() up) for safety because
     the >> 8 above causes the sum to be slightly underestimated. */
  return 8 + 1 + OD_ILOG(n + sum)/2;
}
Example #4
0
File: pvq.c Project: mbebenita/aom
static int32_t od_pow(int32_t x, od_val16 beta)
{
  int16_t t;
  int xshift;
  int log2_x;
  od_val32 logr;
  /*FIXME: this conditional is to avoid doing log2(0).*/
  if (x == 0)
    return 0;
  log2_x = (OD_ILOG(x) - 1);
  xshift = log2_x - OD_LOG2_INSHIFT;
  /*t should be in range [0.0, 1.0[ in Q(OD_LOG2_INSHIFT).*/
  t = OD_VSHR(x, xshift) - (1 << OD_LOG2_INSHIFT);
  /*log2(g/OD_COMPAND_SCALE) = log2(x) - OD_COMPAND_SHIFT in
     Q(OD_LOG2_OUTSHIFT).*/
  logr = od_log2(t) + (log2_x - OD_COMPAND_SHIFT)*OD_LOG2_OUTSCALE;
  logr = OD_MULT16_32_QBETA(beta, logr);
  return od_exp2(logr);
}
Example #5
0
File: pvq.c Project: mbebenita/aom
static od_val16 od_rcp(od_val16 x)
{
  int i;
  od_val16 n;
  od_val16 r;
  i = OD_ILOG(x) - 1;
  /*n is Q15 with range [0,1).*/
  n = OD_VSHR_ROUND(x, i - OD_RCP_INSHIFT) - (1 << OD_RCP_INSHIFT);
  /*Start with a linear approximation:
    r = 1.8823529411764706-0.9411764705882353*n.
    The coefficients and the result are Q14 in the range [15420,30840].*/
  r = 30840 + OD_MULT16_16_Q15(-15420, n);
  /*Perform two Newton iterations:
    r -= r*((r*n)-1.Q15)
       = r*((r*n)+(r-1.Q15)).*/
  r = r - OD_MULT16_16_Q15(r, (OD_MULT16_16_Q15(r, n) + r - 32768));
  /*We subtract an extra 1 in the second iteration to avoid overflow; it also
     neatly compensates for truncation error in the rest of the process.*/
  r = r - (1 + OD_MULT16_16_Q15(r, OD_MULT16_16_Q15(r, n) + r - 32768));
  /*r is now the Q15 solution to 2/(n+1), with a maximum relative error
     of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute
     error of 1.24665/32768.*/
  return OD_VSHR_ROUND(r, i - OD_RCP_OUTSHIFT);
}
Example #6
0
File: pvq.c Project: mbebenita/aom
/** Applies Householder reflection from compute_householder(). The
 * reflection is its own inverse.
 *
 * @param [out]     out    reflected vector
 * @param [in]      x      vector to be reflected
 * @param [in]      r      reflection
 * @param [in]      n      number of dimensions in x,r
 */
void od_apply_householder(od_val16 *out, const od_val16 *x, const od_val16 *r,
 int n) {
  int i;
  od_val32 proj;
  od_val16 proj_1;
  od_val32 l2r;
#if !defined(OD_FLOAT_PVQ)
  od_val16 proj_norm;
  od_val16 l2r_norm;
  od_val16 rcp;
  int proj_shift;
  int l2r_shift;
  int outshift;
#endif
  /*FIXME: Can we get l2r and/or l2r_shift from an earlier computation?*/
  l2r = 0;
  for (i = 0; i < n; i++) {
    l2r += OD_MULT16_16(r[i], r[i]);
  }
  /* Apply Householder reflection */
  proj = 0;
  for (i = 0; i < n; i++) {
    proj += OD_MULT16_16(r[i], x[i]);
  }
#if defined(OD_FLOAT_PVQ)
  proj_1 = proj*2./(1e-100 + l2r);
  for (i = 0; i < n; i++) {
    out[i] = x[i] - r[i]*proj_1;
  }
#else
  /*l2r_norm is [0.5, 1.0[ in Q15.*/
  l2r_shift = (OD_ILOG(l2r) - 1) - 14;
  l2r_norm = OD_VSHR_ROUND(l2r, l2r_shift);
  rcp = od_rcp(l2r_norm);
  proj_shift = (OD_ILOG(abs(proj)) - 1) - 14;
  /*proj_norm is [0.5, 1.0[ in Q15.*/
  proj_norm = OD_VSHR_ROUND(proj, proj_shift);
  proj_1 = OD_MULT16_16_Q15(proj_norm, rcp);
  /*The proj*2. in the float code becomes -1 in the final outshift.
    The sign of l2r_shift is positive since we're taking the reciprocal of
     l2r_norm and this is a right shift.*/
  outshift = OD_MINI(30, OD_RCP_OUTSHIFT - proj_shift - 1 + l2r_shift);
  if (outshift >= 0) {
    for (i = 0; i < n; i++) {
      int32_t tmp;
      tmp = OD_MULT16_16(r[i], proj_1);
      tmp = OD_SHR_ROUND(tmp, outshift);
      out[i] = x[i] - tmp;
    }
  }
  else {
    /*FIXME: Can we make this case impossible?
      Right now, if r[] is all zeros except for 1, 2, or 3 ones, and
       if x[] is all zeros except for large values at the same position as the
       ones in r[], then we can end up with a shift of -1.*/
    for (i = 0; i < n; i++) {
      int32_t tmp;
      tmp = OD_MULT16_16(r[i], proj_1);
      tmp = OD_SHL(tmp, -outshift);
      out[i] = x[i] - tmp;
    }
  }
#endif
}