Пример #1
0
void
PlanarYCbCrImage::CopyData(const Data& aData)
{
  mData = aData;

  // update buffer size
  mBufferSize = mData.mCbCrStride * mData.mCbCrSize.height * 2 +
                mData.mYStride * mData.mYSize.height;

  // get new buffer
  mBuffer = AllocateBuffer(mBufferSize); 
  if (!mBuffer)
    return;

  mData.mYChannel = mBuffer;
  mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
  mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;

  CopyPlane(mData.mYChannel, aData.mYChannel,
            mData.mYSize, mData.mYStride, mData.mYSkip);
  CopyPlane(mData.mCbChannel, aData.mCbChannel,
            mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip);
  CopyPlane(mData.mCrChannel, aData.mCrChannel,
            mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip);

  mSize = aData.mPicSize;
}
Пример #2
0
static int EncodeAlpha(VP8Encoder* const enc,
                       int quality, int method, int filter,
                       int effort_level,
                       uint8_t** const output, size_t* const output_size) {
  const WebPPicture* const pic = enc->pic_;
  const int width = pic->width;
  const int height = pic->height;

  uint8_t* quant_alpha = NULL;
  const size_t data_size = width * height;
  uint64_t sse = 0;
  int ok = 1;
  const int reduce_levels = (quality < 100);

  // quick sanity checks
  assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
  assert(enc != NULL && pic != NULL && pic->a != NULL);
  assert(output != NULL && output_size != NULL);
  assert(width > 0 && height > 0);
  assert(pic->a_stride >= width);
  assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST);

  if (quality < 0 || quality > 100) {
    return 0;
  }

  if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) {
    return 0;
  }

  quant_alpha = (uint8_t*)malloc(data_size);
  if (quant_alpha == NULL) {
    return 0;
  }

  // Extract alpha data (width x height) from raw_data (stride x height).
  CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height);

  if (reduce_levels) {  // No Quantization required for 'quality = 100'.
    // 16 alpha levels gives quite a low MSE w.r.t original alpha plane hence
    // mapped to moderate quality 70. Hence Quality:[0, 70] -> Levels:[2, 16]
    // and Quality:]70, 100] -> Levels:]16, 256].
    const int alpha_levels = (quality <= 70) ? (2 + quality / 5)
                                             : (16 + (quality - 70) * 8);
    ok = QuantizeLevels(quant_alpha, width, height, alpha_levels, &sse);
  }

  if (ok) {
    ok = ApplyFilters(quant_alpha, width, height, data_size, method, filter,
                      reduce_levels, effort_level, output, output_size,
                      pic->stats);
    if (pic->stats != NULL) {  // need stats?
      pic->stats->coded_size += (int)(*output_size);
      enc->sse_[3] = sse;
    }
  }

  free(quant_alpha);
  return ok;
}
Пример #3
0
void MapLoader::SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldvertextable)
{
	FMapThing *mt;

	for (mt = firstmt; mt < lastmt; ++mt)
	{
		if (mt->info != NULL && mt->info->Type == NULL &&
		   (mt->info->Special >= SMT_SlopeFloorPointLine && mt->info->Special <= SMT_VavoomCeiling))
		{
			DVector3 pos = mt->pos;
			secplane_t *refplane;
			sector_t *sec;
			bool ceiling;

			sec = Level->PointInSector (mt->pos);
			if (mt->info->Special == SMT_SlopeCeilingPointLine || mt->info->Special == SMT_VavoomCeiling || mt->info->Special == SMT_SetCeilingSlope)
			{
				refplane = &sec->ceilingplane;
				ceiling = true;
			}
			else
			{
				refplane = &sec->floorplane;
				ceiling = false;
			}
			pos.Z = refplane->ZatPoint (mt->pos) + mt->pos.Z;

			if (mt->info->Special <= SMT_SlopeCeilingPointLine)
			{ // SlopeFloorPointLine and SlopCeilingPointLine
				SlopeLineToPoint (mt->args[0], pos, ceiling);
			}
			else if (mt->info->Special <= SMT_SetCeilingSlope)
			{ // SetFloorSlope and SetCeilingSlope
				SetSlope (refplane, ceiling, mt->angle, mt->args[0], pos);
			}
			else 
			{ // VavoomFloor and VavoomCeiling (these do not perform any sector height adjustment - z is absolute)
				VavoomSlope(sec, mt->thingid, mt->pos, ceiling); 
			}
			mt->EdNum = 0;
		}
	}

	for (mt = firstmt; mt < lastmt; ++mt)
	{
		if (mt->info != NULL && mt->info->Type == NULL &&
			(mt->info->Special == SMT_CopyFloorPlane || mt->info->Special == SMT_CopyCeilingPlane))
		{
			CopyPlane (mt->args[0], mt->pos, mt->info->Special == SMT_CopyCeilingPlane);
			mt->EdNum = 0;
		}
	}

	SetSlopesFromVertexHeights(firstmt, lastmt, oldvertextable);
}
Пример #4
0
void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect,
                     const WebPPicture* const prev_canvas,
                     WebPPicture* const curr_canvas) {
  assert(rect != NULL);
  if (dispose == GIF_DISPOSE_BACKGROUND) {
    GIFClearPic(curr_canvas, rect);
  } else if (dispose == GIF_DISPOSE_RESTORE_PREVIOUS) {
    const int src_stride = prev_canvas->argb_stride;
    const uint32_t* const src =
        prev_canvas->argb + rect->x_offset + rect->y_offset * src_stride;
    const int dst_stride = curr_canvas->argb_stride;
    uint32_t* const dst =
        curr_canvas->argb + rect->x_offset + rect->y_offset * dst_stride;
    assert(prev_canvas != NULL);
    CopyPlane((uint8_t*)src, 4 * src_stride, (uint8_t*)dst, 4 * dst_stride,
              4 * rect->width, rect->height);
  }
}
Пример #5
0
static int EncodeAlpha(VP8Encoder* const enc,
                       int quality, int method, int filter,
                       int effort_level,
                       uint8_t** const output, size_t* const output_size) {
  const WebPPicture* const pic = enc->pic_;
  const int width = pic->width;
  const int height = pic->height;

  uint8_t* quant_alpha = NULL;
  const size_t data_size = width * height;
  uint64_t sse = 0;
  int ok = 1;
  const int reduce_levels = (quality < 100);

  // quick sanity checks
  assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
  assert(enc != NULL && pic != NULL && pic->a != NULL);
  assert(output != NULL && output_size != NULL);
  assert(width > 0 && height > 0);
  assert(pic->a_stride >= width);
  assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST);

  if (quality < 0 || quality > 100) {
    return 0;
  }

  if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) {
    return 0;
  }

  quant_alpha = (uint8_t*)malloc(data_size);
  if (quant_alpha == NULL) {
    return 0;
  }

  // Extract alpha data (width x height) from raw_data (stride x height).
  CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height);

  if (reduce_levels) {  // No Quantization required for 'quality = 100'.
    // 16 alpha levels gives quite a low MSE w.r.t original alpha plane hence
    // mapped to moderate quality 70. Hence Quality:[0, 70] -> Levels:[2, 16]
    // and Quality:]70, 100] -> Levels:]16, 256].
    const int alpha_levels = (quality <= 70) ? (2 + quality / 5)
                                             : (16 + (quality - 70) * 8);
    ok = QuantizeLevels(quant_alpha, width, height, alpha_levels, &sse);
  }

  if (ok) {
    VP8BitWriter bw;
    int test_filter;
    uint8_t* filtered_alpha = NULL;

    // We always test WEBP_FILTER_NONE first.
    ok = EncodeAlphaInternal(quant_alpha, width, height,
                             method, WEBP_FILTER_NONE, reduce_levels,
                             effort_level, NULL, &bw, pic->stats);
    if (!ok) {
      VP8BitWriterWipeOut(&bw);
      goto End;
    }

    if (filter == WEBP_FILTER_FAST) {  // Quick estimate of a second candidate?
      filter = EstimateBestFilter(quant_alpha, width, height, width);
    }
    // Stop?
    if (filter == WEBP_FILTER_NONE) {
      goto Ok;
    }

    filtered_alpha = (uint8_t*)malloc(data_size);
    ok = (filtered_alpha != NULL);
    if (!ok) {
      goto End;
    }

    // Try the other mode(s).
    {
      WebPAuxStats best_stats;
      size_t best_score = VP8BitWriterSize(&bw);

      memset(&best_stats, 0, sizeof(best_stats));  // prevent spurious warning
      if (pic->stats != NULL) best_stats = *pic->stats;
      for (test_filter = WEBP_FILTER_HORIZONTAL;
           ok && (test_filter <= WEBP_FILTER_GRADIENT);
           ++test_filter) {
        VP8BitWriter tmp_bw;
        if (filter != WEBP_FILTER_BEST && test_filter != filter) {
          continue;
        }
        ok = EncodeAlphaInternal(quant_alpha, width, height,
                                 method, test_filter, reduce_levels,
                                 effort_level, filtered_alpha, &tmp_bw,
                                 pic->stats);
        if (ok) {
          const size_t score = VP8BitWriterSize(&tmp_bw);
          if (score < best_score) {
            // swap bitwriter objects.
            VP8BitWriter tmp = tmp_bw;
            tmp_bw = bw;
            bw = tmp;
            best_score = score;
            if (pic->stats != NULL) best_stats = *pic->stats;
          }
        } else {
          VP8BitWriterWipeOut(&bw);
        }
        VP8BitWriterWipeOut(&tmp_bw);
      }
      if (pic->stats != NULL) *pic->stats = best_stats;
    }
 Ok:
    if (ok) {
      *output_size = VP8BitWriterSize(&bw);
      *output = VP8BitWriterBuf(&bw);
      if (pic->stats != NULL) {         // need stats?
        pic->stats->coded_size += (int)(*output_size);
        enc->sse_[3] = sse;
      }
    }
    free(filtered_alpha);
  }
 End:
  free(quant_alpha);
  return ok;
}
Пример #6
0
void GIFCopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
  assert(src->width == dst->width && src->height == dst->height);
  CopyPlane((uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb,
            4 * dst->argb_stride, 4 * src->width, src->height);
}
Пример #7
0
void CMPEG2Decoder::assembleFrame(unsigned char *src[], int pf, YV12PICT *dst)
{
    int *qp;

#ifdef PROFILING
    start_timer();
#endif

    dst->pf = pf;

    if (pp_mode != 0)
    {
        uc* ppptr[3];
        if (!(upConv > 0 && chroma_format == 1))
        {
            ppptr[0] = dst->y;
            ppptr[1] = dst->u;
            ppptr[2] = dst->v;
        }
        else
        {
            ppptr[0] = dst->y;
            ppptr[1] = u422;
            ppptr[2] = v422;
        }
        bool iPPt;
        if (iPP == 1 || (iPP == -1 && pf == 0)) iPPt = true;
        else iPPt = false;
        postprocess(src, this->Coded_Picture_Width, this->Chroma_Width,
                ppptr, dst->ypitch, dst->uvpitch, this->Coded_Picture_Width,
                this->Coded_Picture_Height, this->QP, this->mb_width, pp_mode, moderate_h, moderate_v,
                chroma_format == 1 ? false : true, iPPt);
        if (upConv > 0 && chroma_format == 1)
        {
            if (iCC == 1 || (iCC == -1 && pf == 0))
            {
                conv420to422(ppptr[1],dst->u,0,dst->uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
                conv420to422(ppptr[2],dst->v,0,dst->uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
            }
            else
            {
                conv420to422(ppptr[1],dst->u,1,dst->uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
                conv420to422(ppptr[2],dst->v,1,dst->uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
            }
        }
    }
    else
    {
        YV12PICT psrc;
        psrc.y = src[0]; psrc.u = src[1]; psrc.v = src[2];
        psrc.ypitch = psrc.ywidth = Coded_Picture_Width;
        psrc.uvpitch = psrc.uvwidth = Chroma_Width;
        psrc.yheight = Coded_Picture_Height;
        psrc.uvheight = Chroma_Height;
        if (upConv > 0 && chroma_format == 1)
        {
            CopyPlane(psrc.y,psrc.ypitch,dst->y,dst->ypitch,psrc.ywidth,psrc.yheight);
            if (iCC == 1 || (iCC == -1 && pf == 0))
            {
                conv420to422(psrc.u,dst->u,0,psrc.uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
                conv420to422(psrc.v,dst->v,0,psrc.uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
            }
            else
            {
                conv420to422(psrc.u,dst->u,1,psrc.uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
                conv420to422(psrc.v,dst->v,1,psrc.uvpitch,dst->uvpitch,Coded_Picture_Width,Coded_Picture_Height);
            }
        }
        else CopyAll(&psrc,dst);
    }

    // Re-order quant data for display order.
    if (info == 1 || info == 2 || showQ)
    {
        if (picture_coding_type == B_TYPE)
            qp = auxQP;
        else
            qp = backwardQP;
    }

    if (info == 1 || info == 2)
    {
        __asm emms;
        int x, y, temp;
        int quant;

        minquant = maxquant = qp[0];
        avgquant = 0;
        for(y=0; y<mb_height; ++y)
        {
            temp = y*mb_width;
            for(x=0; x<mb_width; ++x)
            {
                quant = qp[x+temp];
                if (quant > maxquant) maxquant = quant;
                if (quant < minquant) minquant = quant;
                avgquant += quant;
            }
        }
        avgquant = (int)(((float)avgquant/(float)(mb_height*mb_width)) + 0.5f);
    }

    if (showQ)
    {
        int x, y;
        for(y=0; y<this->mb_height; y++)
        {
            for(x=0;x<this->mb_width; x++)
            {
                MBnum(&dst->y[x*16+y*16*dst->ypitch],dst->ypitch,qp[x+y*this->mb_width]);
            }
        }
    }

#ifdef PROFILING
    stop_timer(&tim.post);
    start_timer();
#endif
}
Пример #8
0
void MapLoader::CopyPlane (int tag, const DVector2 &pos, bool copyCeil)
{
	sector_t *dest = Level->PointInSector (pos);
	CopyPlane(tag, dest, copyCeil);
}