Esempio n. 1
0
/** Quantizes a scalar with rate-distortion optimization (RDO)
 * @param [in] x      unquantized value
 * @param [in] q      quantization step size
 * @param [in] delta0 rate increase for encoding a 1 instead of a 0
 * @retval quantized value
 */
int od_rdo_quant(od_coeff x, int q, double delta0) {
  int threshold;
  /* Optimal quantization threshold is 1/2 + lambda*delta_rate/2. See
     Jmspeex' Journal of Dubious Theoretical Results for details. */
  threshold = 128 + OD_CLAMPI(0, (int)(256*OD_PVQ_LAMBDA*delta0/2), 128);
  if (abs(x) < q*threshold/256) {
    return 0;
  }
  else {
    return OD_DIV_R0(x, q);
  }
}
Esempio n. 2
0
void image_data_files_block(image_data *_this,const unsigned char *_data,
 int _stride,int _bi,int _bj,image_files *_files){
  int            mode;
  od_coeff      *p;
  int            j;
  int            i;
  od_coeff       v;
  unsigned char  buf[B_SZ*B_SZ];

  mode=_this->mode[_bj*_this->nxblocks+_bi];

  od_rgba16_image_draw_point(&_files->map,_bi,_bj,COLORS[mode]);

  p=&_this->pre[_this->pre_stride*(B_SZ*_bj+(3*B_SZ>>1))+B_SZ*_bi+(3*B_SZ>>1)];
  for(j=0;j<B_SZ;j++){
    for(i=0;i<B_SZ;i++){
      v=(p[_this->pre_stride*j+i]+INPUT_SCALE*128+INPUT_SCALE/2)/INPUT_SCALE;
      buf[B_SZ*j+i]=OD_CLAMPI(0,v,255);
    }
  }
  image_draw_block(&_files->raw,B_SZ*_bi,B_SZ*_bj,buf,B_SZ);

  p=&_this->post[_this->post_stride*(B_SZ*_bj+(B_SZ>>1))+B_SZ*_bi+(B_SZ>>1)];
  for(j=0;j<B_SZ;j++){
    for(i=0;i<B_SZ;i++){
      v=(p[_this->post_stride*j+i]+INPUT_SCALE*128+INPUT_SCALE/2)/INPUT_SCALE;
      buf[B_SZ*j+i]=OD_CLAMPI(0,v,255);
    }
  }
  image_draw_block(&_files->pred,B_SZ*_bi,B_SZ*_bj,buf,B_SZ);

  for(j=0;j<B_SZ;j++){
    for(i=0;i<B_SZ;i++){
      buf[B_SZ*j+i]=OD_CLAMPI(0,_data[_stride*j+i]-buf[B_SZ*j+i]+128,255);
    }
  }
  image_draw_block(&_files->res,B_SZ*_bi,B_SZ*_bj,buf,B_SZ);
}
Esempio n. 3
0
static int calc_y(int32_t _r,int32_t _g,int32_t _b,int _cb,int _cr){
  int64_t chroma_r;
  int64_t chroma_g;
  int64_t chroma_b;
  int64_t r_res;
  int64_t g_res;
  int64_t b_res;
  int64_t yn;
  int64_t err0;
  int64_t err1;
  int32_t r;
  int32_t g;
  int32_t b;
  int     y0;
  _cb-=128;
  _cr-=128;
  chroma_r=4490222169144LL*_cr;
  chroma_g=-534117096223LL*_cb-1334761232047LL*_cr;
  chroma_b=5290866304968LL*_cb;
  r_res=_r*9745792000LL-chroma_r+4096>>13;
  g_res=_g*9745792000LL-chroma_g+4096>>13;
  b_res=_b*9745792000LL-chroma_b+4096>>13;
  /*Take the floor here instead of rounding; we'll consider both possible
     values.*/
  yn=1063*r_res+3576*g_res+361*b_res;
  y0=(int)((yn-(1780026171874LL&OD_SIGNMASK(yn)))/1780026171875LL);
  /*Clamp before adding the offset.
    We clamp to 238 instead of 239 to ensure we can always add one and stay in
     range.*/
  y0=OD_CLAMPI(-16,y0,238);
  /*Check the reconstruction error with y0 after rounding and clamping.*/
  r=OD_CLAMPI(0,
   (int32_t)OD_DIV_ROUND(2916394880000LL*y0+chroma_r,9745792000LL),65535);
  g=OD_CLAMPI(0,
   (int32_t)OD_DIV_ROUND(2916394880000LL*y0+chroma_g,9745792000LL),65535);
  b=OD_CLAMPI(0,
   (int32_t)OD_DIV_ROUND(2916394880000LL*y0+chroma_b,9745792000LL),65535);
  err0=(_r-r)*(_r-r)+(_g-g)*(_g-g)+(_b-b)*(_b-b);
  /*Check the reconstruction error with y0+1 after rounding and clamping.*/
  r=OD_CLAMPI(0,
   (int32_t)OD_DIV_ROUND(2916394880000LL*(y0+1)+chroma_r,9745792000LL),65535);
  g=OD_CLAMPI(0,
   (int32_t)OD_DIV_ROUND(2916394880000LL*(y0+1)+chroma_g,9745792000LL),65535);
  b=OD_CLAMPI(0,
   (int32_t)OD_DIV_ROUND(2916394880000LL*(y0+1)+chroma_b,9745792000LL),65535);
  err1=(_r-r)*(_r-r)+(_g-g)*(_g-g)+(_b-b)*(_b-b);
  if(err1<err0)y0++;
  /*In the unlikely event there's a tie, round to even.*/
  else if(err1==err0)y0+=y0&1;
  return y0+16;
}
Esempio n. 4
0
/*This is a smart copy that copies the intersection of the two img planes
   and performs any needed bitdepth or packing conversion.
  Note that this copy performs clamping as it's only used for copying into
   and out of the codec, not for internal reference->reference copies.
  Does not touch any padding/border/unintersected area.*/
void od_img_plane_copy(daala_image* dst, daala_image* src, int pli) {
  daala_image_plane *dst_plane;
  daala_image_plane *src_plane;
  unsigned char *dst_data;
  unsigned char *src_data;
  int dst_xstride;
  int dst_ystride;
  int src_xstride;
  int src_ystride;
  int dst_xdec;
  int dst_ydec;
  int src_xdec;
  int src_ydec;
  int dst_plane_width;
  int dst_plane_height;
  int src_plane_width;
  int src_plane_height;
  int w;
  int h;
  int x;
  int y;
  if (pli >= dst->nplanes || pli >= src->nplanes) {
    return;
  }
  dst_plane = dst->planes+pli;
  src_plane = src->planes+pli;
  dst_xstride = dst_plane->xstride;
  dst_ystride = dst_plane->ystride;
  src_xstride = src_plane->xstride;
  src_ystride = src_plane->ystride;

  OD_ASSERT(dst_xstride == 1 || dst_xstride == 2);
  OD_ASSERT(src_xstride == 1 || src_xstride == 2);
  dst_xdec = dst_plane->xdec;
  dst_ydec = dst_plane->ydec;
  src_xdec = src_plane->xdec;
  src_ydec = src_plane->ydec;
  dst_data = dst_plane->data;
  src_data = src_plane->data;
  dst_plane_width = OD_PLANE_SZ(dst->width, dst_xdec);
  dst_plane_height = OD_PLANE_SZ(dst->height, dst_ydec);
  src_plane_width = OD_PLANE_SZ(src->width, src_xdec);
  src_plane_height = OD_PLANE_SZ(src->height, src_ydec);
  w = OD_MINI(dst_plane_width, src_plane_width);
  h = OD_MINI(dst_plane_height, src_plane_height);
  for (y = 0; y < h; y++) {
    unsigned char *src_ptr;
    unsigned char *dst_ptr;
    src_ptr = src_data;
    dst_ptr = dst_data;
    if (src_plane->bitdepth > 8) {
      if (dst_plane->bitdepth > 8) {
        /*Both source and destination are multibyte.*/
        if (dst_plane->bitdepth >= src_plane->bitdepth) {
          /*Shift source up into destination.*/
          int upshift;
          upshift = dst_plane->bitdepth - src_plane->bitdepth;
          for (x = 0; x < w; x++) {
            *(int16_t *)dst_ptr = OD_CLAMPI(0,
             *(int16_t *)src_ptr << upshift,
             (1 << dst_plane->bitdepth) - 1);
            src_ptr += src_xstride;
            dst_ptr += dst_xstride;
          }
        }
        else {
          /*Round source down into destination.*/
          int dnshift;
          dnshift = src_plane->bitdepth - dst_plane->bitdepth;
          for (x = 0; x < w; x++) {
            *(int16_t *)dst_ptr = OD_CLAMPI(0,
             (*(int16_t *)src_ptr + (1 << dnshift >> 1)) >> dnshift,
             (1 << dst_plane->bitdepth) - 1);
            src_ptr += src_xstride;
            dst_ptr += dst_xstride;
          }
        }
      }
      else {
        /*Round multibyte source down into 8-bit destination.*/
        int dnshift;
        dnshift = src_plane->bitdepth - 8;
        OD_ASSERT(dst_plane->bitdepth == 8);
        for (x = 0; x < w; x++) {
          *dst_ptr = OD_CLAMP255((*(int16_t *)src_ptr
           + (1 << dnshift >> 1)) >> dnshift);
          src_ptr += src_xstride;
          dst_ptr += dst_xstride;
        }
      }
    }
    else {
Esempio n. 5
0
void img_to_rgb(SDL_Surface *surf, const od_img *img) {
  unsigned char *y_row;
  unsigned char *cb_row;
  unsigned char *cr_row;
  unsigned char *y;
  unsigned char *cb;
  unsigned char *cr;
  int y_stride;
  int cb_stride;
  int cr_stride;
  int width;
  int height;
  int xdec;
  int ydec;
  int i;
  int j;
  unsigned char *pixels;
  int pitch;
  pixels = (unsigned char *)surf->pixels;
  pitch = surf->pitch;
  width = img->width;
  height = img->height;
  /*Assume both C planes are decimated.*/
  xdec = img->planes[1].xdec;
  ydec = img->planes[1].ydec;
  y_stride = img->planes[0].ystride;
  cb_stride = img->planes[1].ystride;
  cr_stride = img->planes[2].ystride;
  y_row = img->planes[0].data;
  cb_row = img->planes[1].data;
  cr_row = img->planes[2].data;
  /*Chroma up-sampling is just done with a box filter.
    This is very likely what will actually be used in practice on a real
     display, and also removes one more layer to search in for the source of
     artifacts.
    As an added bonus, it's dead simple.*/
  for (j = 0; j < height; j++) {
    int dc;
    y = y_row;
    cb = cb_row;
    cr = cr_row;
    for (i = 0; i < 3 * width;) {
      int64_t yval;
      int64_t cbval;
      int64_t crval;
      unsigned rval;
      unsigned gval;
      unsigned bval;
      yval = *y - 16;
      cbval = *cb - 128;
      crval = *cr - 128;
      /*This is intentionally slow and very accurate.*/
      rval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
       2916394880000LL*yval + 4490222169144LL*crval, 9745792000LL), 65535);
      gval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
       2916394880000LL*yval - 534117096223LL*cbval - 1334761232047LL*crval,
       9745792000LL), 65535);
      bval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
       2916394880000LL*yval + 5290866304968LL*cbval, 9745792000LL), 65535);
      *(pixels + pitch*j + i++) = (unsigned char)(bval >> 8);
      *(pixels + pitch*j + i++) = (unsigned char)(gval >> 8);
      *(pixels + pitch*j + i++) = (unsigned char)(rval >> 8);
      dc = ((y - y_row) & 1) | (1 - xdec);
      y++;
      cb += dc;
      cr += dc;
    }
    y_row += y_stride;
    dc = -((j & 1) | (1 - ydec));
    cb_row += dc & cb_stride;
    cr_row += dc & cr_stride;
  }
}