mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-10-22 19:54:46 +03:00
669 lines
17 KiB
C
669 lines
17 KiB
C
/*
|
|
* 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"
|
|
|
|
#define R 0
|
|
#define G 1
|
|
#define B 2
|
|
#define X 3
|
|
#define A 3
|
|
|
|
#define C 0
|
|
#define M 1
|
|
#define Y 2
|
|
#define K 3
|
|
|
|
/* byte swapping macros */
|
|
|
|
#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]);
|
|
|
|
#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
|
|
pack1(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i, m, b;
|
|
/* bilevel (black is 0) */
|
|
b = 0;
|
|
m = 128;
|
|
for (i = 0; i < pixels; i++) {
|
|
if (in[i] != 0) {
|
|
b |= m;
|
|
}
|
|
m >>= 1;
|
|
if (m == 0) {
|
|
*out++ = b;
|
|
b = 0;
|
|
m = 128;
|
|
}
|
|
}
|
|
if (m != 128) {
|
|
*out++ = b;
|
|
}
|
|
}
|
|
|
|
static void
|
|
pack1I(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i, m, b;
|
|
/* bilevel (black is 1) */
|
|
b = 0;
|
|
m = 128;
|
|
for (i = 0; i < pixels; i++) {
|
|
if (in[i] == 0) {
|
|
b |= m;
|
|
}
|
|
m >>= 1;
|
|
if (m == 0) {
|
|
*out++ = b;
|
|
b = 0;
|
|
m = 128;
|
|
}
|
|
}
|
|
if (m != 128) {
|
|
*out++ = b;
|
|
}
|
|
}
|
|
|
|
static void
|
|
pack1R(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i, m, b;
|
|
/* bilevel, lsb first (black is 0) */
|
|
b = 0;
|
|
m = 1;
|
|
for (i = 0; i < pixels; i++) {
|
|
if (in[i] != 0) {
|
|
b |= m;
|
|
}
|
|
m <<= 1;
|
|
if (m == 256) {
|
|
*out++ = b;
|
|
b = 0;
|
|
m = 1;
|
|
}
|
|
}
|
|
if (m != 1) {
|
|
*out++ = b;
|
|
}
|
|
}
|
|
|
|
static void
|
|
pack1IR(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i, m, b;
|
|
/* bilevel, lsb first (black is 1) */
|
|
b = 0;
|
|
m = 1;
|
|
for (i = 0; i < pixels; i++) {
|
|
if (in[i] == 0) {
|
|
b |= m;
|
|
}
|
|
m <<= 1;
|
|
if (m == 256) {
|
|
*out++ = b;
|
|
b = 0;
|
|
m = 1;
|
|
}
|
|
}
|
|
if (m != 1) {
|
|
*out++ = b;
|
|
}
|
|
}
|
|
|
|
static void
|
|
pack1L(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* bilevel, stored as bytes */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[i] = (in[i] != 0) ? 255 : 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packP4(UINT8 *out, const UINT8 *in, int pixels) {
|
|
while (pixels >= 2) {
|
|
*out++ = (in[0] << 4) | (in[1] & 15);
|
|
in += 2;
|
|
pixels -= 2;
|
|
}
|
|
|
|
if (pixels) {
|
|
out[0] = (in[0] << 4);
|
|
}
|
|
}
|
|
|
|
static void
|
|
packP2(UINT8 *out, const UINT8 *in, int pixels) {
|
|
while (pixels >= 4) {
|
|
*out++ = (in[0] << 6) | ((in[1] & 3) << 4) | ((in[2] & 3) << 2) | (in[3] & 3);
|
|
in += 4;
|
|
pixels -= 4;
|
|
}
|
|
|
|
switch (pixels) {
|
|
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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
packL16(UINT8 *out, const UINT8 *in, int pixels) {
|
|
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
|
|
packL16B(UINT8 *out, const UINT8 *in, int pixels) {
|
|
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;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packLA(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* LA, pixel interleaved */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = in[R];
|
|
out[1] = in[A];
|
|
out += 2;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packLAL(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* LA, line interleaved */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[i] = in[R];
|
|
out[i + pixels] = in[A];
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackRGB(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i = 0;
|
|
/* RGB triplets */
|
|
for (; i < pixels - 1; i++) {
|
|
memcpy(out, in + i * 4, 4);
|
|
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;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackXRGB(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* XRGB, triplets with left padding */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = 0;
|
|
out[1] = in[R];
|
|
out[2] = in[G];
|
|
out[3] = in[B];
|
|
out += 4;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackBGR(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* RGB, reversed bytes */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = in[B];
|
|
out[1] = in[G];
|
|
out[2] = in[R];
|
|
out += 3;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackBGRX(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* BGRX, reversed bytes with right padding */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = in[B];
|
|
out[1] = in[G];
|
|
out[2] = in[R];
|
|
out[3] = 0;
|
|
out += 4;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackXBGR(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* XBGR, reversed bytes with left padding */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = 0;
|
|
out[1] = in[B];
|
|
out[2] = in[G];
|
|
out[3] = in[R];
|
|
out += 4;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackBGRA(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* BGRA, reversed bytes with right alpha */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = in[B];
|
|
out[1] = in[G];
|
|
out[2] = in[R];
|
|
out[3] = in[A];
|
|
out += 4;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackABGR(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* ABGR, reversed bytes with left alpha */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = in[A];
|
|
out[1] = in[B];
|
|
out[2] = in[G];
|
|
out[3] = in[R];
|
|
out += 4;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackBGRa(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* BGRa, reversed bytes with premultiplied alpha */
|
|
for (i = 0; i < pixels; i++) {
|
|
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);
|
|
out += 4;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packRGBL(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* RGB, line interleaved */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[i] = in[R];
|
|
out[i + pixels] = in[G];
|
|
out[i + pixels + pixels] = in[B];
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packRGBXL(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* RGBX, line interleaved */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[i] = in[R];
|
|
out[i + pixels] = in[G];
|
|
out[i + pixels + pixels] = in[B];
|
|
out[i + pixels + pixels + pixels] = in[X];
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packI16B(UINT8 *out, const UINT8 *in_, int pixels) {
|
|
int i;
|
|
UINT16 tmp_;
|
|
UINT8 *tmp = (UINT8 *)&tmp_;
|
|
for (i = 0; i < pixels; i++) {
|
|
INT32 in;
|
|
memcpy(&in, in_, sizeof(in));
|
|
if (in <= 0) {
|
|
tmp_ = 0;
|
|
} else if (in > 65535) {
|
|
tmp_ = 65535;
|
|
} else {
|
|
tmp_ = in;
|
|
}
|
|
C16B;
|
|
out += 2;
|
|
in_ += sizeof(in);
|
|
}
|
|
}
|
|
|
|
static void
|
|
packI16N_I16B(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
UINT8 *tmp = (UINT8 *)in;
|
|
for (i = 0; i < pixels; i++) {
|
|
C16B;
|
|
out += 2;
|
|
tmp += 2;
|
|
}
|
|
}
|
|
static void
|
|
packI16N_I16(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
UINT8 *tmp = (UINT8 *)in;
|
|
for (i = 0; i < pixels; i++) {
|
|
C16L;
|
|
out += 2;
|
|
tmp += 2;
|
|
}
|
|
}
|
|
|
|
static void
|
|
packI32S(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
UINT8 *tmp = (UINT8 *)in;
|
|
for (i = 0; i < pixels; i++) {
|
|
C32L;
|
|
out += 4;
|
|
tmp += 4;
|
|
}
|
|
}
|
|
|
|
void
|
|
ImagingPackLAB(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
/* LAB triplets */
|
|
for (i = 0; i < pixels; i++) {
|
|
out[0] = in[0];
|
|
out[1] = in[1] ^ 128; /* signed in outside world */
|
|
out[2] = in[2] ^ 128;
|
|
out += 3;
|
|
in += 4;
|
|
}
|
|
}
|
|
|
|
static void
|
|
copy1(UINT8 *out, const UINT8 *in, int pixels) {
|
|
/* L, P */
|
|
memcpy(out, in, pixels);
|
|
}
|
|
|
|
static void
|
|
copy2(UINT8 *out, const UINT8 *in, int pixels) {
|
|
/* I;16, etc */
|
|
memcpy(out, in, pixels * 2);
|
|
}
|
|
|
|
static void
|
|
copy4(UINT8 *out, const UINT8 *in, int pixels) {
|
|
/* RGBA, CMYK quadruples */
|
|
memcpy(out, in, 4 * pixels);
|
|
}
|
|
|
|
static void
|
|
copy4I(UINT8 *out, const UINT8 *in, int pixels) {
|
|
/* RGBA, CMYK quadruples, inverted */
|
|
int i;
|
|
for (i = 0; i < pixels * 4; i++) {
|
|
out[i] = ~in[i];
|
|
}
|
|
}
|
|
|
|
static void
|
|
band0(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
for (i = 0; i < pixels; i++, in += 4) {
|
|
out[i] = in[0];
|
|
}
|
|
}
|
|
|
|
static void
|
|
band1(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
for (i = 0; i < pixels; i++, in += 4) {
|
|
out[i] = in[1];
|
|
}
|
|
}
|
|
|
|
static void
|
|
band2(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
for (i = 0; i < pixels; i++, in += 4) {
|
|
out[i] = in[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
band3(UINT8 *out, const UINT8 *in, int pixels) {
|
|
int i;
|
|
for (i = 0; i < pixels; i++, in += 4) {
|
|
out[i] = in[3];
|
|
}
|
|
}
|
|
|
|
static struct {
|
|
const ModeID mode;
|
|
const RawModeID rawmode;
|
|
int bits;
|
|
ImagingShuffler pack;
|
|
} packers[] = {
|
|
|
|
/* bilevel */
|
|
{IMAGING_MODE_1, IMAGING_RAWMODE_1, 1, pack1},
|
|
{IMAGING_MODE_1, IMAGING_RAWMODE_1_I, 1, pack1I},
|
|
{IMAGING_MODE_1, IMAGING_RAWMODE_1_R, 1, pack1R},
|
|
{IMAGING_MODE_1, IMAGING_RAWMODE_1_IR, 1, pack1IR},
|
|
{IMAGING_MODE_1, IMAGING_RAWMODE_L, 8, pack1L},
|
|
|
|
/* grayscale */
|
|
{IMAGING_MODE_L, IMAGING_RAWMODE_L, 8, copy1},
|
|
{IMAGING_MODE_L, IMAGING_RAWMODE_L_16, 16, packL16},
|
|
{IMAGING_MODE_L, IMAGING_RAWMODE_L_16B, 16, packL16B},
|
|
|
|
/* grayscale w. alpha */
|
|
{IMAGING_MODE_LA, IMAGING_RAWMODE_LA, 16, packLA},
|
|
{IMAGING_MODE_LA, IMAGING_RAWMODE_LA_L, 16, packLAL},
|
|
|
|
/* grayscale w. alpha premultiplied */
|
|
{IMAGING_MODE_La, IMAGING_RAWMODE_La, 16, packLA},
|
|
|
|
/* palette */
|
|
{IMAGING_MODE_P, IMAGING_RAWMODE_P_1, 1, pack1},
|
|
{IMAGING_MODE_P, IMAGING_RAWMODE_P_2, 2, packP2},
|
|
{IMAGING_MODE_P, IMAGING_RAWMODE_P_4, 4, packP4},
|
|
{IMAGING_MODE_P, IMAGING_RAWMODE_P, 8, copy1},
|
|
|
|
/* palette w. alpha */
|
|
{IMAGING_MODE_PA, IMAGING_RAWMODE_PA, 16, packLA},
|
|
{IMAGING_MODE_PA, IMAGING_RAWMODE_PA_L, 16, packLAL},
|
|
|
|
/* true colour */
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB, 24, ImagingPackRGB},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBX, 32, copy4},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBA, 32, copy4},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_XRGB, 32, ImagingPackXRGB},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_BGR, 24, ImagingPackBGR},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_BGRX, 32, ImagingPackBGRX},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_XBGR, 32, ImagingPackXBGR},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_L, 24, packRGBL},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_R, 8, band0},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_G, 8, band1},
|
|
{IMAGING_MODE_RGB, IMAGING_RAWMODE_B, 8, band2},
|
|
|
|
/* true colour w. alpha */
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA, 32, copy4},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_L, 32, packRGBXL},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGB, 24, ImagingPackRGB},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGR, 24, ImagingPackBGR},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA, 32, ImagingPackBGRA},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_ABGR, 32, ImagingPackABGR},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRa, 32, ImagingPackBGRa},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_R, 8, band0},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_G, 8, band1},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_B, 8, band2},
|
|
{IMAGING_MODE_RGBA, IMAGING_RAWMODE_A, 8, band3},
|
|
|
|
/* true colour w. alpha premultiplied */
|
|
{IMAGING_MODE_RGBa, IMAGING_RAWMODE_RGBa, 32, copy4},
|
|
{IMAGING_MODE_RGBa, IMAGING_RAWMODE_BGRa, 32, ImagingPackBGRA},
|
|
{IMAGING_MODE_RGBa, IMAGING_RAWMODE_aBGR, 32, ImagingPackABGR},
|
|
|
|
/* true colour w. padding */
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX, 32, copy4},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_L, 32, packRGBXL},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB, 24, ImagingPackRGB},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGR, 24, ImagingPackBGR},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGRX, 32, ImagingPackBGRX},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_XBGR, 32, ImagingPackXBGR},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_R, 8, band0},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_G, 8, band1},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_B, 8, band2},
|
|
{IMAGING_MODE_RGBX, IMAGING_RAWMODE_X, 8, band3},
|
|
|
|
/* colour separation */
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK, 32, copy4},
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_I, 32, copy4I},
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_L, 32, packRGBXL},
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_C, 8, band0},
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_M, 8, band1},
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_Y, 8, band2},
|
|
{IMAGING_MODE_CMYK, IMAGING_RAWMODE_K, 8, band3},
|
|
|
|
/* video (YCbCr) */
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCr, 24, ImagingPackRGB},
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCr_L, 24, packRGBL},
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCrX, 32, copy4},
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCrK, 32, copy4},
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_Y, 8, band0},
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_Cb, 8, band1},
|
|
{IMAGING_MODE_YCbCr, IMAGING_RAWMODE_Cr, 8, band2},
|
|
|
|
/* LAB Color */
|
|
{IMAGING_MODE_LAB, IMAGING_RAWMODE_LAB, 24, ImagingPackLAB},
|
|
{IMAGING_MODE_LAB, IMAGING_RAWMODE_L, 8, band0},
|
|
{IMAGING_MODE_LAB, IMAGING_RAWMODE_A, 8, band1},
|
|
{IMAGING_MODE_LAB, IMAGING_RAWMODE_B, 8, band2},
|
|
|
|
/* HSV */
|
|
{IMAGING_MODE_HSV, IMAGING_RAWMODE_HSV, 24, ImagingPackRGB},
|
|
{IMAGING_MODE_HSV, IMAGING_RAWMODE_H, 8, band0},
|
|
{IMAGING_MODE_HSV, IMAGING_RAWMODE_S, 8, band1},
|
|
{IMAGING_MODE_HSV, IMAGING_RAWMODE_V, 8, band2},
|
|
|
|
/* integer */
|
|
{IMAGING_MODE_I, IMAGING_RAWMODE_I, 32, copy4},
|
|
{IMAGING_MODE_I, IMAGING_RAWMODE_I_16B, 16, packI16B},
|
|
{IMAGING_MODE_I, IMAGING_RAWMODE_I_32S, 32, packI32S},
|
|
{IMAGING_MODE_I, IMAGING_RAWMODE_I_32NS, 32, copy4},
|
|
|
|
/* floating point */
|
|
{IMAGING_MODE_F, IMAGING_RAWMODE_F, 32, copy4},
|
|
{IMAGING_MODE_F, IMAGING_RAWMODE_F_32F, 32, packI32S},
|
|
{IMAGING_MODE_F, IMAGING_RAWMODE_F_32NF, 32, copy4},
|
|
|
|
/* storage modes */
|
|
{IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16, 16, copy2},
|
|
#ifdef WORDS_BIGENDIAN
|
|
{IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16B, 16, packI16N_I16},
|
|
#else
|
|
{IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16B, 16, packI16N_I16B},
|
|
#endif
|
|
{IMAGING_MODE_I_16B, IMAGING_RAWMODE_I_16B, 16, copy2},
|
|
{IMAGING_MODE_I_16L, IMAGING_RAWMODE_I_16L, 16, copy2},
|
|
{IMAGING_MODE_I_16N, IMAGING_RAWMODE_I_16N, 16, copy2},
|
|
{IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16N, 16, packI16N_I16
|
|
}, // LibTiff native->image endian.
|
|
{IMAGING_MODE_I_16L, IMAGING_RAWMODE_I_16N, 16, packI16N_I16},
|
|
{IMAGING_MODE_I_16B, IMAGING_RAWMODE_I_16N, 16, packI16N_I16B}
|
|
};
|
|
|
|
ImagingShuffler
|
|
ImagingFindPacker(const ModeID mode, const RawModeID rawmode, int *bits_out) {
|
|
for (size_t i = 0; i < sizeof(packers) / sizeof(*packers); i++) {
|
|
if (packers[i].mode == mode && packers[i].rawmode == rawmode) {
|
|
if (bits_out) {
|
|
*bits_out = packers[i].bits;
|
|
}
|
|
return packers[i].pack;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|