summaryrefslogtreecommitdiff
path: root/libavcodec/pngenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/pngenc.c')
-rw-r--r--libavcodec/pngenc.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index bf61be1609..35a95921ad 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -113,6 +113,22 @@ static void sub_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, i
}
}
+static void sub_left_prediction(DSPContext *dsp, uint8_t *dst, const uint8_t *src, int bpp, int size)
+{
+ const uint8_t *src1 = src + bpp;
+ const uint8_t *src2 = src;
+ int x, unaligned_w;
+
+ memcpy(dst, src, bpp);
+ dst += bpp;
+ size -= bpp;
+ unaligned_w = FFMIN(32 - bpp, size);
+ for (x = 0; x < unaligned_w; x++)
+ *dst++ = *src1++ - *src2++;
+ size -= unaligned_w;
+ dsp->diff_bytes(dst, src1, src2, size);
+}
+
static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
uint8_t *src, uint8_t *top, int size, int bpp)
{
@@ -123,8 +139,7 @@ static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
memcpy(dst, src, size);
break;
case PNG_FILTER_VALUE_SUB:
- dsp->diff_bytes(dst, src, src-bpp, size);
- memcpy(dst, src, bpp);
+ sub_left_prediction(dsp, dst, src, bpp, size);
break;
case PNG_FILTER_VALUE_UP:
dsp->diff_bytes(dst, src, top, size);