Refactor CopyPlane() and CopyPixels() methods: put them in utils.

Change-Id: I0e1533df557a0fa42c670e3b826fc0675c36e0a5
This commit is contained in:
Urvang Joshi 2015-11-12 15:28:09 -08:00 committed by James Zern
parent 6ecd72f845
commit 397863bd66
6 changed files with 67 additions and 83 deletions

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "utils/utils.h"
#include "webp/mux_types.h"
#include "webp/encode.h"
@ -228,21 +229,8 @@ void GIFClearPic(WebPPicture* const pic, const GIFFrameRect* const rect) {
}
}
// TODO: Also used in picture.c. Move to a common location?
// Copy width x height pixels from 'src' to 'dst' honoring the strides.
static void CopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) {
while (height-- > 0) {
memcpy(dst, src, width);
src += src_stride;
dst += dst_stride;
}
}
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);
WebPCopyPixels(src, dst);
}
void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect,
@ -259,7 +247,7 @@ void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect,
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,
WebPCopyPlane((uint8_t*)src, 4 * src_stride, (uint8_t*)dst, 4 * dst_stride,
4 * rect->width, rect->height);
}
}

View File

@ -82,7 +82,6 @@ static int EncodeLossless(const uint8_t* const data, int width, int height,
return 0;
}
return 1;
}
// -----------------------------------------------------------------------------
@ -166,16 +165,6 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
// -----------------------------------------------------------------------------
// TODO(skal): move to dsp/ ?
static void CopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) {
while (height-- > 0) {
memcpy(dst, src, width);
src += src_stride;
dst += dst_stride;
}
}
static int GetNumColors(const uint8_t* data, int width, int height,
int stride) {
int j;
@ -326,7 +315,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
}
// Extract alpha data (width x height) from raw_data (stride x height).
CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height);
WebPCopyPlane(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

View File

@ -30,16 +30,6 @@ static void PictureGrabSpecs(const WebPPicture* const src,
}
//------------------------------------------------------------------------------
// Picture copying
static void CopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) {
while (height-- > 0) {
memcpy(dst, src, width);
src += src_stride;
dst += dst_stride;
}
}
// Adjust top-left corner to chroma sample position.
static void SnapTopLeftPosition(const WebPPicture* const pic,
@ -70,18 +60,18 @@ int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
if (!WebPPictureAlloc(dst)) return 0;
if (!src->use_argb) {
CopyPlane(src->y, src->y_stride,
WebPCopyPlane(src->y, src->y_stride,
dst->y, dst->y_stride, dst->width, dst->height);
CopyPlane(src->u, src->uv_stride,
dst->u, dst->uv_stride, HALVE(dst->width), HALVE(dst->height));
CopyPlane(src->v, src->uv_stride,
dst->v, dst->uv_stride, HALVE(dst->width), HALVE(dst->height));
WebPCopyPlane(src->u, src->uv_stride, dst->u, dst->uv_stride,
HALVE(dst->width), HALVE(dst->height));
WebPCopyPlane(src->v, src->uv_stride, dst->v, dst->uv_stride,
HALVE(dst->width), HALVE(dst->height));
if (dst->a != NULL) {
CopyPlane(src->a, src->a_stride,
WebPCopyPlane(src->a, src->a_stride,
dst->a, dst->a_stride, dst->width, dst->height);
}
} else {
CopyPlane((const uint8_t*)src->argb, 4 * src->argb_stride,
WebPCopyPlane((const uint8_t*)src->argb, 4 * src->argb_stride,
(uint8_t*)dst->argb, 4 * dst->argb_stride,
4 * dst->width, dst->height);
}
@ -144,24 +134,23 @@ int WebPPictureCrop(WebPPicture* pic,
if (!pic->use_argb) {
const int y_offset = top * pic->y_stride + left;
const int uv_offset = (top / 2) * pic->uv_stride + left / 2;
CopyPlane(pic->y + y_offset, pic->y_stride,
WebPCopyPlane(pic->y + y_offset, pic->y_stride,
tmp.y, tmp.y_stride, width, height);
CopyPlane(pic->u + uv_offset, pic->uv_stride,
WebPCopyPlane(pic->u + uv_offset, pic->uv_stride,
tmp.u, tmp.uv_stride, HALVE(width), HALVE(height));
CopyPlane(pic->v + uv_offset, pic->uv_stride,
WebPCopyPlane(pic->v + uv_offset, pic->uv_stride,
tmp.v, tmp.uv_stride, HALVE(width), HALVE(height));
if (tmp.a != NULL) {
const int a_offset = top * pic->a_stride + left;
CopyPlane(pic->a + a_offset, pic->a_stride,
WebPCopyPlane(pic->a + a_offset, pic->a_stride,
tmp.a, tmp.a_stride, width, height);
}
} else {
const uint8_t* const src =
(const uint8_t*)(pic->argb + top * pic->argb_stride + left);
CopyPlane(src, pic->argb_stride * 4,
(uint8_t*)tmp.argb, tmp.argb_stride * 4,
width * 4, height);
WebPCopyPlane(src, pic->argb_stride * 4, (uint8_t*)tmp.argb,
tmp.argb_stride * 4, width * 4, height);
}
WebPPictureFree(pic);
*pic = tmp;

View File

@ -477,26 +477,6 @@ static int GetSubRect(const WebPPicture* const prev_canvas,
rect->width_, rect->height_, sub_frame);
}
// TODO: Also used in picture.c. Move to a common location?
// Copy width x height pixels from 'src' to 'dst' honoring the strides.
static void CopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) {
while (height-- > 0) {
memcpy(dst, src, width);
src += src_stride;
dst += dst_stride;
}
}
// Copy pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are assumed
// to be already allocated.
static void CopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
assert(src->width == dst->width && src->height == dst->height);
assert(src->use_argb && dst->use_argb);
CopyPlane((uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb,
4 * dst->argb_stride, 4 * src->width, src->height);
}
static void DisposeFrameRectangle(int dispose_method,
const FrameRect* const rect,
WebPPicture* const curr_canvas) {
@ -717,7 +697,7 @@ static WebPEncodingError EncodeCandidate(WebPPicture* const sub_frame,
static void CopyCurrentCanvas(WebPAnimEncoder* const enc) {
if (enc->curr_canvas_copy_modified_) {
CopyPixels(enc->curr_canvas_, &enc->curr_canvas_copy_);
WebPCopyPixels(enc->curr_canvas_, &enc->curr_canvas_copy_);
enc->curr_canvas_copy_modified_ = 0;
}
}
@ -988,7 +968,7 @@ static WebPEncodingError SetFrame(WebPAnimEncoder* const enc,
if (dispose_bg_possible) {
// Change-rectangle assuming previous frame was DISPOSE_BACKGROUND.
WebPPicture* const prev_canvas_disposed = &enc->prev_canvas_disposed_;
CopyPixels(prev_canvas, prev_canvas_disposed);
WebPCopyPixels(prev_canvas, prev_canvas_disposed);
DisposeFrameRectangle(WEBP_MUX_DISPOSE_BACKGROUND, &enc->prev_rect_,
prev_canvas_disposed);
// Even if there is exact pixel match between 'disposed previous canvas' and
@ -1118,7 +1098,7 @@ static int CacheFrame(WebPAnimEncoder* const enc,
}
// Update previous to previous and previous canvases for next call.
CopyPixels(enc->curr_canvas_, &enc->prev_canvas_);
WebPCopyPixels(enc->curr_canvas_, &enc->prev_canvas_);
enc->is_first_frame_ = 0;
Skip:

View File

@ -12,7 +12,9 @@
// Author: Skal (pascal.massimino@gmail.com)
#include <stdlib.h>
#include <string.h> // for memcpy()
#include "../webp/decode.h"
#include "../webp/encode.h"
#include "./utils.h"
// If PRINT_MEM_INFO is defined, extra info (like total memory used, number of
@ -214,3 +216,24 @@ void WebPFree(void* ptr) {
}
//------------------------------------------------------------------------------
void WebPCopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) {
assert(src != NULL && dst != NULL);
assert(src_stride >= width && dst_stride >= width);
while (height-- > 0) {
memcpy(dst, src, width);
src += src_stride;
dst += dst_stride;
}
}
void WebPCopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
assert(src != NULL && dst != NULL);
assert(src->width == dst->width && src->height == dst->height);
assert(src->use_argb && dst->use_argb);
WebPCopyPlane((uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb,
4 * dst->argb_stride, 4 * src->width, src->height);
}
//------------------------------------------------------------------------------

View File

@ -118,6 +118,21 @@ static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
}
#endif
//------------------------------------------------------------------------------
// Pixel copying.
struct WebPPicture;
// Copy width x height pixels from 'src' to 'dst' honoring the strides.
WEBP_EXTERN(void) WebPCopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride,
int width, int height);
// Copy ARGB pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are
// assumed to be already allocated and using ARGB data.
WEBP_EXTERN(void) WebPCopyPixels(const struct WebPPicture* const src,
struct WebPPicture* const dst);
//------------------------------------------------------------------------------
#ifdef __cplusplus