improve BGRA -> RGBA conversion

This commit is contained in:
John Cupitt 2020-10-16 18:53:45 +01:00
parent 50288c5f18
commit 93f67a2bdf
2 changed files with 35 additions and 26 deletions

View File

@ -35,7 +35,7 @@
#include <vips/vips.h>
#include <vips/internal.h>
/* Convert from ARGB to RGBA and undo premultiplication.
/* Convert from Cairo's BGRA to RGBA and undo premultiplication.
*
* See also openslide's argb2rgba().
*/
@ -45,22 +45,26 @@ vips__cairo2rgba( guint32 * restrict buf, int n )
int i;
for( i = 0; i < n; i++ ) {
guint32 * restrict p = buf + i;
guint32 x = *p;
guint8 a = x >> 24;
VipsPel * restrict out = (VipsPel *) p;
guint32 bgra = GUINT32_FROM_BE( buf[i] );
guint8 a = bgra & 0xff;
if( a == 255 )
*p = GUINT32_TO_BE( (x << 8) | 255 );
else if( a == 0 )
*p = GUINT32_TO_BE( x << 8 );
else {
/* Undo premultiplication.
*/
out[0] = 255 * ((x >> 16) & 255) / a;
out[1] = 255 * ((x >> 8) & 255) / a;
out[2] = 255 * (x & 255) / a;
out[3] = a;
}
guint32 rgba;
if( a == 0 ||
a == 255 )
rgba =
(bgra & 0x00ff00ff) |
(bgra & 0x0000ff00) << 16 |
(bgra & 0xff000000) >> 16;
else
/* Undo premultiplication.
*/
rgba =
((255 * ((bgra >> 8) & 0xff) / a) << 24) |
((255 * ((bgra >> 16) & 0xff) / a) << 16) |
((255 * ((bgra >> 24) & 0xff) / a) << 8) |
a;
buf[i] = GUINT32_TO_BE( rgba );
}
}

View File

@ -43,7 +43,6 @@
/* TODO
*
* - speed up BRGA -> RGBA conversion
* - what about filename encodings?
* - need to test on Windows
*/
@ -569,19 +568,25 @@ vips_foreign_load_pdf_generate( VipsRegion *or,
i += 1;
}
/* PDFium writes BRGA, we must swap.
*
* FIXME ... this is slow, try using vips__cairo2rgba()? Do we need to
* unpremultiply as well?
/* PDFium writes BGRA, we must swap.
*/
for( y = 0; y < r->height; y++ ) {
VipsPel *p;
guint32 * restrict p =
(guint32 *) VIPS_REGION_ADDR( or, r->left, r->top + y );
int x;
p = VIPS_REGION_ADDR( or, r->left, r->top + y );
for( x = 0; x < r->width; x++ ) {
VIPS_SWAP( VipsPel, p[0], p[2] );
p += 4;
guint32 bgra = GUINT32_FROM_BE( p[x] );
guint rgba;
rgba =
(bgra & 0x00ff00ff) |
(bgra & 0x0000ff00) << 16 |
(bgra & 0xff000000) >> 16;
p[x] = GUINT32_TO_BE( rgba );
}
}