mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
add a stride 'a_stride' for the alpha plane
(instead of hardcoding it to 'width') Change-Id: Ibce97285bfe8ff4aea45b5797f53a53d3f60adab
This commit is contained in:
parent
b8dcbf2f35
commit
8fd42b3a81
@ -9,6 +9,7 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "vp8enci.h"
|
#include "vp8enci.h"
|
||||||
|
|
||||||
@ -50,7 +51,8 @@ int WebPPictureAddAlphaPlane(WebPPicture* const picture) {
|
|||||||
if (picture) {
|
if (picture) {
|
||||||
const int width = picture->width;
|
const int width = picture->width;
|
||||||
const int height = picture->height;
|
const int height = picture->height;
|
||||||
const uint64_t a_size = (uint64_t)width * height;
|
const int a_stride = width;
|
||||||
|
const uint64_t a_size = (uint64_t)a_stride * height;
|
||||||
// Security and validation checks
|
// Security and validation checks
|
||||||
if (width <= 0 || height <= 0 || // check param error
|
if (width <= 0 || height <= 0 || // check param error
|
||||||
a_size >= (1ULL << 40) || // check for reasonable global size
|
a_size >= (1ULL << 40) || // check for reasonable global size
|
||||||
@ -59,6 +61,7 @@ int WebPPictureAddAlphaPlane(WebPPicture* const picture) {
|
|||||||
}
|
}
|
||||||
free(picture->a); // erase previous buffer
|
free(picture->a); // erase previous buffer
|
||||||
picture->a = (uint8_t*)malloc((size_t)a_size);
|
picture->a = (uint8_t*)malloc((size_t)a_size);
|
||||||
|
picture->a_stride = a_stride;
|
||||||
return (picture->a != NULL);
|
return (picture->a != NULL);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -85,9 +88,11 @@ int WebPPictureCopy(const WebPPicture* const src, WebPPicture* const dst) {
|
|||||||
if (!WebPPictureAlloc(dst)) return 0;
|
if (!WebPPictureAlloc(dst)) return 0;
|
||||||
if (src->a != NULL && !WebPPictureAddAlphaPlane(dst)) return 0;
|
if (src->a != NULL && !WebPPictureAddAlphaPlane(dst)) return 0;
|
||||||
for (y = 0; y < dst->height; ++y) {
|
for (y = 0; y < dst->height; ++y) {
|
||||||
memcpy(dst->y + y * dst->y_stride, src->y + y * src->y_stride, src->width);
|
memcpy(dst->y + y * dst->y_stride,
|
||||||
|
src->y + y * src->y_stride, src->width);
|
||||||
if (dst->a != NULL) {
|
if (dst->a != NULL) {
|
||||||
memcpy(dst->a + y * dst->width, src->a + y * src->width, src->width);
|
memcpy(dst->a + y * dst->a_stride,
|
||||||
|
src->a + y * src->a_stride, src->width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (y = 0; y < (dst->height + 1) / 2; ++y) {
|
for (y = 0; y < (dst->height + 1) / 2; ++y) {
|
||||||
@ -121,8 +126,8 @@ int WebPPictureCrop(WebPPicture* const pic,
|
|||||||
memcpy(tmp.y + y * tmp.y_stride,
|
memcpy(tmp.y + y * tmp.y_stride,
|
||||||
pic->y + (top + y) * pic->y_stride + left, width);
|
pic->y + (top + y) * pic->y_stride + left, width);
|
||||||
if (tmp.a) {
|
if (tmp.a) {
|
||||||
memcpy(tmp.a + y * tmp.width,
|
memcpy(tmp.a + y * tmp.a_stride,
|
||||||
pic->a + (top + y) * pic->width + left, width);
|
pic->a + (top + y) * pic->a_stride + left, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (y = 0; y < (height + 1) / 2; ++y) {
|
for (y = 0; y < (height + 1) / 2; ++y) {
|
||||||
@ -229,11 +234,12 @@ static inline int rgb_to_v(int r, int g, int b) {
|
|||||||
|
|
||||||
static int Import(WebPPicture* const picture,
|
static int Import(WebPPicture* const picture,
|
||||||
const uint8_t* const rgb, int rgb_stride,
|
const uint8_t* const rgb, int rgb_stride,
|
||||||
int step, int swap, int alpha_offset) {
|
int step, int swap, int import_alpha) {
|
||||||
int x, y;
|
int x, y;
|
||||||
const uint8_t* const r_ptr = rgb + (swap ? 2 : 0);
|
const uint8_t* const r_ptr = rgb + (swap ? 2 : 0);
|
||||||
const uint8_t* const g_ptr = rgb + 1;
|
const uint8_t* const g_ptr = rgb + 1;
|
||||||
const uint8_t* const b_ptr = rgb + (swap ? 0 : 2);
|
const uint8_t* const b_ptr = rgb + (swap ? 0 : 2);
|
||||||
|
const uint8_t* const a_ptr = rgb + 3;
|
||||||
|
|
||||||
for (y = 0; y < picture->height; ++y) {
|
for (y = 0; y < picture->height; ++y) {
|
||||||
for (x = 0; x < picture->width; ++x) {
|
for (x = 0; x < picture->width; ++x) {
|
||||||
@ -258,14 +264,15 @@ static int Import(WebPPicture* const picture,
|
|||||||
RGB_TO_UV(x, y, SUM1);
|
RGB_TO_UV(x, y, SUM1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (alpha_offset >= 0) {
|
if (import_alpha) {
|
||||||
|
assert(step >= 4);
|
||||||
if (!WebPPictureAddAlphaPlane(picture)) {
|
if (!WebPPictureAddAlphaPlane(picture)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (y = 0; y < picture->height; ++y) {
|
for (y = 0; y < picture->height; ++y) {
|
||||||
for (x = 0; x < picture->width; ++x) {
|
for (x = 0; x < picture->width; ++x) {
|
||||||
picture->a[x + y * picture->width] =
|
picture->a[x + y * picture->a_stride] =
|
||||||
rgb[step * x + y * rgb_stride + alpha_offset];
|
a_ptr[step * x + y * rgb_stride];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,25 +287,25 @@ static int Import(WebPPicture* const picture,
|
|||||||
int WebPPictureImportRGB(WebPPicture* const picture,
|
int WebPPictureImportRGB(WebPPicture* const picture,
|
||||||
const uint8_t* const rgb, int rgb_stride) {
|
const uint8_t* const rgb, int rgb_stride) {
|
||||||
if (!WebPPictureAlloc(picture)) return 0;
|
if (!WebPPictureAlloc(picture)) return 0;
|
||||||
return Import(picture, rgb, rgb_stride, 3, 0, -1);
|
return Import(picture, rgb, rgb_stride, 3, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebPPictureImportBGR(WebPPicture* const picture,
|
int WebPPictureImportBGR(WebPPicture* const picture,
|
||||||
const uint8_t* const rgb, int rgb_stride) {
|
const uint8_t* const rgb, int rgb_stride) {
|
||||||
if (!WebPPictureAlloc(picture)) return 0;
|
if (!WebPPictureAlloc(picture)) return 0;
|
||||||
return Import(picture, rgb, rgb_stride, 3, 1, -1);
|
return Import(picture, rgb, rgb_stride, 3, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebPPictureImportRGBA(WebPPicture* const picture,
|
int WebPPictureImportRGBA(WebPPicture* const picture,
|
||||||
const uint8_t* const rgba, int rgba_stride) {
|
const uint8_t* const rgba, int rgba_stride) {
|
||||||
if (!WebPPictureAlloc(picture)) return 0;
|
if (!WebPPictureAlloc(picture)) return 0;
|
||||||
return Import(picture, rgba, rgba_stride, 4, 0, 3);
|
return Import(picture, rgba, rgba_stride, 4, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebPPictureImportBGRA(WebPPicture* const picture,
|
int WebPPictureImportBGRA(WebPPicture* const picture,
|
||||||
const uint8_t* const rgba, int rgba_stride) {
|
const uint8_t* const rgba, int rgba_stride) {
|
||||||
if (!WebPPictureAlloc(picture)) return 0;
|
if (!WebPPictureAlloc(picture)) return 0;
|
||||||
return Import(picture, rgba, rgba_stride, 4, 1, 3);
|
return Import(picture, rgba, rgba_stride, 4, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -136,7 +136,8 @@ struct WebPPicture {
|
|||||||
int width, height; // dimensions.
|
int width, height; // dimensions.
|
||||||
uint8_t *y, *u, *v; // pointers to luma/chroma planes.
|
uint8_t *y, *u, *v; // pointers to luma/chroma planes.
|
||||||
int y_stride, uv_stride; // luma/chroma strides.
|
int y_stride, uv_stride; // luma/chroma strides.
|
||||||
uint8_t *a; // pointer to the width x height alpha plane
|
uint8_t *a; // pointer to the alpha plane
|
||||||
|
int a_stride; // stride of the alpha plane
|
||||||
|
|
||||||
// output
|
// output
|
||||||
WebPWriterFunction writer; // can be NULL
|
WebPWriterFunction writer; // can be NULL
|
||||||
|
Loading…
Reference in New Issue
Block a user