reorder the YUVA->ARGB and ARGB->YUVA functions correctly

+ rework few loops
+ consolidate few error-checks / error-reporting
+ don't modify picture->colorspace in Import() for ARGB output

Change-Id: Iae6da9b50acc738c59b85c3ee64efbaf6af8bffc
This commit is contained in:
Pascal Massimino 2014-07-18 06:20:08 -07:00
parent c6461bfda2
commit 1549d62067

View File

@ -176,18 +176,19 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
int rgb_stride, // bytes per scanline int rgb_stride, // bytes per scanline
float dithering, float dithering,
WebPPicture* const picture) { WebPPicture* const picture) {
const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK;
int x, y; int x, y;
const int width = picture->width; const int width = picture->width;
const int height = picture->height; const int height = picture->height;
const int has_alpha = CheckNonOpaque(a_ptr, width, height, step, rgb_stride); const int has_alpha = CheckNonOpaque(a_ptr, width, height, step, rgb_stride);
VP8Random rg; VP8Random rg;
picture->colorspace = uv_csp;
picture->use_argb = 0;
if (has_alpha) { if (has_alpha) {
picture->colorspace |= WEBP_CSP_ALPHA_BIT; picture->colorspace |= WEBP_CSP_ALPHA_BIT;
} else {
picture->colorspace &= WEBP_CSP_UV_MASK;
} }
picture->use_argb = 0;
if (!WebPPictureAllocYUVA(picture, width, height)) return 0; if (!WebPPictureAllocYUVA(picture, width, height)) return 0;
VP8InitRandom(&rg, dithering); VP8InitRandom(&rg, dithering);
@ -195,10 +196,10 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
// Import luma plane // Import luma plane
for (y = 0; y < height; ++y) { for (y = 0; y < height; ++y) {
uint8_t* const dst = &picture->y[y * picture->y_stride];
for (x = 0; x < width; ++x) { for (x = 0; x < width; ++x) {
const int offset = step * x + y * rgb_stride; const int offset = step * x + y * rgb_stride;
picture->y[x + y * picture->y_stride] = dst[x] = RGBToY(r_ptr[offset], g_ptr[offset], b_ptr[offset], &rg);
RGBToY(r_ptr[offset], g_ptr[offset], b_ptr[offset], &rg);
} }
} }
@ -233,53 +234,6 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
return 1; return 1;
} }
static int Import(WebPPicture* const picture,
const uint8_t* const rgb, int rgb_stride,
int step, int swap_rb, int import_alpha) {
const uint8_t* const r_ptr = rgb + (swap_rb ? 2 : 0);
const uint8_t* const g_ptr = rgb + 1;
const uint8_t* const b_ptr = rgb + (swap_rb ? 0 : 2);
const uint8_t* const a_ptr = import_alpha ? rgb + 3 : NULL;
const int width = picture->width;
const int height = picture->height;
if (!picture->use_argb) {
return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride,
0.f /* no dithering */, picture);
}
if (import_alpha) {
picture->colorspace |= WEBP_CSP_ALPHA_BIT;
} else {
picture->colorspace &= ~WEBP_CSP_ALPHA_BIT;
}
if (!WebPPictureAlloc(picture)) return 0;
if (!import_alpha) {
int x, y;
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
const int offset = step * x + y * rgb_stride;
const uint32_t argb =
MakeARGB32(r_ptr[offset], g_ptr[offset], b_ptr[offset]);
picture->argb[x + y * picture->argb_stride] = argb;
}
}
} else {
int x, y;
assert(step >= 4);
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
const int offset = step * x + y * rgb_stride;
const uint32_t argb = ((uint32_t)a_ptr[offset] << 24) |
(r_ptr[offset] << 16) |
(g_ptr[offset] << 8) |
(b_ptr[offset]);
picture->argb[x + y * picture->argb_stride] = argb;
}
}
}
return 1;
}
#undef SUM4 #undef SUM4
#undef SUM2V #undef SUM2V
#undef SUM2H #undef SUM2H
@ -287,39 +241,32 @@ static int Import(WebPPicture* const picture,
#undef RGB_TO_UV #undef RGB_TO_UV
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// call for ARGB->YUVA conversion
int WebPPictureImportRGB(WebPPicture* picture, int WebPPictureARGBToYUVADithered(WebPPicture* picture, WebPEncCSP colorspace,
const uint8_t* rgb, int rgb_stride) { float dithering) {
return Import(picture, rgb, rgb_stride, 3, 0, 0); if (picture == NULL) return 0;
if (picture->argb == NULL) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
} else {
const uint8_t* const argb = (const uint8_t*)picture->argb;
const uint8_t* const r = ALPHA_IS_LAST ? argb + 2 : argb + 1;
const uint8_t* const g = ALPHA_IS_LAST ? argb + 1 : argb + 2;
const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3;
const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0;
picture->colorspace = colorspace;
return ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride,
dithering, picture);
}
} }
int WebPPictureImportBGR(WebPPicture* picture, int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace) {
const uint8_t* rgb, int rgb_stride) { return WebPPictureARGBToYUVADithered(picture, colorspace, 0.f);
return Import(picture, rgb, rgb_stride, 3, 1, 0);
}
int WebPPictureImportRGBA(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return Import(picture, rgba, rgba_stride, 4, 0, 1);
}
int WebPPictureImportBGRA(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return Import(picture, rgba, rgba_stride, 4, 1, 1);
}
int WebPPictureImportRGBX(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return Import(picture, rgba, rgba_stride, 4, 0, 0);
}
int WebPPictureImportBGRX(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return Import(picture, rgba, rgba_stride, 4, 1, 0);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Automatic YUV <-> ARGB conversions. // call for YUVA -> ARGB conversion
int WebPPictureYUVAToARGB(WebPPicture* picture) { int WebPPictureYUVAToARGB(WebPPicture* picture) {
if (picture == NULL) return 0; if (picture == NULL) return 0;
@ -380,29 +327,75 @@ int WebPPictureYUVAToARGB(WebPPicture* picture) {
return 1; return 1;
} }
int WebPPictureARGBToYUVADithered(WebPPicture* picture, WebPEncCSP colorspace, //------------------------------------------------------------------------------
float dithering) { // automatic import / conversion
if (picture == NULL) return 0;
if (picture->argb == NULL) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
} else {
const uint8_t* const argb = (const uint8_t*)picture->argb;
const uint8_t* const r = ALPHA_IS_LAST ? argb + 2 : argb + 1;
const uint8_t* const g = ALPHA_IS_LAST ? argb + 1 : argb + 2;
const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3;
const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0;
picture->colorspace = colorspace; static int Import(WebPPicture* const picture,
if (!ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, dithering, const uint8_t* const rgb, int rgb_stride,
picture)) { int step, int swap_rb, int import_alpha) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); int y;
const uint8_t* const r_ptr = rgb + (swap_rb ? 2 : 0);
const uint8_t* const g_ptr = rgb + 1;
const uint8_t* const b_ptr = rgb + (swap_rb ? 0 : 2);
const uint8_t* const a_ptr = import_alpha ? rgb + 3 : NULL;
const int width = picture->width;
const int height = picture->height;
if (!picture->use_argb) {
return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride,
0.f /* no dithering */, picture);
}
if (!WebPPictureAlloc(picture)) return 0;
assert(step >= (import_alpha ? 4 : 3));
for (y = 0; y < height; ++y) {
uint32_t* const dst = &picture->argb[y * picture->argb_stride];
int x;
for (x = 0; x < width; ++x) {
const int offset = step * x + y * rgb_stride;
if (!import_alpha) {
dst[x] = MakeARGB32(r_ptr[offset], g_ptr[offset], b_ptr[offset]);
} else {
dst[x] = ((uint32_t)a_ptr[offset] << 24) |
(r_ptr[offset] << 16) |
(g_ptr[offset] << 8) |
(b_ptr[offset]);
}
} }
} }
return 1; return 1;
} }
int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace) { // Public API
return WebPPictureARGBToYUVADithered(picture, colorspace, 0.f);
int WebPPictureImportRGB(WebPPicture* picture,
const uint8_t* rgb, int rgb_stride) {
return (picture != NULL) ? Import(picture, rgb, rgb_stride, 3, 0, 0) : 0;
}
int WebPPictureImportBGR(WebPPicture* picture,
const uint8_t* rgb, int rgb_stride) {
return (picture != NULL) ? Import(picture, rgb, rgb_stride, 3, 1, 0) : 0;
}
int WebPPictureImportRGBA(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 0, 1) : 0;
}
int WebPPictureImportBGRA(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 1, 1) : 0;
}
int WebPPictureImportRGBX(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 0, 0) : 0;
}
int WebPPictureImportBGRX(WebPPicture* picture,
const uint8_t* rgba, int rgba_stride) {
return (picture != NULL) ? Import(picture, rgba, rgba_stride, 4, 1, 0) : 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------