diff --git a/examples/gifdec.c b/examples/gifdec.c index f315a5b0..b12d2df4 100644 --- a/examples/gifdec.c +++ b/examples/gifdec.c @@ -18,6 +18,7 @@ #include #include +#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,8 +247,8 @@ 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, - 4 * rect->width, rect->height); + WebPCopyPlane((uint8_t*)src, 4 * src_stride, (uint8_t*)dst, 4 * dst_stride, + 4 * rect->width, rect->height); } } diff --git a/src/enc/alpha.c b/src/enc/alpha.c index fa488375..fad6346e 100644 --- a/src/enc/alpha.c +++ b/src/enc/alpha.c @@ -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 diff --git a/src/enc/picture_rescale.c b/src/enc/picture_rescale.c index 023e5998..9f19e8e8 100644 --- a/src/enc/picture_rescale.c +++ b/src/enc/picture_rescale.c @@ -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,20 +60,20 @@ int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) { if (!WebPPictureAlloc(dst)) return 0; if (!src->use_argb) { - CopyPlane(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->y, src->y_stride, + dst->y, dst->y_stride, dst->width, 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, - dst->a, dst->a_stride, dst->width, dst->height); + 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, - (uint8_t*)dst->argb, 4 * dst->argb_stride, - 4 * dst->width, dst->height); + WebPCopyPlane((const uint8_t*)src->argb, 4 * src->argb_stride, + (uint8_t*)dst->argb, 4 * dst->argb_stride, + 4 * dst->width, dst->height); } return 1; } @@ -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, - tmp.y, tmp.y_stride, width, height); - CopyPlane(pic->u + uv_offset, pic->uv_stride, - tmp.u, tmp.uv_stride, HALVE(width), HALVE(height)); - CopyPlane(pic->v + uv_offset, pic->uv_stride, - tmp.v, tmp.uv_stride, HALVE(width), HALVE(height)); + WebPCopyPlane(pic->y + y_offset, pic->y_stride, + tmp.y, tmp.y_stride, width, height); + WebPCopyPlane(pic->u + uv_offset, pic->uv_stride, + tmp.u, tmp.uv_stride, HALVE(width), HALVE(height)); + 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, - tmp.a, tmp.a_stride, width, height); + 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; diff --git a/src/mux/anim_encode.c b/src/mux/anim_encode.c index 7d682000..fa86eaac 100644 --- a/src/mux/anim_encode.c +++ b/src/mux/anim_encode.c @@ -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: diff --git a/src/utils/utils.c b/src/utils/utils.c index 735bf3f6..d8e30930 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -12,7 +12,9 @@ // Author: Skal (pascal.massimino@gmail.com) #include +#include // 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); +} + +//------------------------------------------------------------------------------ diff --git a/src/utils/utils.h b/src/utils/utils.h index ce225d6a..df83b12b 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -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