mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Merge pull request #2693 from uploadcare/fast-unpacking
Fast unpacking and partially packing
This commit is contained in:
		
						commit
						367ce3c1bc
					
				| 
						 | 
				
			
			@ -77,9 +77,6 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc)
 | 
			
		|||
                UINT16 coef1 = src->a * 255 * 255 * 128 / outa255;
 | 
			
		||||
                UINT16 coef2 = 255 * 128 - coef1;
 | 
			
		||||
 | 
			
		||||
                #define SHIFTFORDIV255(a)\
 | 
			
		||||
                    ((((a) >> 8) + a) >> 8)
 | 
			
		||||
 | 
			
		||||
                tmpr = src->r * coef1 + dst->r * coef2 + (0x80 << 7);
 | 
			
		||||
                out->r = SHIFTFORDIV255(tmpr) >> 7;
 | 
			
		||||
                tmpg = src->g * coef1 + dst->g * coef2 + (0x80 << 7);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,13 +22,6 @@
 | 
			
		|||
#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef WORDS_BIGENDIAN
 | 
			
		||||
    #define MAKE_UINT32(u0, u1, u2, u3) (u3 | (u2<<8) | (u1<<16) | (u0<<24))
 | 
			
		||||
#else
 | 
			
		||||
    #define MAKE_UINT32(u0, u1, u2, u3) (u0 | (u1<<8) | (u2<<16) | (u3<<24))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Imaging
 | 
			
		||||
ImagingGetBand(Imaging imIn, int band)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,10 +41,6 @@
 | 
			
		|||
#define CLIP(v) ((v) <= 0 ? 0 : (v) >= 255 ? 255 : (v))
 | 
			
		||||
#define CLIP16(v) ((v) <= -32768 ? -32768 : (v) >= 32767 ? 32767 : (v))
 | 
			
		||||
 | 
			
		||||
/* like (a * b + 127) / 255), but much faster on most platforms */
 | 
			
		||||
#define MULDIV255(a, b, tmp)\
 | 
			
		||||
        (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8))
 | 
			
		||||
 | 
			
		||||
/* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */
 | 
			
		||||
#define L(rgb)\
 | 
			
		||||
    ((INT32) (rgb)[0]*299 + (INT32) (rgb)[1]*587 + (INT32) (rgb)[2]*114)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,13 +42,6 @@
 | 
			
		|||
#define INK8(ink) (*(UINT8*)ink)
 | 
			
		||||
#define INK32(ink) (*(INT32*)ink)
 | 
			
		||||
 | 
			
		||||
/* like (a * b + 127) / 255), but much faster on most platforms */
 | 
			
		||||
#define MULDIV255(a, b, tmp)\
 | 
			
		||||
        (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8))
 | 
			
		||||
 | 
			
		||||
#define BLEND(mask, in1, in2, tmp1, tmp2)\
 | 
			
		||||
        (MULDIV255(in1, 255 - mask, tmp1) + MULDIV255(in2, mask, tmp2))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Rounds around zero (up=away from zero, down=torwards zero)
 | 
			
		||||
 * This guarantees that ROUND_UP|DOWN(f) == -ROUND_UP|DOWN(-f)
 | 
			
		||||
| 
						 | 
				
			
			@ -88,14 +81,14 @@ point32(Imaging im, int x, int y, int ink)
 | 
			
		|||
static inline void
 | 
			
		||||
point32rgba(Imaging im, int x, int y, int ink)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int tmp1, tmp2;
 | 
			
		||||
    unsigned int tmp1;
 | 
			
		||||
 | 
			
		||||
    if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
 | 
			
		||||
        UINT8* out = (UINT8*) im->image[y]+x*4;
 | 
			
		||||
        UINT8* in = (UINT8*) &ink;
 | 
			
		||||
        out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2);
 | 
			
		||||
        out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2);
 | 
			
		||||
        out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2);
 | 
			
		||||
        out[0] = BLEND(in[3], out[0], in[0], tmp1);
 | 
			
		||||
        out[1] = BLEND(in[3], out[1], in[1], tmp1);
 | 
			
		||||
        out[2] = BLEND(in[3], out[2], in[2], tmp1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +140,7 @@ static inline void
 | 
			
		|||
hline32rgba(Imaging im, int x0, int y0, int x1, int ink)
 | 
			
		||||
{
 | 
			
		||||
    int tmp;
 | 
			
		||||
    unsigned int tmp1, tmp2;
 | 
			
		||||
    unsigned int tmp1;
 | 
			
		||||
 | 
			
		||||
    if (y0 >= 0 && y0 < im->ysize) {
 | 
			
		||||
        if (x0 > x1)
 | 
			
		||||
| 
						 | 
				
			
			@ -164,9 +157,9 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink)
 | 
			
		|||
            UINT8* out = (UINT8*) im->image[y0]+x0*4;
 | 
			
		||||
            UINT8* in = (UINT8*) &ink;
 | 
			
		||||
            while (x0 <= x1) {
 | 
			
		||||
                out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2);
 | 
			
		||||
                out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2);
 | 
			
		||||
                out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2);
 | 
			
		||||
                out[0] = BLEND(in[3], out[0], in[0], tmp1);
 | 
			
		||||
                out[1] = BLEND(in[3], out[1], in[1], tmp1);
 | 
			
		||||
                out[2] = BLEND(in[3], out[2], in[2], tmp1);
 | 
			
		||||
                x0++; out += 4;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -466,13 +466,9 @@ extern int ImagingZipEncodeCleanup(ImagingCodecState state);
 | 
			
		|||
typedef void (*ImagingShuffler)(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
 | 
			
		||||
/* Public shufflers */
 | 
			
		||||
extern void ImagingPackRGB(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingPackBGR(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingUnpackYCbCr(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
 | 
			
		||||
extern void ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
extern void ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels);
 | 
			
		||||
| 
						 | 
				
			
			@ -514,6 +510,10 @@ extern Py_ssize_t _imaging_tell_pyFd(PyObject *fd);
 | 
			
		|||
#define	IMAGING_CODEC_CONFIG	-8
 | 
			
		||||
#define	IMAGING_CODEC_MEMORY	-9
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "ImagingUtils.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								libImaging/ImagingUtils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								libImaging/ImagingUtils.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
#ifdef WORDS_BIGENDIAN
 | 
			
		||||
    #define MAKE_UINT32(u0, u1, u2, u3) (u3 | (u2<<8) | (u1<<16) | (u0<<24))
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_0 0xff000000
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_1 0x00ff0000
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_2 0x0000ff00
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_3 0x000000ff
 | 
			
		||||
#else
 | 
			
		||||
    #define MAKE_UINT32(u0, u1, u2, u3) (u0 | (u1<<8) | (u2<<16) | (u3<<24))
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_0 0x000000ff
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_1 0x0000ff00
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_2 0x00ff0000
 | 
			
		||||
    #define MASK_UINT32_CHANNEL_3 0xff000000
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define SHIFTFORDIV255(a)\
 | 
			
		||||
    ((((a) >> 8) + a) >> 8)
 | 
			
		||||
 | 
			
		||||
/* like (a * b + 127) / 255), but much faster on most platforms */
 | 
			
		||||
#define MULDIV255(a, b, tmp)\
 | 
			
		||||
    (tmp = (a) * (b) + 128, SHIFTFORDIV255(tmp))
 | 
			
		||||
 | 
			
		||||
#define DIV255(a, tmp)\
 | 
			
		||||
    (tmp = (a) + 128, SHIFTFORDIV255(tmp))
 | 
			
		||||
 | 
			
		||||
#define BLEND(mask, in1, in2, tmp1)\
 | 
			
		||||
    DIV255(in1 * (255 - mask) + in2 * mask, tmp1)
 | 
			
		||||
 | 
			
		||||
#define PREBLEND(mask, in1, in2, tmp1)\
 | 
			
		||||
    (MULDIV255(in1, (255 - mask), tmp1) + in2)
 | 
			
		||||
| 
						 | 
				
			
			@ -72,9 +72,6 @@
 | 
			
		|||
#define C64L C64N
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* like (a * b + 127) / 255), but much faster on most platforms */
 | 
			
		||||
#define MULDIV255(a, b, tmp)\
 | 
			
		||||
        (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8))
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pack1(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
| 
						 | 
				
			
			@ -227,13 +224,17 @@ packLAL(UINT8* out, const UINT8* in, int pixels)
 | 
			
		|||
void
 | 
			
		||||
ImagingPackRGB(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    /* RGB triplets */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[0] = in[R];
 | 
			
		||||
        out[1] = in[G];
 | 
			
		||||
        out[2] = in[B];
 | 
			
		||||
        out += 3; in += 4;
 | 
			
		||||
    for (; i < pixels-1; i++) {
 | 
			
		||||
        ((UINT32*)out)[0] = ((UINT32*)in)[i];
 | 
			
		||||
        out += 3;
 | 
			
		||||
    }
 | 
			
		||||
    for (; i < pixels; i++) {
 | 
			
		||||
        out[0] = in[i*4+R];
 | 
			
		||||
        out[1] = in[i*4+G];
 | 
			
		||||
        out[2] = in[i*4+B];
 | 
			
		||||
        out += 3;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,20 +23,6 @@
 | 
			
		|||
 | 
			
		||||
#include "Imaging.h"
 | 
			
		||||
 | 
			
		||||
/* like (a * b + 127) / 255), but much faster on most platforms */
 | 
			
		||||
#define MULDIV255NEW(a, tmp)\
 | 
			
		||||
        (tmp = (a) + 128, ((((tmp) >> 8) + (tmp)) >> 8))
 | 
			
		||||
 | 
			
		||||
#define MULDIV255OLD(a, tmp)\
 | 
			
		||||
        (((a) + 127) / 255)
 | 
			
		||||
 | 
			
		||||
#define MULDIV255 MULDIV255NEW
 | 
			
		||||
 | 
			
		||||
#define BLEND(mask, in1, in2, tmp1)\
 | 
			
		||||
        MULDIV255(in1 * (255 - mask) + in2 * mask, tmp1)
 | 
			
		||||
 | 
			
		||||
#define PREBLEND(mask, in1, in2, tmp1)\
 | 
			
		||||
        (MULDIV255(in1 * (255 - mask), tmp1) + in2)
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
paste(Imaging imOut, Imaging imIn, int dx, int dy, int sx, int sy,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,12 +5,6 @@
 | 
			
		|||
 | 
			
		||||
#define ROUND_UP(f) ((int) ((f) >= 0.0 ? (f) + 0.5F : (f) - 0.5F))
 | 
			
		||||
 | 
			
		||||
#ifdef WORDS_BIGENDIAN
 | 
			
		||||
    #define MAKE_UINT32(u0, u1, u2, u3) (u3 | (u2<<8) | (u1<<16) | (u0<<24))
 | 
			
		||||
#else
 | 
			
		||||
    #define MAKE_UINT32(u0, u1, u2, u3) (u0 | (u1<<8) | (u2<<16) | (u3<<24))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct filter {
 | 
			
		||||
    double (*filter)(double x);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -326,26 +326,25 @@ unpackL4IR(UINT8* out, const UINT8* in, int pixels)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackLA(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackLA(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* LA, pixel interleaved */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = out[G] = out[B] = in[0];
 | 
			
		||||
        out[A] = in[1];
 | 
			
		||||
        in += 2; out += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[0], in[0], in[0], in[1]);
 | 
			
		||||
        in += 2;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackLAL(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackLAL(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* LA, line interleaved */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = out[G] = out[B] = in[i];
 | 
			
		||||
        out[A] = in[i+pixels];
 | 
			
		||||
        out += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[i], in[i], in[i], in[i+pixels]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -476,89 +475,82 @@ unpackP4L(UINT8* out, const UINT8* in, int pixels)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Unpack to "RGB" image */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
ImagingUnpackRGB(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB triplets */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[0];
 | 
			
		||||
        out[G] = in[1];
 | 
			
		||||
        out[B] = in[2];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 3;
 | 
			
		||||
    for (; i < pixels-1; i++) {
 | 
			
		||||
        out[i] = MASK_UINT32_CHANNEL_3 | *(UINT32*)&in[0];
 | 
			
		||||
        in += 3;
 | 
			
		||||
    }
 | 
			
		||||
    for (; i < pixels; i++) {
 | 
			
		||||
        out[i] = MAKE_UINT32(in[0], in[1], in[2], 255);
 | 
			
		||||
        in += 3;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
unpackRGB16L(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGB16L(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* 16-bit RGB triplets, little-endian order */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[1];
 | 
			
		||||
        out[G] = in[3];
 | 
			
		||||
        out[B] = in[5];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 6;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[1], in[3], in[5], 255);
 | 
			
		||||
        in += 6;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
unpackRGB16B(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGB16B(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* 16-bit RGB triplets, big-endian order */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[0];
 | 
			
		||||
        out[G] = in[2];
 | 
			
		||||
        out[B] = in[4];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 6;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[0], in[2], in[4], 255);
 | 
			
		||||
        in += 6;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBL(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBL(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB, line interleaved */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[i];
 | 
			
		||||
        out[G] = in[i+pixels];
 | 
			
		||||
        out[B] = in[i+pixels+pixels];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], 255);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBR(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBR(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB, bit reversed */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = BITFLIP[in[0]];
 | 
			
		||||
        out[G] = BITFLIP[in[1]];
 | 
			
		||||
        out[B] = BITFLIP[in[2]];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 3;
 | 
			
		||||
        out[i] = MAKE_UINT32(BITFLIP[in[0]], BITFLIP[in[1]],
 | 
			
		||||
                             BITFLIP[in[2]], 255);
 | 
			
		||||
        in += 3;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
ImagingUnpackBGR(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB, reversed bytes */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[2];
 | 
			
		||||
        out[G] = in[1];
 | 
			
		||||
        out[B] = in[0];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 3;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[2], in[1], in[0], 255);
 | 
			
		||||
        in += 3;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -683,166 +675,148 @@ ImagingUnpackRGBA4B(UINT8* out, const UINT8* in, int pixels)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ImagingUnpackBGRX(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
ImagingUnpackBGRX(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB, reversed bytes with padding */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[2];
 | 
			
		||||
        out[G] = in[1];
 | 
			
		||||
        out[B] = in[0];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[2], in[1], in[0], 255);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ImagingUnpackXRGB(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
ImagingUnpackXRGB(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB, leading pad */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[1];
 | 
			
		||||
        out[G] = in[2];
 | 
			
		||||
        out[B] = in[3];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[1], in[2], in[3], 255);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ImagingUnpackXBGR(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
ImagingUnpackXBGR(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGB, reversed bytes, leading pad */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[3];
 | 
			
		||||
        out[G] = in[2];
 | 
			
		||||
        out[B] = in[1];
 | 
			
		||||
        out[A] = 255;
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[3], in[2], in[1], 255);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Unpack to "RGBA" image */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBALA(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBALA(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* greyscale with alpha */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = out[G] = out[B] = in[0];
 | 
			
		||||
        out[A] = in[1];
 | 
			
		||||
        out += 4; in += 2;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[0], in[0], in[0], in[1]);
 | 
			
		||||
        in += 2;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBALA16B(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBALA16B(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* 16-bit greyscale with alpha, big-endian */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = out[G] = out[B] = in[0];
 | 
			
		||||
        out[A] = in[2];
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[0], in[0], in[0], in[2]);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBa16L(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBa16L(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* premultiplied 16-bit RGBA, little-endian */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        int a = in[7];
 | 
			
		||||
        if (!a)
 | 
			
		||||
            out[R] = out[G] = out[B] = out[A] = 0;
 | 
			
		||||
        else if (a == 255) {
 | 
			
		||||
            out[R] = in[1];
 | 
			
		||||
            out[G] = in[3];
 | 
			
		||||
            out[B] = in[5];
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
        if ( ! a) {
 | 
			
		||||
            out[i] = 0;
 | 
			
		||||
        } else if (a == 255) {
 | 
			
		||||
            out[i] = MAKE_UINT32(in[1], in[3], in[5], a);
 | 
			
		||||
        } else {
 | 
			
		||||
            out[R] = CLIP(in[1] * 255 / a);
 | 
			
		||||
            out[G] = CLIP(in[3] * 255 / a);
 | 
			
		||||
            out[B] = CLIP(in[5] * 255 / a);
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
            out[i] = MAKE_UINT32(CLIP(in[1] * 255 / a),
 | 
			
		||||
                                 CLIP(in[3] * 255 / a),
 | 
			
		||||
                                 CLIP(in[5] * 255 / a), a);
 | 
			
		||||
        }
 | 
			
		||||
        out += 4; in += 8;
 | 
			
		||||
        in += 8;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBa16B(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBa16B(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* premultiplied 16-bit RGBA, big-endian */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        int a = in[6];
 | 
			
		||||
        if (!a)
 | 
			
		||||
            out[R] = out[G] = out[B] = out[A] = 0;
 | 
			
		||||
        else if (a == 255) {
 | 
			
		||||
            out[R] = in[0];
 | 
			
		||||
            out[G] = in[2];
 | 
			
		||||
            out[B] = in[4];
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
        if ( ! a) {
 | 
			
		||||
            out[i] = 0;
 | 
			
		||||
        } else if (a == 255) {
 | 
			
		||||
            out[i] = MAKE_UINT32(in[0], in[2], in[4], a);
 | 
			
		||||
        } else {
 | 
			
		||||
            out[R] = CLIP(in[0] * 255 / a);
 | 
			
		||||
            out[G] = CLIP(in[2] * 255 / a);
 | 
			
		||||
            out[B] = CLIP(in[4] * 255 / a);
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
            out[i] = MAKE_UINT32(CLIP(in[0] * 255 / a),
 | 
			
		||||
                                 CLIP(in[2] * 255 / a),
 | 
			
		||||
                                 CLIP(in[4] * 255 / a), a);
 | 
			
		||||
        }
 | 
			
		||||
        out += 4; in += 8;
 | 
			
		||||
        in += 8;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBa(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBa(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* premultiplied RGBA */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        int a = in[3];
 | 
			
		||||
        if (!a)
 | 
			
		||||
            out[R] = out[G] = out[B] = out[A] = 0;
 | 
			
		||||
        else if (a == 255) {
 | 
			
		||||
            out[R] = in[0];
 | 
			
		||||
            out[G] = in[1];
 | 
			
		||||
            out[B] = in[2];
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
        if ( ! a) {
 | 
			
		||||
            out[i] = 0;
 | 
			
		||||
        } else if (a == 255) {
 | 
			
		||||
            out[i] = MAKE_UINT32(in[0], in[1], in[2], a);
 | 
			
		||||
        } else {
 | 
			
		||||
            out[R] = CLIP(in[0] * 255 / a);
 | 
			
		||||
            out[G] = CLIP(in[1] * 255 / a);
 | 
			
		||||
            out[B] = CLIP(in[2] * 255 / a);
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
            out[i] = MAKE_UINT32(CLIP(in[0] * 255 / a),
 | 
			
		||||
                                 CLIP(in[1] * 255 / a),
 | 
			
		||||
                                 CLIP(in[2] * 255 / a), a);
 | 
			
		||||
        }
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackBGRa(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackBGRa(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* premultiplied BGRA */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        int a = in[3];
 | 
			
		||||
        if (!a)
 | 
			
		||||
            out[R] = out[G] = out[B] = out[A] = 0;
 | 
			
		||||
        else if (a == 255) {
 | 
			
		||||
            out[R] = in[2];
 | 
			
		||||
            out[G] = in[1];
 | 
			
		||||
            out[B] = in[0];
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
        if ( ! a) {
 | 
			
		||||
            out[i] = 0;
 | 
			
		||||
        } else if (a == 255) {
 | 
			
		||||
            out[i] = MAKE_UINT32(in[2], in[1], in[0], a);
 | 
			
		||||
        } else {
 | 
			
		||||
            out[R] = CLIP(in[2] * 255 / a);
 | 
			
		||||
            out[G] = CLIP(in[1] * 255 / a);
 | 
			
		||||
            out[B] = CLIP(in[0] * 255 / a);
 | 
			
		||||
            out[A] = a;
 | 
			
		||||
            out[i] = MAKE_UINT32(CLIP(in[2] * 255 / a),
 | 
			
		||||
                                 CLIP(in[1] * 255 / a),
 | 
			
		||||
                                 CLIP(in[0] * 255 / a), a);
 | 
			
		||||
        }
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -861,87 +835,74 @@ unpackRGBAI(UINT8* out, const UINT8* in, int pixels)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackRGBAL(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBAL(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGBA, line interleaved */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[i];
 | 
			
		||||
        out[G] = in[i+pixels];
 | 
			
		||||
        out[B] = in[i+pixels+pixels];
 | 
			
		||||
        out[A] = in[i+pixels+pixels+pixels];
 | 
			
		||||
        out += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels],
 | 
			
		||||
                             in[i+pixels+pixels+pixels]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
unpackRGBA16L(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBA16L(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* 16-bit RGBA, little-endian order */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[1];
 | 
			
		||||
        out[G] = in[3];
 | 
			
		||||
        out[B] = in[5];
 | 
			
		||||
        out[A] = in[7];
 | 
			
		||||
        out += 4; in += 8;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[1], in[3], in[5], in[7]);
 | 
			
		||||
        in += 8;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
unpackRGBA16B(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackRGBA16B(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* 16-bit RGBA, big-endian order */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[0];
 | 
			
		||||
        out[G] = in[2];
 | 
			
		||||
        out[B] = in[4];
 | 
			
		||||
        out[A] = in[6];
 | 
			
		||||
        out += 4; in += 8;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[0], in[2], in[4], in[6]);
 | 
			
		||||
        in += 8;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackARGB(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackARGB(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGBA, leading pad */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[1];
 | 
			
		||||
        out[G] = in[2];
 | 
			
		||||
        out[B] = in[3];
 | 
			
		||||
        out[A] = in[0];
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[1], in[2], in[3], in[0]);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackABGR(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackABGR(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGBA, reversed bytes */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[3];
 | 
			
		||||
        out[G] = in[2];
 | 
			
		||||
        out[B] = in[1];
 | 
			
		||||
        out[A] = in[0];
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[3], in[2], in[1], in[0]);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackBGRA(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackBGRA(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* RGBA, reversed bytes */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[R] = in[2];
 | 
			
		||||
        out[G] = in[1];
 | 
			
		||||
        out[B] = in[0];
 | 
			
		||||
        out[A] = in[3];
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = MAKE_UINT32(in[2], in[1], in[0], in[3]);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -949,16 +910,14 @@ unpackBGRA(UINT8* out, const UINT8* in, int pixels)
 | 
			
		|||
/* Unpack to "CMYK" image */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpackCMYKI(UINT8* out, const UINT8* in, int pixels)
 | 
			
		||||
unpackCMYKI(UINT8* _out, const UINT8* in, int pixels)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    UINT32* out = (UINT32*) _out;
 | 
			
		||||
    /* CMYK, inverted bytes (Photoshop 2.5) */
 | 
			
		||||
    for (i = 0; i < pixels; i++) {
 | 
			
		||||
        out[C] = ~in[0];
 | 
			
		||||
        out[M] = ~in[1];
 | 
			
		||||
        out[Y] = ~in[2];
 | 
			
		||||
        out[K] = ~in[3];
 | 
			
		||||
        out += 4; in += 4;
 | 
			
		||||
        out[i] = ~MAKE_UINT32(in[0], in[1], in[2], in[3]);
 | 
			
		||||
        in += 4;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user