Pillow/src/libImaging/Pack.c

693 lines
15 KiB
C
Raw Normal View History

2021-01-03 06:17:51 +03:00
/*
2010-07-31 06:52:47 +04:00
* The Python Imaging Library.
* $Id$
*
* code to pack raw data
*
* history:
* 1996-04-30 fl Created
* 1996-05-12 fl Published a few RGB packers
* 1996-11-01 fl More RGB packers (Tk booster stuff)
* 1996-12-30 fl Added P;1, P;2 and P;4 packers
* 1997-06-02 fl Added F (F;32NF) packer
* 1997-08-28 fl Added 1 as L packer
* 1998-02-08 fl Added I packer
* 1998-03-09 fl Added mode field, RGBA/RGBX as RGB packers
* 1998-07-01 fl Added YCbCr support
* 1998-07-12 fl Added I 16 packer
* 1999-02-03 fl Added BGR packers
* 2003-09-26 fl Added LA/PA packers
* 2006-06-22 fl Added CMYK;I packer
*
* Copyright (c) 1997-2006 by Secret Labs AB.
* Copyright (c) 1996-1997 by Fredrik Lundh.
*
* See the README file for information on usage and redistribution.
*/
#include "Imaging.h"
2016-12-03 17:07:49 +03:00
#define R 0
#define G 1
#define B 2
#define X 3
#define A 3
2010-07-31 06:52:47 +04:00
2016-12-03 17:07:49 +03:00
#define C 0
#define M 1
#define Y 2
#define K 3
2010-07-31 06:52:47 +04:00
/* byte swapping macros */
2021-01-03 06:17:51 +03:00
#define C16N (out[0] = tmp[0], out[1] = tmp[1]);
#define C16S (out[1] = tmp[0], out[0] = tmp[1]);
#define C32N (out[0] = tmp[0], out[1] = tmp[1], out[2] = tmp[2], out[3] = tmp[3]);
#define C32S (out[3] = tmp[0], out[2] = tmp[1], out[1] = tmp[2], out[0] = tmp[3]);
#define C64N \
(out[0] = tmp[0], \
out[1] = tmp[1], \
out[2] = tmp[2], \
out[3] = tmp[3], \
out[4] = tmp[4], \
out[5] = tmp[5], \
out[6] = tmp[6], \
out[7] = tmp[7]);
#define C64S \
(out[7] = tmp[0], \
out[6] = tmp[1], \
out[5] = tmp[2], \
out[4] = tmp[3], \
out[3] = tmp[4], \
out[2] = tmp[5], \
out[1] = tmp[6], \
out[0] = tmp[7]);
2010-07-31 06:52:47 +04:00
#ifdef WORDS_BIGENDIAN
#define C16B C16N
#define C16L C16S
#define C32B C32N
#define C32L C32S
#define C64B C64N
#define C64L C64S
#else
#define C16B C16S
#define C16L C16N
#define C32B C32S
#define C32L C32N
#define C64B C64S
#define C64L C64N
#endif
static void
2021-01-03 06:17:51 +03:00
pack1(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i, m, b;
/* bilevel (black is 0) */
2021-01-03 06:17:51 +03:00
b = 0;
m = 128;
2010-07-31 06:52:47 +04:00
for (i = 0; i < pixels; i++) {
2020-05-10 12:56:36 +03:00
if (in[i] != 0) {
2016-12-03 17:07:49 +03:00
b |= m;
2020-05-10 12:56:36 +03:00
}
2016-12-03 17:07:49 +03:00
m >>= 1;
if (m == 0) {
*out++ = b;
2021-01-03 06:17:51 +03:00
b = 0;
m = 128;
2016-12-03 17:07:49 +03:00
}
2010-07-31 06:52:47 +04:00
}
2020-05-10 12:56:36 +03:00
if (m != 128) {
2016-12-03 17:07:49 +03:00
*out++ = b;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
pack1I(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i, m, b;
/* bilevel (black is 1) */
2021-01-03 06:17:51 +03:00
b = 0;
m = 128;
2010-07-31 06:52:47 +04:00
for (i = 0; i < pixels; i++) {
2020-05-10 12:56:36 +03:00
if (in[i] == 0) {
2016-12-03 17:07:49 +03:00
b |= m;
2020-05-10 12:56:36 +03:00
}
2016-12-03 17:07:49 +03:00
m >>= 1;
if (m == 0) {
*out++ = b;
2021-01-03 06:17:51 +03:00
b = 0;
m = 128;
2016-12-03 17:07:49 +03:00
}
2010-07-31 06:52:47 +04:00
}
2020-05-10 12:56:36 +03:00
if (m != 128) {
2016-12-03 17:07:49 +03:00
*out++ = b;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
pack1R(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i, m, b;
/* bilevel, lsb first (black is 0) */
2021-01-03 06:17:51 +03:00
b = 0;
m = 1;
2010-07-31 06:52:47 +04:00
for (i = 0; i < pixels; i++) {
2020-05-10 12:56:36 +03:00
if (in[i] != 0) {
2016-12-03 17:07:49 +03:00
b |= m;
2020-05-10 12:56:36 +03:00
}
2016-12-03 17:07:49 +03:00
m <<= 1;
2021-01-03 06:17:51 +03:00
if (m == 256) {
2016-12-03 17:07:49 +03:00
*out++ = b;
2021-01-03 06:17:51 +03:00
b = 0;
m = 1;
2016-12-03 17:07:49 +03:00
}
2010-07-31 06:52:47 +04:00
}
2020-05-10 12:56:36 +03:00
if (m != 1) {
2016-12-03 17:07:49 +03:00
*out++ = b;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
pack1IR(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i, m, b;
/* bilevel, lsb first (black is 1) */
2021-01-03 06:17:51 +03:00
b = 0;
m = 1;
2010-07-31 06:52:47 +04:00
for (i = 0; i < pixels; i++) {
2020-05-10 12:56:36 +03:00
if (in[i] == 0) {
2016-12-03 17:07:49 +03:00
b |= m;
2020-05-10 12:56:36 +03:00
}
2016-12-03 17:07:49 +03:00
m <<= 1;
2021-01-03 06:17:51 +03:00
if (m == 256) {
2016-12-03 17:07:49 +03:00
*out++ = b;
2021-01-03 06:17:51 +03:00
b = 0;
m = 1;
2016-12-03 17:07:49 +03:00
}
2010-07-31 06:52:47 +04:00
}
2020-05-10 12:56:36 +03:00
if (m != 1) {
2016-12-03 17:07:49 +03:00
*out++ = b;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
pack1L(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* bilevel, stored as bytes */
2020-05-10 12:56:36 +03:00
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[i] = (in[i] != 0) ? 255 : 0;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
packP4(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
while (pixels >= 2) {
2021-01-03 06:17:51 +03:00
*out++ = (in[0] << 4) | (in[1] & 15);
in += 2;
pixels -= 2;
2010-07-31 06:52:47 +04:00
}
2020-05-10 12:56:36 +03:00
if (pixels) {
2016-12-03 17:07:49 +03:00
out[0] = (in[0] << 4);
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
packP2(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
while (pixels >= 4) {
2021-01-03 06:17:51 +03:00
*out++ = (in[0] << 6) | ((in[1] & 3) << 4) | ((in[2] & 3) << 2) | (in[3] & 3);
in += 4;
pixels -= 4;
2010-07-31 06:52:47 +04:00
}
switch (pixels) {
2021-01-03 06:17:51 +03:00
case 3:
out[0] = (in[0] << 6) | ((in[1] & 3) << 4) | ((in[2] & 3) << 2);
break;
case 2:
out[0] = (in[0] << 6) | ((in[1] & 3) << 4);
break;
case 1:
out[0] = (in[0] << 6);
2010-07-31 06:52:47 +04:00
}
}
2017-09-29 16:39:16 +03:00
static void
2021-01-03 06:17:51 +03:00
packL16(UINT8 *out, const UINT8 *in, int pixels) {
2017-09-29 16:39:16 +03:00
int i;
/* L -> L;16, e.g: \xff77 -> \x00\xff\x00\x77 */
for (i = 0; i < pixels; i++) {
out[0] = 0;
out[1] = in[i];
out += 2;
}
}
static void
2021-01-03 06:17:51 +03:00
packL16B(UINT8 *out, const UINT8 *in, int pixels) {
2017-09-29 16:39:16 +03:00
int i;
/* L -> L;16B, e.g: \xff77 -> \xff\x00\x77\x00 */
for (i = 0; i < pixels; i++) {
out[0] = in[i];
out[1] = 0;
out += 2;
}
}
2010-07-31 06:52:47 +04:00
static void
2021-01-03 06:17:51 +03:00
packLA(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* LA, pixel interleaved */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = in[R];
out[1] = in[A];
2021-01-03 06:17:51 +03:00
out += 2;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
static void
2021-01-03 06:17:51 +03:00
packLAL(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* LA, line interleaved */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[i] = in[R];
2021-01-03 06:17:51 +03:00
out[i + pixels] = in[A];
2016-12-03 17:07:49 +03:00
in += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackRGB(UINT8 *out, const UINT8 *in, int pixels) {
2017-08-18 01:13:50 +03:00
int i = 0;
2010-07-31 06:52:47 +04:00
/* RGB triplets */
#ifdef __sparc
/* SPARC CPUs cannot read integers from nonaligned addresses. */
for (; i < pixels; i++) {
out[0] = in[R];
out[1] = in[G];
out[2] = in[B];
2021-01-03 06:17:51 +03:00
out += 3;
in += 4;
}
#else
2021-01-03 06:17:51 +03:00
for (; i < pixels - 1; i++) {
memcpy(out, in + i * 4, 4);
2017-08-18 01:13:50 +03:00
out += 3;
}
for (; i < pixels; i++) {
2021-01-03 06:17:51 +03:00
out[0] = in[i * 4 + R];
out[1] = in[i * 4 + G];
out[2] = in[i * 4 + B];
2017-08-18 01:13:50 +03:00
out += 3;
2010-07-31 06:52:47 +04:00
}
#endif
2010-07-31 06:52:47 +04:00
}
void
2021-01-03 06:17:51 +03:00
ImagingPackXRGB(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* XRGB, triplets with left padding */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = 0;
out[1] = in[R];
out[2] = in[G];
out[3] = in[B];
2021-01-03 06:17:51 +03:00
out += 4;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackBGR(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* RGB, reversed bytes */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = in[B];
out[1] = in[G];
out[2] = in[R];
2021-01-03 06:17:51 +03:00
out += 3;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackBGRX(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* BGRX, reversed bytes with right padding */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = in[B];
out[1] = in[G];
out[2] = in[R];
out[3] = 0;
2021-01-03 06:17:51 +03:00
out += 4;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackXBGR(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* XBGR, reversed bytes with left padding */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = 0;
out[1] = in[B];
out[2] = in[G];
out[3] = in[R];
2021-01-03 06:17:51 +03:00
out += 4;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackBGRA(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* BGRX, reversed bytes with right padding */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = in[B];
out[1] = in[G];
out[2] = in[R];
out[3] = in[A];
2021-01-03 06:17:51 +03:00
out += 4;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackABGR(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* XBGR, reversed bytes with left padding */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = in[A];
out[1] = in[B];
out[2] = in[G];
out[3] = in[R];
2021-01-03 06:17:51 +03:00
out += 4;
in += 4;
2010-07-31 06:52:47 +04:00
}
}
2016-08-07 16:34:45 +03:00
void
2021-01-03 06:17:51 +03:00
ImagingPackBGRa(UINT8 *out, const UINT8 *in, int pixels) {
2016-08-07 16:34:45 +03:00
int i;
2016-08-25 14:43:31 +03:00
/* BGRa, reversed bytes with premultiplied alpha */
2016-08-07 16:34:45 +03:00
for (i = 0; i < pixels; i++) {
2016-08-08 01:09:55 +03:00
int alpha = out[3] = in[A];
int tmp;
out[0] = MULDIV255(in[B], alpha, tmp);
out[1] = MULDIV255(in[G], alpha, tmp);
out[2] = MULDIV255(in[R], alpha, tmp);
2021-01-03 06:17:51 +03:00
out += 4;
in += 4;
2016-08-07 16:34:45 +03:00
}
}
2010-07-31 06:52:47 +04:00
static void
2021-01-03 06:17:51 +03:00
packRGBL(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* RGB, line interleaved */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[i] = in[R];
2021-01-03 06:17:51 +03:00
out[i + pixels] = in[G];
out[i + pixels + pixels] = in[B];
2016-12-03 17:07:49 +03:00
in += 4;
2010-07-31 06:52:47 +04:00
}
}
static void
2021-01-03 06:17:51 +03:00
packRGBXL(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
/* RGBX, line interleaved */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[i] = in[R];
2021-01-03 06:17:51 +03:00
out[i + pixels] = in[G];
out[i + pixels + pixels] = in[B];
out[i + pixels + pixels + pixels] = in[X];
2016-12-03 17:07:49 +03:00
in += 4;
2010-07-31 06:52:47 +04:00
}
}
static void
2021-01-03 06:17:51 +03:00
packI16B(UINT8 *out, const UINT8 *in_, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
UINT16 tmp_;
2021-01-03 06:17:51 +03:00
UINT8 *tmp = (UINT8 *)&tmp_;
2010-07-31 06:52:47 +04:00
for (i = 0; i < pixels; i++) {
INT32 in;
memcpy(&in, in_, sizeof(in));
2020-05-10 12:56:36 +03:00
if (in <= 0) {
2010-07-31 06:52:47 +04:00
tmp_ = 0;
2020-05-10 12:56:36 +03:00
} else if (in > 65535) {
2010-07-31 06:52:47 +04:00
tmp_ = 65535;
2020-05-10 12:56:36 +03:00
} else {
tmp_ = in;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
C16B;
2021-01-03 06:17:51 +03:00
out += 2;
in_ += sizeof(in);
2010-07-31 06:52:47 +04:00
}
}
static void
2021-01-03 06:17:51 +03:00
packI16N_I16B(UINT8 *out, const UINT8 *in, int pixels) {
int i;
2021-01-03 06:17:51 +03:00
UINT8 *tmp = (UINT8 *)in;
for (i = 0; i < pixels; i++) {
C16B;
2021-01-03 06:17:51 +03:00
out += 2;
tmp += 2;
}
}
static void
2021-01-03 06:17:51 +03:00
packI16N_I16(UINT8 *out, const UINT8 *in, int pixels) {
int i;
2021-01-03 06:17:51 +03:00
UINT8 *tmp = (UINT8 *)in;
for (i = 0; i < pixels; i++) {
C16L;
2021-01-03 06:17:51 +03:00
out += 2;
tmp += 2;
}
}
2010-07-31 06:52:47 +04:00
static void
2021-01-03 06:17:51 +03:00
packI32S(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
2021-01-03 06:17:51 +03:00
UINT8 *tmp = (UINT8 *)in;
2010-07-31 06:52:47 +04:00
for (i = 0; i < pixels; i++) {
C32L;
2021-01-03 06:17:51 +03:00
out += 4;
tmp += 4;
2010-07-31 06:52:47 +04:00
}
}
void
2021-01-03 06:17:51 +03:00
ImagingPackLAB(UINT8 *out, const UINT8 *in, int pixels) {
int i;
/* LAB triplets */
for (i = 0; i < pixels; i++) {
2016-12-03 17:07:49 +03:00
out[0] = in[0];
out[1] = in[1] ^ 128; /* signed in outside world */
out[2] = in[2] ^ 128;
2021-01-03 06:17:51 +03:00
out += 3;
in += 4;
}
}
2010-07-31 06:52:47 +04:00
static void
2021-01-03 06:17:51 +03:00
copy1(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
/* L, P */
memcpy(out, in, pixels);
}
static void
2021-01-03 06:17:51 +03:00
copy2(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
/* I;16, etc */
2021-01-03 06:17:51 +03:00
memcpy(out, in, pixels * 2);
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
copy3(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
/* BGR;24, etc */
2021-01-03 06:17:51 +03:00
memcpy(out, in, pixels * 3);
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
copy4(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
/* RGBA, CMYK quadruples */
2021-01-03 06:17:51 +03:00
memcpy(out, in, 4 * pixels);
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
copy4I(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
/* RGBA, CMYK quadruples, inverted */
int i;
2021-01-03 06:17:51 +03:00
for (i = 0; i < pixels * 4; i++) {
2016-12-03 17:07:49 +03:00
out[i] = ~in[i];
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
band0(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
2020-05-10 12:56:36 +03:00
for (i = 0; i < pixels; i++, in += 4) {
2016-12-03 17:07:49 +03:00
out[i] = in[0];
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
band1(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
2020-05-10 12:56:36 +03:00
for (i = 0; i < pixels; i++, in += 4) {
2016-12-03 17:07:49 +03:00
out[i] = in[1];
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
band2(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
2020-05-10 12:56:36 +03:00
for (i = 0; i < pixels; i++, in += 4) {
2016-12-03 17:07:49 +03:00
out[i] = in[2];
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static void
2021-01-03 06:17:51 +03:00
band3(UINT8 *out, const UINT8 *in, int pixels) {
2010-07-31 06:52:47 +04:00
int i;
2020-05-10 12:56:36 +03:00
for (i = 0; i < pixels; i++, in += 4) {
2016-12-03 17:07:49 +03:00
out[i] = in[3];
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
}
static struct {
2021-01-03 06:17:51 +03:00
const char *mode;
const char *rawmode;
2010-07-31 06:52:47 +04:00
int bits;
ImagingShuffler pack;
} packers[] = {
/* bilevel */
2021-01-03 06:17:51 +03:00
{"1", "1", 1, pack1},
{"1", "1;I", 1, pack1I},
{"1", "1;R", 1, pack1R},
{"1", "1;IR", 1, pack1IR},
{"1", "L", 8, pack1L},
2010-07-31 06:52:47 +04:00
/* greyscale */
2021-01-03 06:17:51 +03:00
{"L", "L", 8, copy1},
{"L", "L;16", 16, packL16},
{"L", "L;16B", 16, packL16B},
2010-07-31 06:52:47 +04:00
/* greyscale w. alpha */
2021-01-03 06:17:51 +03:00
{"LA", "LA", 16, packLA},
{"LA", "LA;L", 16, packLAL},
2010-07-31 06:52:47 +04:00
2019-12-04 22:47:15 +03:00
/* greyscale w. alpha premultiplied */
2021-01-03 06:17:51 +03:00
{"La", "La", 16, packLA},
2019-12-04 22:47:15 +03:00
2010-07-31 06:52:47 +04:00
/* palette */
2021-01-03 06:17:51 +03:00
{"P", "P;1", 1, pack1},
{"P", "P;2", 2, packP2},
{"P", "P;4", 4, packP4},
{"P", "P", 8, copy1},
2010-07-31 06:52:47 +04:00
/* palette w. alpha */
2021-01-03 06:17:51 +03:00
{"PA", "PA", 16, packLA},
{"PA", "PA;L", 16, packLAL},
2010-07-31 06:52:47 +04:00
/* true colour */
2021-01-03 06:17:51 +03:00
{"RGB", "RGB", 24, ImagingPackRGB},
{"RGB", "RGBX", 32, copy4},
2022-02-17 02:04:43 +03:00
{"RGB", "RGBA", 32, copy4},
2021-01-03 06:17:51 +03:00
{"RGB", "XRGB", 32, ImagingPackXRGB},
{"RGB", "BGR", 24, ImagingPackBGR},
{"RGB", "BGRX", 32, ImagingPackBGRX},
{"RGB", "XBGR", 32, ImagingPackXBGR},
{"RGB", "RGB;L", 24, packRGBL},
{"RGB", "R", 8, band0},
{"RGB", "G", 8, band1},
{"RGB", "B", 8, band2},
2010-07-31 06:52:47 +04:00
/* true colour w. alpha */
2021-01-03 06:17:51 +03:00
{"RGBA", "RGBA", 32, copy4},
{"RGBA", "RGBA;L", 32, packRGBXL},
{"RGBA", "RGB", 24, ImagingPackRGB},
{"RGBA", "BGR", 24, ImagingPackBGR},
{"RGBA", "BGRA", 32, ImagingPackBGRA},
{"RGBA", "ABGR", 32, ImagingPackABGR},
{"RGBA", "BGRa", 32, ImagingPackBGRa},
{"RGBA", "R", 8, band0},
{"RGBA", "G", 8, band1},
{"RGBA", "B", 8, band2},
{"RGBA", "A", 8, band3},
2010-07-31 06:52:47 +04:00
/* true colour w. alpha premultiplied */
2021-01-03 06:17:51 +03:00
{"RGBa", "RGBa", 32, copy4},
{"RGBa", "BGRa", 32, ImagingPackBGRA},
{"RGBa", "aBGR", 32, ImagingPackABGR},
2010-07-31 06:52:47 +04:00
/* true colour w. padding */
2021-01-03 06:17:51 +03:00
{"RGBX", "RGBX", 32, copy4},
{"RGBX", "RGBX;L", 32, packRGBXL},
{"RGBX", "RGB", 24, ImagingPackRGB},
{"RGBX", "BGR", 24, ImagingPackBGR},
{"RGBX", "BGRX", 32, ImagingPackBGRX},
{"RGBX", "XBGR", 32, ImagingPackXBGR},
{"RGBX", "R", 8, band0},
{"RGBX", "G", 8, band1},
{"RGBX", "B", 8, band2},
{"RGBX", "X", 8, band3},
2010-07-31 06:52:47 +04:00
/* colour separation */
2021-01-03 06:17:51 +03:00
{"CMYK", "CMYK", 32, copy4},
{"CMYK", "CMYK;I", 32, copy4I},
{"CMYK", "CMYK;L", 32, packRGBXL},
{"CMYK", "C", 8, band0},
{"CMYK", "M", 8, band1},
{"CMYK", "Y", 8, band2},
{"CMYK", "K", 8, band3},
2010-07-31 06:52:47 +04:00
/* video (YCbCr) */
2021-01-03 06:17:51 +03:00
{"YCbCr", "YCbCr", 24, ImagingPackRGB},
{"YCbCr", "YCbCr;L", 24, packRGBL},
{"YCbCr", "YCbCrX", 32, copy4},
{"YCbCr", "YCbCrK", 32, copy4},
{"YCbCr", "Y", 8, band0},
{"YCbCr", "Cb", 8, band1},
{"YCbCr", "Cr", 8, band2},
2010-07-31 06:52:47 +04:00
2013-10-11 10:27:34 +04:00
/* LAB Color */
2021-01-03 06:17:51 +03:00
{"LAB", "LAB", 24, ImagingPackLAB},
{"LAB", "L", 8, band0},
{"LAB", "A", 8, band1},
{"LAB", "B", 8, band2},
2013-10-11 10:27:34 +04:00
/* HSV */
2021-01-03 06:17:51 +03:00
{"HSV", "HSV", 24, ImagingPackRGB},
{"HSV", "H", 8, band0},
{"HSV", "S", 8, band1},
{"HSV", "V", 8, band2},
2010-07-31 06:52:47 +04:00
/* integer */
2021-01-03 06:17:51 +03:00
{"I", "I", 32, copy4},
{"I", "I;16B", 16, packI16B},
{"I", "I;32S", 32, packI32S},
{"I", "I;32NS", 32, copy4},
2010-07-31 06:52:47 +04:00
/* floating point */
2021-01-03 06:17:51 +03:00
{"F", "F", 32, copy4},
{"F", "F;32F", 32, packI32S},
{"F", "F;32NF", 32, copy4},
2010-07-31 06:52:47 +04:00
/* storage modes */
2021-01-03 06:17:51 +03:00
{"I;16", "I;16", 16, copy2},
#ifdef WORDS_BIGENDIAN
{"I;16", "I;16B", 16, packI16N_I16},
#else
2021-01-03 06:17:51 +03:00
{"I;16", "I;16B", 16, packI16N_I16B},
#endif
2021-01-03 06:17:51 +03:00
{"I;16B", "I;16B", 16, copy2},
{"I;16L", "I;16L", 16, copy2},
{"I;16", "I;16N", 16, packI16N_I16}, // LibTiff native->image endian.
{"I;16L", "I;16N", 16, packI16N_I16},
{"I;16B", "I;16N", 16, packI16N_I16B},
{"BGR;15", "BGR;15", 16, copy2},
{"BGR;16", "BGR;16", 16, copy2},
{"BGR;24", "BGR;24", 24, copy3},
2010-07-31 06:52:47 +04:00
{NULL} /* sentinel */
};
ImagingShuffler
2021-01-03 06:17:51 +03:00
ImagingFindPacker(const char *mode, const char *rawmode, int *bits_out) {
2010-07-31 06:52:47 +04:00
int i;
/* find a suitable pixel packer */
2020-05-10 12:56:36 +03:00
for (i = 0; packers[i].rawmode; i++) {
2016-12-03 17:07:49 +03:00
if (strcmp(packers[i].mode, mode) == 0 &&
2010-07-31 06:52:47 +04:00
strcmp(packers[i].rawmode, rawmode) == 0) {
2020-05-10 12:56:36 +03:00
if (bits_out) {
2016-12-03 17:07:49 +03:00
*bits_out = packers[i].bits;
2020-05-10 12:56:36 +03:00
}
2016-12-03 17:07:49 +03:00
return packers[i].pack;
}
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
return NULL;
}