123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533 |
- /*
- * The Python Imaging Library.
- * $Id$
- *
- * code to unpack raw data from various file formats
- *
- * history:
- * 1996-03-07 fl Created (from various decoders)
- * 1996-04-19 fl Added band unpackers
- * 1996-05-12 fl Published RGB unpackers
- * 1996-05-27 fl Added nibble unpacker
- * 1996-12-10 fl Added complete set of PNG unpackers
- * 1996-12-29 fl Set alpha byte in RGB unpackers
- * 1997-01-05 fl Added remaining TGA unpackers
- * 1997-01-18 fl Added inverting band unpackers
- * 1997-01-25 fl Added FlashPix unpackers
- * 1997-05-31 fl Added floating point unpackers
- * 1998-02-08 fl Added I unpacker
- * 1998-07-01 fl Added YCbCr unpacker
- * 1998-07-02 fl Added full set of integer unpackers
- * 1998-12-29 fl Added mode field, I;16 unpackers
- * 1998-12-30 fl Added RGBX modes
- * 1999-02-04 fl Fixed I;16 unpackers
- * 2003-05-13 fl Added L/RGB reversed unpackers
- * 2003-09-26 fl Added LA/PA and RGBa->RGB unpackers
- *
- * Copyright (c) 1997-2003 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\
- (tmp[0]=in[0], tmp[1]=in[1]);
- #define C16S\
- (tmp[1]=in[0], tmp[0]=in[1]);
- #define C32N\
- (tmp[0]=in[0], tmp[1]=in[1], tmp[2]=in[2], tmp[3]=in[3]);
- #define C32S\
- (tmp[3]=in[0], tmp[2]=in[1], tmp[1]=in[2], tmp[0]=in[3]);
- #define C64N\
- (tmp[0]=in[0], tmp[1]=in[1], tmp[2]=in[2], tmp[3]=in[3],\
- tmp[4]=in[4], tmp[5]=in[5], tmp[6]=in[6], tmp[7]=in[7]);
- #define C64S\
- (tmp[7]=in[0], tmp[6]=in[1], tmp[5]=in[2], tmp[4]=in[3],\
- tmp[3]=in[4], tmp[2]=in[5], tmp[1]=in[6], tmp[0]=in[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
- /* bit-swapping */
- static UINT8 BITFLIP[] = {
- 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112,
- 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184,
- 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52,
- 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220,
- 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82,
- 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154,
- 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22,
- 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238,
- 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97,
- 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169,
- 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37,
- 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205,
- 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67,
- 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139,
- 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7,
- 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
- 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127,
- 255
- };
- /* Unpack to "1" image */
- static void
- unpack1(UINT8* out, const UINT8* in, int pixels)
- {
- /* bits (msb first, white is non-zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 7: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 6: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 5: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 4: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 3: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 2: *out++ = (byte & 128) ? 255 : 0; byte <<= 1;
- case 1: *out++ = (byte & 128) ? 255 : 0;
- }
- pixels -= 8;
- }
- }
- static void
- unpack1I(UINT8* out, const UINT8* in, int pixels)
- {
- /* bits (msb first, white is zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 7: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 6: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 5: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 4: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 3: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 2: *out++ = (byte & 128) ? 0 : 255; byte <<= 1;
- case 1: *out++ = (byte & 128) ? 0 : 255;
- }
- pixels -= 8;
- }
- }
- static void
- unpack1R(UINT8* out, const UINT8* in, int pixels)
- {
- /* bits (lsb first, white is non-zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 7: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 6: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 5: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 4: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 3: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 2: *out++ = (byte & 1) ? 255 : 0; byte >>= 1;
- case 1: *out++ = (byte & 1) ? 255 : 0;
- }
- pixels -= 8;
- }
- }
- static void
- unpack1IR(UINT8* out, const UINT8* in, int pixels)
- {
- /* bits (lsb first, white is zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 7: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 6: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 5: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 4: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 3: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 2: *out++ = (byte & 1) ? 0 : 255; byte >>= 1;
- case 1: *out++ = (byte & 1) ? 0 : 255;
- }
- pixels -= 8;
- }
- }
- static void
- unpack18(UINT8* out, const UINT8* in, int pixels)
- {
- /* Unpack a '|b1' image, which is a numpy boolean.
- 1 == true, 0==false, in bytes */
- int i;
- for (i = 0; i < pixels; i++) {
- out[i] = in[i] > 0 ? 255 : 0;
- }
- }
- /* Unpack to "L" image */
- static void
- unpackL2(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (msb first, white is non-zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
- case 3: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
- case 2: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
- case 1: *out++ = ((byte >> 6) & 0x03U) * 0x55U;
- }
- pixels -= 4;
- }
- }
- static void
- unpackL2I(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (msb first, white is zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
- case 3: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
- case 2: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
- case 1: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U);
- }
- pixels -= 4;
- }
- }
- static void
- unpackL2R(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (bit order reversed, white is non-zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- byte = BITFLIP[byte];
- switch (pixels) {
- default: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
- case 3: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
- case 2: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
- case 1: *out++ = ((byte >> 6) & 0x03U) * 0x55U;
- }
- pixels -= 4;
- }
- }
- static void
- unpackL2IR(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (bit order reversed, white is zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- byte = BITFLIP[byte];
- switch (pixels) {
- default: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
- case 3: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
- case 2: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
- case 1: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U);
- }
- pixels -= 4;
- }
- }
- static void
- unpackL4(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (msb first, white is non-zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = ((byte >> 4) & 0x0FU) * 0x11U; byte <<= 4;
- case 1: *out++ = ((byte >> 4) & 0x0FU) * 0x11U;
- }
- pixels -= 2;
- }
- }
- static void
- unpackL4I(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (msb first, white is zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U); byte <<= 4;
- case 1: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U);
- }
- pixels -= 2;
- }
- }
- static void
- unpackL4R(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (bit order reversed, white is non-zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- byte = BITFLIP[byte];
- switch (pixels) {
- default: *out++ = ((byte >> 4) & 0x0FU) * 0x11U; byte <<= 4;
- case 1: *out++ = ((byte >> 4) & 0x0FU) * 0x11U;
- }
- pixels -= 2;
- }
- }
- static void
- unpackL4IR(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles (bit order reversed, white is zero) */
- while (pixels > 0) {
- UINT8 byte = *in++;
- byte = BITFLIP[byte];
- switch (pixels) {
- default: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U); byte <<= 4;
- case 1: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U);
- }
- pixels -= 2;
- }
- }
- static void
- unpackLA(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* LA, pixel interleaved */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[1]);
- memcpy(_out, &iv, sizeof(iv));
- in += 2; _out += 4;
- }
- }
- static void
- unpackLAL(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* LA, line interleaved */
- for (i = 0; i < pixels; i++, _out+=4) {
- UINT32 iv = MAKE_UINT32(in[i], in[i], in[i], in[i+pixels]);
- memcpy(_out, &iv, sizeof(iv));
- }
- }
- static void
- unpackLI(UINT8* out, const UINT8* in, int pixels)
- {
- /* negative */
- int i;
- for (i = 0; i < pixels; i++)
- out[i] = ~in[i];
- }
- static void
- unpackLR(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, bit reversed */
- for (i = 0; i < pixels; i++) {
- out[i] = BITFLIP[in[i]];
- }
- }
- static void
- unpackL16(UINT8* out, const UINT8* in, int pixels)
- {
- /* int16 (upper byte, little endian) */
- int i;
- for (i = 0; i < pixels; i++) {
- out[i] = in[1];
- in += 2;
- }
- }
- static void
- unpackL16B(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* int16 (upper byte, big endian) */
- for (i = 0; i < pixels; i++) {
- out[i] = in[0];
- in += 2;
- }
- }
- /* Unpack to "P" image */
- static void
- unpackP1(UINT8* out, const UINT8* in, int pixels)
- {
- /* bits */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 7: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 6: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 5: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 4: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 3: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 2: *out++ = (byte >> 7) & 1; byte <<= 1;
- case 1: *out++ = (byte >> 7) & 1;
- }
- pixels -= 8;
- }
- }
- static void
- unpackP2(UINT8* out, const UINT8* in, int pixels)
- {
- /* bit pairs */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte >> 6) & 3; byte <<= 2;
- case 3: *out++ = (byte >> 6) & 3; byte <<= 2;
- case 2: *out++ = (byte >> 6) & 3; byte <<= 2;
- case 1: *out++ = (byte >> 6) & 3;
- }
- pixels -= 4;
- }
- }
- static void
- unpackP4(UINT8* out, const UINT8* in, int pixels)
- {
- /* nibbles */
- while (pixels > 0) {
- UINT8 byte = *in++;
- switch (pixels) {
- default: *out++ = (byte >> 4) & 15; byte <<= 4;
- case 1: *out++ = (byte >> 4) & 15;
- }
- pixels -= 2;
- }
- }
- static void
- unpackP2L(UINT8* out, const UINT8* in, int pixels)
- {
- int i, j, m, s;
- /* bit layers */
- m = 128;
- s = (pixels+7)/8;
- for (i = j = 0; i < pixels; i++) {
- out[i] = ((in[j] & m) ? 1 : 0) + ((in[j + s] & m) ? 2 : 0);
- if ((m >>= 1) == 0) {
- m = 128;
- j++;
- }
- }
- }
- static void
- unpackP4L(UINT8* out, const UINT8* in, int pixels)
- {
- int i, j, m, s;
- /* bit layers (trust the optimizer ;-) */
- m = 128;
- s = (pixels+7)/8;
- for (i = j = 0; i < pixels; i++) {
- out[i] = ((in[j] & m) ? 1 : 0) + ((in[j + s] & m) ? 2 : 0) +
- ((in[j + 2*s] & m) ? 4 : 0) + ((in[j + 3*s] & m) ? 8 : 0);
- if ((m >>= 1) == 0) {
- m = 128;
- j++;
- }
- }
- }
- /* Unpack to "RGB" image */
- void
- ImagingUnpackRGB(UINT8* _out, const UINT8* in, int pixels)
- {
- int i = 0;
- /* RGB triplets */
- for (; i < pixels-1; i++) {
- UINT32 iv;
- memcpy(&iv, in, sizeof(iv));
- iv |= MASK_UINT32_CHANNEL_3;
- memcpy(_out, &iv, sizeof(iv));
- in += 3; _out += 4;
- }
- for (; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[0], in[1], in[2], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 3; _out += 4;
- }
- }
- void
- unpackRGB16L(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* 16-bit RGB triplets, little-endian order */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[1], in[3], in[5], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 6; _out += 4;
- }
- }
- void
- unpackRGB16B(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* 16-bit RGB triplets, big-endian order */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[0], in[2], in[4], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 6; _out += 4;
- }
- }
- static void
- unpackRGBL(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, line interleaved */
- for (i = 0; i < pixels; i++, _out+=4) {
- UINT32 iv = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], 255);
- memcpy(_out, &iv, sizeof(iv));
- }
- }
- static void
- unpackRGBR(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, bit reversed */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(BITFLIP[in[0]], BITFLIP[in[1]],
- BITFLIP[in[2]], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 3; _out += 4;
- }
- }
- void
- ImagingUnpackBGR(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, reversed bytes */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 3; _out += 4;
- }
- }
- void
- ImagingUnpackRGB15(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, 5 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[R] = (pixel & 31) * 255 / 31;
- out[G] = ((pixel>>5) & 31) * 255 / 31;
- out[B] = ((pixel>>10) & 31) * 255 / 31;
- out[A] = 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackRGBA15(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, 5/5/5/1 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[R] = (pixel & 31) * 255 / 31;
- out[G] = ((pixel>>5) & 31) * 255 / 31;
- out[B] = ((pixel>>10) & 31) * 255 / 31;
- out[A] = (pixel>>15) * 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackBGR15(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, reversed bytes, 5 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[B] = (pixel & 31) * 255 / 31;
- out[G] = ((pixel>>5) & 31) * 255 / 31;
- out[R] = ((pixel>>10) & 31) * 255 / 31;
- out[A] = 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackBGRA15(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, reversed bytes, 5/5/5/1 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[B] = (pixel & 31) * 255 / 31;
- out[G] = ((pixel>>5) & 31) * 255 / 31;
- out[R] = ((pixel>>10) & 31) * 255 / 31;
- out[A] = (pixel>>15) * 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackRGB16(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, 5/6/5 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[R] = (pixel & 31) * 255 / 31;
- out[G] = ((pixel>>5) & 63) * 255 / 63;
- out[B] = ((pixel>>11) & 31) * 255 / 31;
- out[A] = 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackBGR16(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, reversed bytes, 5/6/5 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[B] = (pixel & 31) * 255 / 31;
- out[G] = ((pixel>>5) & 63) * 255 / 63;
- out[R] = ((pixel>>11) & 31) * 255 / 31;
- out[A] = 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackRGB4B(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGB, 4 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[R] = (pixel & 15) * 17;
- out[G] = ((pixel>>4) & 15) * 17;
- out[B] = ((pixel>>8) & 15) * 17;
- out[A] = 255;
- out += 4; in += 2;
- }
- }
- void
- ImagingUnpackRGBA4B(UINT8* out, const UINT8* in, int pixels)
- {
- int i, pixel;
- /* RGBA, 4 bits per pixel */
- for (i = 0; i < pixels; i++) {
- pixel = in[0] + (in[1] << 8);
- out[R] = (pixel & 15) * 17;
- out[G] = ((pixel>>4) & 15) * 17;
- out[B] = ((pixel>>8) & 15) * 17;
- out[A] = ((pixel>>12) & 15) * 17;
- out += 4; in += 2;
- }
- }
- static void
- ImagingUnpackBGRX(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, reversed bytes with padding */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- ImagingUnpackXRGB(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, leading pad */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[1], in[2], in[3], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- ImagingUnpackXBGR(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGB, reversed bytes, leading pad */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[3], in[2], in[1], 255);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- /* Unpack to "RGBA" image */
- static void
- unpackRGBALA(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* greyscale with alpha */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[1]);
- memcpy(_out, &iv, sizeof(iv));
- in += 2; _out += 4;
- }
- }
- static void
- unpackRGBALA16B(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* 16-bit greyscale with alpha, big-endian */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[2]);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- unpackRGBa16L(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* premultiplied 16-bit RGBA, little-endian */
- for (i = 0; i < pixels; i++) {
- int a = in[7];
- UINT32 iv;
- if ( ! a) {
- iv = 0;
- } else if (a == 255) {
- iv = MAKE_UINT32(in[1], in[3], in[5], a);
- } else {
- iv = MAKE_UINT32(CLIP8(in[1] * 255 / a),
- CLIP8(in[3] * 255 / a),
- CLIP8(in[5] * 255 / a), a);
- }
- memcpy(_out, &iv, sizeof(iv));
- in += 8; _out += 4;
- }
- }
- static void
- unpackRGBa16B(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* premultiplied 16-bit RGBA, big-endian */
- for (i = 0; i < pixels; i++) {
- int a = in[6];
- UINT32 iv;
- if ( ! a) {
- iv = 0;
- } else if (a == 255) {
- iv = MAKE_UINT32(in[0], in[2], in[4], a);
- } else {
- iv = MAKE_UINT32(CLIP8(in[0] * 255 / a),
- CLIP8(in[2] * 255 / a),
- CLIP8(in[4] * 255 / a), a);
- }
- memcpy(_out, &iv, sizeof(iv));
- in += 8; _out += 4;
- }
- }
- static void
- unpackRGBa(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* premultiplied RGBA */
- for (i = 0; i < pixels; i++) {
- int a = in[3];
- UINT32 iv;
- if ( ! a) {
- iv = 0;
- } else if (a == 255) {
- iv = MAKE_UINT32(in[0], in[1], in[2], a);
- } else {
- iv = MAKE_UINT32(CLIP8(in[0] * 255 / a),
- CLIP8(in[1] * 255 / a),
- CLIP8(in[2] * 255 / a), a);
- }
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- unpackRGBaskip1(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[i] = 0;
- } else if (a == 255) {
- out[i] = MAKE_UINT32(in[0], in[1], in[2], a);
- } else {
- out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a),
- CLIP8(in[1] * 255 / a),
- CLIP8(in[2] * 255 / a), a);
- }
- in += 5;
- }
- }
- static void
- unpackRGBaskip2(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[i] = 0;
- } else if (a == 255) {
- out[i] = MAKE_UINT32(in[0], in[1], in[2], a);
- } else {
- out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a),
- CLIP8(in[1] * 255 / a),
- CLIP8(in[2] * 255 / a), a);
- }
- in += 6;
- }
- }
- static void
- unpackBGRa(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* premultiplied BGRA */
- for (i = 0; i < pixels; i++) {
- int a = in[3];
- UINT32 iv;
- if ( ! a) {
- iv = 0;
- } else if (a == 255) {
- iv = MAKE_UINT32(in[2], in[1], in[0], a);
- } else {
- iv = MAKE_UINT32(CLIP8(in[2] * 255 / a),
- CLIP8(in[1] * 255 / a),
- CLIP8(in[0] * 255 / a), a);
- }
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- unpackRGBAI(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* RGBA, inverted RGB bytes (FlashPix) */
- for (i = 0; i < pixels; i++) {
- out[R] = ~in[0];
- out[G] = ~in[1];
- out[B] = ~in[2];
- out[A] = in[3];
- out += 4; in += 4;
- }
- }
- static void
- unpackRGBAL(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGBA, line interleaved */
- for (i = 0; i < pixels; i++, _out+=4) {
- UINT32 iv = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels],
- in[i+pixels+pixels+pixels]);
- memcpy(_out, &iv, sizeof(iv));
- }
- }
- void
- unpackRGBA16L(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* 16-bit RGBA, little-endian order */
- for (i = 0; i < pixels; i++, _out+=4) {
- UINT32 iv = MAKE_UINT32(in[1], in[3], in[5], in[7]);
- memcpy(_out, &iv, sizeof(iv));
- in += 8;
- }
- }
- void
- unpackRGBA16B(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* 16-bit RGBA, big-endian order */
- for (i = 0; i < pixels; i++, _out+=4) {
- UINT32 iv = MAKE_UINT32(in[0], in[2], in[4], in[6]);
- memcpy(_out, &iv, sizeof(iv));
- in += 8;
- }
- }
- static void
- unpackARGB(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGBA, leading pad */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[1], in[2], in[3], in[0]);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- unpackABGR(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGBA, reversed bytes */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[3], in[2], in[1], in[0]);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- static void
- unpackBGRA(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* RGBA, reversed bytes */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], in[3]);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- /* Unpack to "CMYK" image */
- static void
- unpackCMYKI(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- /* CMYK, inverted bytes (Photoshop 2.5) */
- for (i = 0; i < pixels; i++) {
- UINT32 iv = ~MAKE_UINT32(in[0], in[1], in[2], in[3]);
- memcpy(_out, &iv, sizeof(iv));
- in += 4; _out += 4;
- }
- }
- /* Unpack to "LAB" image */
- /* There are two representations of LAB images for whatever precision:
- L: Uint (in PS, it's 0-100)
- A: Int (in ps, -128 .. 128, or elsewhere 0..255, with 128 as middle.
- Channels in PS display a 0 value as middle grey,
- LCMS appears to use 128 as the 0 value for these channels)
- B: Int (as above)
- Since we don't have any signed ints, we're going with the shifted versions
- internally, and we'll unshift for saving and whatnot.
- */
- void
- ImagingUnpackLAB(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] = 255;
- out += 4; in += 3;
- }
- }
- static void
- unpackI16N_I16B(UINT8* out, const UINT8* in, int pixels){
- int i;
- UINT8* tmp = (UINT8*) out;
- for (i = 0; i < pixels; i++) {
- C16B;
- in += 2; tmp += 2;
- }
- }
- static void
- unpackI16N_I16(UINT8* out, const UINT8* in, int pixels){
- int i;
- UINT8* tmp = (UINT8*) out;
- for (i = 0; i < pixels; i++) {
- C16L;
- in += 2; tmp += 2;
- }
- }
- static void
- unpackI12_I16(UINT8* out, const UINT8* in, int pixels){
- /* Fillorder 1/MSB -> LittleEndian, for 12bit integer greyscale tiffs.
- According to the TIFF spec:
- FillOrder = 2 should be used only when BitsPerSample = 1 and
- the data is either uncompressed or compressed using CCITT 1D
- or 2D compression, to avoid potentially ambiguous situations.
- Yeah. I thought so. We'll see how well people read the spec.
- We've got several fillorder=2 modes in TiffImagePlugin.py
- There's no spec I can find. It appears that the in storage
- layout is: 00 80 00 ... -> (128 , 0 ...). The samples are
- stored in a single big bitian 12bit block, but need to be
- pulled out to little endian format to be stored in a 2 byte
- int.
- */
- int i;
- UINT16 pixel;
- #ifdef WORDS_BIGENDIAN
- UINT8* tmp = (UINT8 *)&pixel;
- #endif
- for (i = 0; i < pixels-1; i+=2) {
- pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4);
- #ifdef WORDS_BIGENDIAN
- out[0] = tmp[1]; out[1] = tmp[0];
- #else
- memcpy(out, &pixel, sizeof(pixel));
- #endif
- out+=2;
- pixel = (((UINT16) (in[1] & 0x0F)) << 8) + in[2];
- #ifdef WORDS_BIGENDIAN
- out[0] = tmp[1]; out[1] = tmp[0];
- #else
- memcpy(out, &pixel, sizeof(pixel));
- #endif
- in += 3; out+=2;
- }
- if (i == pixels-1) {
- pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4);
- #ifdef WORDS_BIGENDIAN
- out[0] = tmp[1]; out[1] = tmp[0];
- #else
- memcpy(out, &pixel, sizeof(pixel));
- #endif
- }
- }
- 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 */
- 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
- copy4skip1(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- for (i = 0; i < pixels; i++) {
- memcpy(_out, in, 4);
- in += 5; _out += 4;
- }
- }
- static void
- copy4skip2(UINT8* _out, const UINT8* in, int pixels)
- {
- int i;
- for (i = 0; i < pixels; i++) {
- memcpy(_out, in, 4);
- in += 6; _out += 4;
- }
- }
- /* Unpack to "I" and "F" images */
- #define UNPACK_RAW(NAME, GET, INTYPE, OUTTYPE)\
- static void NAME(UINT8* out_, const UINT8* in, int pixels)\
- {\
- int i;\
- OUTTYPE* out = (OUTTYPE*) out_;\
- for (i = 0; i < pixels; i++, in += sizeof(INTYPE))\
- out[i] = (OUTTYPE) ((INTYPE) GET);\
- }
- #define UNPACK(NAME, COPY, INTYPE, OUTTYPE)\
- static void NAME(UINT8* out_, const UINT8* in, int pixels)\
- {\
- int i;\
- OUTTYPE* out = (OUTTYPE*) out_;\
- INTYPE tmp_;\
- UINT8* tmp = (UINT8*) &tmp_;\
- for (i = 0; i < pixels; i++, in += sizeof(INTYPE)) {\
- COPY;\
- out[i] = (OUTTYPE) tmp_;\
- }\
- }
- UNPACK_RAW(unpackI8, in[0], UINT8, INT32)
- UNPACK_RAW(unpackI8S, in[0], INT8, INT32)
- UNPACK(unpackI16, C16L, UINT16, INT32)
- UNPACK(unpackI16S, C16L, INT16, INT32)
- UNPACK(unpackI16B, C16B, UINT16, INT32)
- UNPACK(unpackI16BS, C16B, INT16, INT32)
- UNPACK(unpackI16N, C16N, UINT16, INT32)
- UNPACK(unpackI16NS, C16N, INT16, INT32)
- UNPACK(unpackI32, C32L, UINT32, INT32)
- UNPACK(unpackI32S, C32L, INT32, INT32)
- UNPACK(unpackI32B, C32B, UINT32, INT32)
- UNPACK(unpackI32BS, C32B, INT32, INT32)
- UNPACK(unpackI32N, C32N, UINT32, INT32)
- UNPACK(unpackI32NS, C32N, INT32, INT32)
- UNPACK_RAW(unpackF8, in[0], UINT8, FLOAT32)
- UNPACK_RAW(unpackF8S, in[0], INT8, FLOAT32)
- UNPACK(unpackF16, C16L, UINT16, FLOAT32)
- UNPACK(unpackF16S, C16L, INT16, FLOAT32)
- UNPACK(unpackF16B, C16B, UINT16, FLOAT32)
- UNPACK(unpackF16BS, C16B, INT16, FLOAT32)
- UNPACK(unpackF16N, C16N, UINT16, FLOAT32)
- UNPACK(unpackF16NS, C16N, INT16, FLOAT32)
- UNPACK(unpackF32, C32L, UINT32, FLOAT32)
- UNPACK(unpackF32S, C32L, INT32, FLOAT32)
- UNPACK(unpackF32B, C32B, UINT32, FLOAT32)
- UNPACK(unpackF32BS, C32B, INT32, FLOAT32)
- UNPACK(unpackF32N, C32N, UINT32, FLOAT32)
- UNPACK(unpackF32NS, C32N, INT32, FLOAT32)
- UNPACK(unpackF32F, C32L, FLOAT32, FLOAT32)
- UNPACK(unpackF32BF, C32B, FLOAT32, FLOAT32)
- UNPACK(unpackF32NF, C32N, FLOAT32, FLOAT32)
- #ifdef FLOAT64
- UNPACK(unpackF64F, C64L, FLOAT64, FLOAT32)
- UNPACK(unpackF64BF, C64B, FLOAT64, FLOAT32)
- UNPACK(unpackF64NF, C64N, FLOAT64, FLOAT32)
- #endif
- /* Misc. unpackers */
- static void
- band0(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* band 0 only */
- for (i = 0; i < pixels; i++) {
- out[0] = in[i];
- out += 4;
- }
- }
- static void
- band1(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* band 1 only */
- for (i = 0; i < pixels; i++) {
- out[1] = in[i];
- out += 4;
- }
- }
- static void
- band2(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* band 2 only */
- for (i = 0; i < pixels; i++) {
- out[2] = in[i];
- out += 4;
- }
- }
- static void
- band3(UINT8* out, const UINT8* in, int pixels)
- {
- /* band 3 only */
- int i;
- for (i = 0; i < pixels; i++) {
- out[3] = in[i];
- out += 4;
- }
- }
- static void
- band0I(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* band 0 only */
- for (i = 0; i < pixels; i++) {
- out[0] = ~in[i];
- out += 4;
- }
- }
- static void
- band1I(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* band 1 only */
- for (i = 0; i < pixels; i++) {
- out[1] = ~in[i];
- out += 4;
- }
- }
- static void
- band2I(UINT8* out, const UINT8* in, int pixels)
- {
- int i;
- /* band 2 only */
- for (i = 0; i < pixels; i++) {
- out[2] = ~in[i];
- out += 4;
- }
- }
- static void
- band3I(UINT8* out, const UINT8* in, int pixels)
- {
- /* band 3 only */
- int i;
- for (i = 0; i < pixels; i++) {
- out[3] = ~in[i];
- out += 4;
- }
- }
- static struct {
- const char* mode;
- const char* rawmode;
- int bits;
- ImagingShuffler unpack;
- } unpackers[] = {
- /* raw mode syntax is "<mode>;<bits><flags>" where "bits" defaults
- depending on mode (1 for "1", 8 for "P" and "L", etc), and
- "flags" should be given in alphabetical order. if both bits
- and flags have their default values, the ; should be left out */
- /* flags: "I" inverted data; "R" reversed bit order; "B" big
- endian byte order (default is little endian); "L" line
- interleave, "S" signed, "F" floating point */
- /* exception: rawmodes "I" and "F" are always native endian byte order */
- /* bilevel */
- {"1", "1", 1, unpack1},
- {"1", "1;I", 1, unpack1I},
- {"1", "1;R", 1, unpack1R},
- {"1", "1;IR", 1, unpack1IR},
- {"1", "1;8", 8, unpack18},
- /* greyscale */
- {"L", "L;2", 2, unpackL2},
- {"L", "L;2I", 2, unpackL2I},
- {"L", "L;2R", 2, unpackL2R},
- {"L", "L;2IR", 2, unpackL2IR},
- {"L", "L;4", 4, unpackL4},
- {"L", "L;4I", 4, unpackL4I},
- {"L", "L;4R", 4, unpackL4R},
- {"L", "L;4IR", 4, unpackL4IR},
- {"L", "L", 8, copy1},
- {"L", "L;I", 8, unpackLI},
- {"L", "L;R", 8, unpackLR},
- {"L", "L;16", 16, unpackL16},
- {"L", "L;16B", 16, unpackL16B},
- /* greyscale w. alpha */
- {"LA", "LA", 16, unpackLA},
- {"LA", "LA;L", 16, unpackLAL},
- /* palette */
- {"P", "P;1", 1, unpackP1},
- {"P", "P;2", 2, unpackP2},
- {"P", "P;2L", 2, unpackP2L},
- {"P", "P;4", 4, unpackP4},
- {"P", "P;4L", 4, unpackP4L},
- {"P", "P", 8, copy1},
- {"P", "P;R", 8, unpackLR},
- /* palette w. alpha */
- {"PA", "PA", 16, unpackLA},
- {"PA", "PA;L", 16, unpackLAL},
- /* true colour */
- {"RGB", "RGB", 24, ImagingUnpackRGB},
- {"RGB", "RGB;L", 24, unpackRGBL},
- {"RGB", "RGB;R", 24, unpackRGBR},
- {"RGB", "RGB;16L", 48, unpackRGB16L},
- {"RGB", "RGB;16B", 48, unpackRGB16B},
- {"RGB", "BGR", 24, ImagingUnpackBGR},
- {"RGB", "RGB;15", 16, ImagingUnpackRGB15},
- {"RGB", "BGR;15", 16, ImagingUnpackBGR15},
- {"RGB", "RGB;16", 16, ImagingUnpackRGB16},
- {"RGB", "BGR;16", 16, ImagingUnpackBGR16},
- {"RGB", "RGB;4B", 16, ImagingUnpackRGB4B},
- {"RGB", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */
- {"RGB", "RGBX", 32, copy4},
- {"RGB", "RGBX;L", 32, unpackRGBAL},
- {"RGB", "RGBA;L", 32, unpackRGBAL},
- {"RGB", "BGRX", 32, ImagingUnpackBGRX},
- {"RGB", "XRGB", 32, ImagingUnpackXRGB},
- {"RGB", "XBGR", 32, ImagingUnpackXBGR},
- {"RGB", "YCC;P", 24, ImagingUnpackYCC},
- {"RGB", "R", 8, band0},
- {"RGB", "G", 8, band1},
- {"RGB", "B", 8, band2},
- /* true colour w. alpha */
- {"RGBA", "LA", 16, unpackRGBALA},
- {"RGBA", "LA;16B", 32, unpackRGBALA16B},
- {"RGBA", "RGBA", 32, copy4},
- {"RGBA", "RGBAX", 40, copy4skip1},
- {"RGBA", "RGBAXX", 48, copy4skip2},
- {"RGBA", "RGBa", 32, unpackRGBa},
- {"RGBA", "RGBaX", 40, unpackRGBaskip1},
- {"RGBA", "RGBaXX", 48, unpackRGBaskip2},
- {"RGBA", "RGBa;16L", 64, unpackRGBa16L},
- {"RGBA", "RGBa;16B", 64, unpackRGBa16B},
- {"RGBA", "BGRa", 32, unpackBGRa},
- {"RGBA", "RGBA;I", 32, unpackRGBAI},
- {"RGBA", "RGBA;L", 32, unpackRGBAL},
- {"RGBA", "RGBA;15", 16, ImagingUnpackRGBA15},
- {"RGBA", "BGRA;15", 16, ImagingUnpackBGRA15},
- {"RGBA", "RGBA;4B", 16, ImagingUnpackRGBA4B},
- {"RGBA", "RGBA;16L", 64, unpackRGBA16L},
- {"RGBA", "RGBA;16B", 64, unpackRGBA16B},
- {"RGBA", "BGRA", 32, unpackBGRA},
- {"RGBA", "ARGB", 32, unpackARGB},
- {"RGBA", "ABGR", 32, unpackABGR},
- {"RGBA", "YCCA;P", 32, ImagingUnpackYCCA},
- {"RGBA", "R", 8, band0},
- {"RGBA", "G", 8, band1},
- {"RGBA", "B", 8, band2},
- {"RGBA", "A", 8, band3},
- #ifdef WORDS_BIGENDIAN
- {"RGB", "RGB;16N", 48, unpackRGB16B},
- {"RGBA", "RGBa;16N", 64, unpackRGBa16B},
- {"RGBA", "RGBA;16N", 64, unpackRGBA16B},
- {"RGBX", "RGBX;16N", 64, unpackRGBA16B},
- #else
- {"RGB", "RGB;16N", 48, unpackRGB16L},
- {"RGBA", "RGBa;16N", 64, unpackRGBa16L},
- {"RGBA", "RGBA;16N", 64, unpackRGBA16L},
- {"RGBX", "RGBX;16N", 64, unpackRGBA16B},
- #endif
- /* true colour w. alpha premultiplied */
- {"RGBa", "RGBa", 32, copy4},
- {"RGBa", "BGRa", 32, unpackBGRA},
- {"RGBa", "aRGB", 32, unpackARGB},
- {"RGBa", "aBGR", 32, unpackABGR},
- /* true colour w. padding */
- {"RGBX", "RGB", 24, ImagingUnpackRGB},
- {"RGBX", "RGB;L", 24, unpackRGBL},
- {"RGBX", "RGB;16B", 48, unpackRGB16B},
- {"RGBX", "BGR", 24, ImagingUnpackBGR},
- {"RGBX", "RGB;15", 16, ImagingUnpackRGB15},
- {"RGBX", "BGR;15", 16, ImagingUnpackBGR15},
- {"RGBX", "RGB;4B", 16, ImagingUnpackRGB4B},
- {"RGBX", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */
- {"RGBX", "RGBX", 32, copy4},
- {"RGBX", "RGBXX", 40, copy4skip1},
- {"RGBX", "RGBXXX", 48, copy4skip2},
- {"RGBX", "RGBX;L", 32, unpackRGBAL},
- {"RGBX", "RGBX;16L", 64, unpackRGBA16L},
- {"RGBX", "RGBX;16B", 64, unpackRGBA16B},
- {"RGBX", "BGRX", 32, ImagingUnpackBGRX},
- {"RGBX", "XRGB", 32, ImagingUnpackXRGB},
- {"RGBX", "XBGR", 32, ImagingUnpackXBGR},
- {"RGBX", "YCC;P", 24, ImagingUnpackYCC},
- {"RGBX", "R", 8, band0},
- {"RGBX", "G", 8, band1},
- {"RGBX", "B", 8, band2},
- {"RGBX", "X", 8, band3},
- /* colour separation */
- {"CMYK", "CMYK", 32, copy4},
- {"CMYK", "CMYKX", 40, copy4skip1},
- {"CMYK", "CMYKXX", 48, copy4skip2},
- {"CMYK", "CMYK;I", 32, unpackCMYKI},
- {"CMYK", "CMYK;L", 32, unpackRGBAL},
- {"CMYK", "CMYK;16L", 64, unpackRGBA16L},
- {"CMYK", "CMYK;16B", 64, unpackRGBA16B},
- {"CMYK", "C", 8, band0},
- {"CMYK", "M", 8, band1},
- {"CMYK", "Y", 8, band2},
- {"CMYK", "K", 8, band3},
- {"CMYK", "C;I", 8, band0I},
- {"CMYK", "M;I", 8, band1I},
- {"CMYK", "Y;I", 8, band2I},
- {"CMYK", "K;I", 8, band3I},
- #ifdef WORDS_BIGENDIAN
- {"CMYK", "CMYK;16N", 64, unpackRGBA16B},
- #else
- {"CMYK", "CMYK;16N", 64, unpackRGBA16L},
- #endif
- /* video (YCbCr) */
- {"YCbCr", "YCbCr", 24, ImagingUnpackRGB},
- {"YCbCr", "YCbCr;L", 24, unpackRGBL},
- {"YCbCr", "YCbCrX", 32, copy4},
- {"YCbCr", "YCbCrK", 32, copy4},
- /* LAB Color */
- {"LAB", "LAB", 24, ImagingUnpackLAB},
- {"LAB", "L", 8, band0},
- {"LAB", "A", 8, band1},
- {"LAB", "B", 8, band2},
- /* HSV Color */
- {"HSV", "HSV", 24, ImagingUnpackRGB},
- {"HSV", "H", 8, band0},
- {"HSV", "S", 8, band1},
- {"HSV", "V", 8, band2},
- /* integer variations */
- {"I", "I", 32, copy4},
- {"I", "I;8", 8, unpackI8},
- {"I", "I;8S", 8, unpackI8S},
- {"I", "I;16", 16, unpackI16},
- {"I", "I;16S", 16, unpackI16S},
- {"I", "I;16B", 16, unpackI16B},
- {"I", "I;16BS", 16, unpackI16BS},
- {"I", "I;16N", 16, unpackI16N},
- {"I", "I;16NS", 16, unpackI16NS},
- {"I", "I;32", 32, unpackI32},
- {"I", "I;32S", 32, unpackI32S},
- {"I", "I;32B", 32, unpackI32B},
- {"I", "I;32BS", 32, unpackI32BS},
- {"I", "I;32N", 32, unpackI32N},
- {"I", "I;32NS", 32, unpackI32NS},
- /* floating point variations */
- {"F", "F", 32, copy4},
- {"F", "F;8", 8, unpackF8},
- {"F", "F;8S", 8, unpackF8S},
- {"F", "F;16", 16, unpackF16},
- {"F", "F;16S", 16, unpackF16S},
- {"F", "F;16B", 16, unpackF16B},
- {"F", "F;16BS", 16, unpackF16BS},
- {"F", "F;16N", 16, unpackF16N},
- {"F", "F;16NS", 16, unpackF16NS},
- {"F", "F;32", 32, unpackF32},
- {"F", "F;32S", 32, unpackF32S},
- {"F", "F;32B", 32, unpackF32B},
- {"F", "F;32BS", 32, unpackF32BS},
- {"F", "F;32N", 32, unpackF32N},
- {"F", "F;32NS", 32, unpackF32NS},
- {"F", "F;32F", 32, unpackF32F},
- {"F", "F;32BF", 32, unpackF32BF},
- {"F", "F;32NF", 32, unpackF32NF},
- #ifdef FLOAT64
- {"F", "F;64F", 64, unpackF64F},
- {"F", "F;64BF", 64, unpackF64BF},
- {"F", "F;64NF", 64, unpackF64NF},
- #endif
- /* storage modes */
- {"I;16", "I;16", 16, copy2},
- {"I;16B", "I;16B", 16, copy2},
- {"I;16L", "I;16L", 16, copy2},
- {"I;16", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian.
- {"I;16L", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian.
- {"I;16B", "I;16N", 16, unpackI16N_I16B},
- {"I;16", "I;12", 12, unpackI12_I16}, // 12 bit Tiffs stored in 16bits.
- {NULL} /* sentinel */
- };
- ImagingShuffler
- ImagingFindUnpacker(const char* mode, const char* rawmode, int* bits_out)
- {
- int i;
- /* find a suitable pixel unpacker */
- for (i = 0; unpackers[i].rawmode; i++)
- if (strcmp(unpackers[i].mode, mode) == 0 &&
- strcmp(unpackers[i].rawmode, rawmode) == 0) {
- if (bits_out)
- *bits_out = unpackers[i].bits;
- return unpackers[i].unpack;
- }
- /* FIXME: configure a general unpacker based on the type codes... */
- return NULL;
- }
|